Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.help > #537 > unrolled thread

Instantiate an abstract class

Started byRob McDonald <rob.a.mcdonald@gmail.com>
First post2011-04-05 14:14 -0700
Last post2011-04-06 12:41 -0700
Articles 15 — 8 participants

Back to article view | Back to comp.lang.java.help


Contents

  Instantiate an abstract class Rob McDonald <rob.a.mcdonald@gmail.com> - 2011-04-05 14:14 -0700
    Re: Instantiate an abstract class Patricia Shanahan <pats@acm.org> - 2011-04-05 14:37 -0700
      Re: Instantiate an abstract class Rob McDonald <rob.a.mcdonald@gmail.com> - 2011-04-05 14:49 -0700
    Re: Instantiate an abstract class Joshua Cranmer <Pidgeot18@verizon.invalid> - 2011-04-05 17:48 -0400
      Re: Instantiate an abstract class Rob McDonald <rob.a.mcdonald@gmail.com> - 2011-04-05 14:54 -0700
        Re: Instantiate an abstract class Patricia Shanahan <pats@acm.org> - 2011-04-05 15:09 -0700
        Re: Instantiate an abstract class Lew <noone@lewscanon.com> - 2011-04-06 12:43 -0400
          Re: Instantiate an abstract class "John B. Matthews" <nospam@nospam.invalid> - 2011-04-06 22:07 -0400
    Re: Instantiate an abstract class Roedy Green <see_website@mindprod.com.invalid> - 2011-04-05 19:02 -0700
    Re: Instantiate an abstract class Roedy Green <see_website@mindprod.com.invalid> - 2011-04-05 19:42 -0700
    Re: Instantiate an abstract class Lothar Kimmeringer <news200709@kimmeringer.de> - 2011-04-06 18:26 +0200
      Re: Instantiate an abstract class Lew <noone@lewscanon.com> - 2011-04-06 12:49 -0400
        Re: Instantiate an abstract class Patricia Shanahan <pats@acm.org> - 2011-04-06 10:09 -0700
        Re: Instantiate an abstract class Lothar Kimmeringer <news200709@kimmeringer.de> - 2011-04-07 01:01 +0200
    Re: Instantiate an abstract class Wojtek <nowhere@a.com> - 2011-04-06 12:41 -0700

#537 — Instantiate an abstract class

FromRob McDonald <rob.a.mcdonald@gmail.com>
Date2011-04-05 14:14 -0700
SubjectInstantiate an abstract class
Message-ID<61c7300d-6011-4639-a5f1-5cd4c58906fa@r4g2000prm.googlegroups.com>
Now, we all know that you can't instantiate an abstract class -- but I
want to anyway...  Actually, I would like my abstract class to be able
to instantiate another instance of whatever concrete class it is at
the time.

I have an abstract class AFoo, which will have implementations Bar and
Fred.

abstract class AFoo {
  void doStuff() {
    AFoo a = new this.getClass();
  }
}

class Bar extends AFoo {
}

class Fred extends AFoo {
}

When Bar.doStuff() executes, it should instantiate with 'new Bar()'
for its use.  Similarly for Fred().

When I try it, I get a variety of errors depending on different
attempts...

AFoo a = new this.getClass();
Syntax error on token "this", invalid Name

AFoo a = new (this.getClass());
AFoo a = new (this).getClass();
Syntax error on token "new", ClassType expected after this token

Suggestions appreciated,

Rob

[toc] | [next] | [standalone]


#538

FromPatricia Shanahan <pats@acm.org>
Date2011-04-05 14:37 -0700
Message-ID<5Z-dnerIwYsWFgbQnZ2dnUVZ_qydnZ2d@earthlink.com>
In reply to#537
On 4/5/2011 2:14 PM, Rob McDonald wrote:
> Now, we all know that you can't instantiate an abstract class -- but I
> want to anyway...  Actually, I would like my abstract class to be able
> to instantiate another instance of whatever concrete class it is at
> the time.
...

Have you tried making AFoo Cloneable, and giving it a clone method? Your
requirements seem to match the normal clone() behavior.

Patricia

[toc] | [prev] | [next] | [standalone]


#540

FromRob McDonald <rob.a.mcdonald@gmail.com>
Date2011-04-05 14:49 -0700
Message-ID<d49fb9bf-d0a1-409e-9fda-d04cc2c0e115@1g2000yqq.googlegroups.com>
In reply to#538
On Apr 5, 5:37 pm, Patricia Shanahan <p...@acm.org> wrote:
> On 4/5/2011 2:14 PM, Rob McDonald wrote:> Now, we all know that you can't instantiate an abstract class -- but I
> > want to anyway...  Actually, I would like my abstract class to be able
> > to instantiate another instance of whatever concrete class it is at
> > the time.
>
> ...
>
> Have you tried making AFoo Cloneable, and giving it a clone method? Your
> requirements seem to match the normal clone() behavior.
>
> Patricia

Thanks Patricia,

My understanding of clone() is that it constructs a duplicate instance
of your object -- all fields would have identical values.  I don't
want a duplicate, I'd like a new fresh one.

This class previously was not abstract (and everything worked fine),
but now I would like to create two slightly different versions.  So, I
would like to leave the common implementation matters in the abstract
class, and only implement the differences.

I'm not sure if more information will help or confuse things, but here
goes...
(I realize that a through redesign may be appropriate here, but I
would rather not.  As I said, I got here from code which worked, and I
think there 'ought to be' a way to make this work.)

My object is actually a container with some advanced functionality.
You can think of it as a group of items -- sometimes I want to create
a subgroup of items -- and treat it as an item at the first level.

Initially:

Group G1
 contains items a,b,c,d,e,f

Later:

Group G1
 contains items a,G2,e,f

Group G2
 contains items b,c,d


Where, Group extends the abstract AGroup, and the code we're
discussing is in AGroup.  When AGroup.createSubGroup() goes to make
Group G2, it needs a type to instantiate.

Hope this clarifies; thanks for the help,

Rob

[toc] | [prev] | [next] | [standalone]


#539

FromJoshua Cranmer <Pidgeot18@verizon.invalid>
Date2011-04-05 17:48 -0400
Message-ID<ing2nd$627$1@dont-email.me>
In reply to#537
On 04/05/2011 05:14 PM, Rob McDonald wrote:
> Now, we all know that you can't instantiate an abstract class -- but I
> want to anyway...  Actually, I would like my abstract class to be able
> to instantiate another instance of whatever concrete class it is at
> the time.

Your class is abstract, so you can easily have:

abstract class AFoo {
   public abstract AFoo makeInstance();
}

Or, as Patricia mentions:

abstract class AFoo {
   public abstract AFoo clone(); // Legal only in Java 5+
}

Each subclass would then implement this method as appropriate.

I can answer your question more directly with reflection, but it's a 
method I wouldn't recommend without a very compelling reason why this 
approach wouldn't work for you.
-- 
Beware of bugs in the above code; I have only proved it correct, not 
tried it. -- Donald E. Knuth

[toc] | [prev] | [next] | [standalone]


#541

FromRob McDonald <rob.a.mcdonald@gmail.com>
Date2011-04-05 14:54 -0700
Message-ID<edce4c55-5560-4718-b3b2-d9797dff79fc@l39g2000yqh.googlegroups.com>
In reply to#539
On Apr 5, 5:48 pm, Joshua Cranmer <Pidgeo...@verizon.invalid> wrote:
> On 04/05/2011 05:14 PM, Rob McDonald wrote:
>
> > Now, we all know that you can't instantiate an abstract class -- but I
> > want to anyway...  Actually, I would like my abstract class to be able
> > to instantiate another instance of whatever concrete class it is at
> > the time.
>
> Your class is abstract, so you can easily have:
>
> abstract class AFoo {
>    public abstract AFoo makeInstance();
>
> }
>
> Or, as Patricia mentions:
>
> abstract class AFoo {
>    public abstract AFoo clone(); // Legal only in Java 5+
>
> }
>
> Each subclass would then implement this method as appropriate.
>
> I can answer your question more directly with reflection, but it's a
> method I wouldn't recommend without a very compelling reason why this
> approach wouldn't work for you.

Joshua,

That worked great.  I don't know why I hadn't come up with that
solution myself.

Most of my online searches had lead down the reflection path and I
quickly got myself wrapped around the axle.  I'm going to go with the
above implementation, but I am curious about how it could be made to
work the other way.

Thanks for the help,

Rob

[toc] | [prev] | [next] | [standalone]


#542

FromPatricia Shanahan <pats@acm.org>
Date2011-04-05 15:09 -0700
Message-ID<b4GdnUdhF-OlDgbQnZ2dnUVZ_gSdnZ2d@earthlink.com>
In reply to#541
On 4/5/2011 2:54 PM, Rob McDonald wrote:
...
> Most of my online searches had lead down the reflection path and I
> quickly got myself wrapped around the axle.  I'm going to go with the
> above implementation, but I am curious about how it could be made to
> work the other way.
...

Obviously, a real implementation would handle the exceptions for a
subclass that does not have an accessible parameterless constructor, but
this should give you an idea. The advantage of this approach is that you
only need to require each subclass to have an accessible parameterless
constructor.

public abstract class AFoo {

   private AFoo getNewInstance() throws InstantiationException,
       IllegalAccessException {
     return (AFoo) getClass().newInstance();
   }

   public static void main(String[] args) throws InstantiationException,
       IllegalAccessException {
     AFoo bob = new Bob();
     AFoo bobExtra = bob.getNewInstance();
     System.out.println(bobExtra.getClass());

     AFoo fred = new Fred();
     AFoo fredExtra = fred.getNewInstance();
     System.out.println(fredExtra.getClass());
   }
}

class Bob extends AFoo {
}

class Fred extends AFoo {
}

[toc] | [prev] | [next] | [standalone]


#557

FromLew <noone@lewscanon.com>
Date2011-04-06 12:43 -0400
Message-ID<ini58c$8eh$2@news.albasani.net>
In reply to#541
Rob McDonald wrote:
> Joshua Cranmer wrote:
>> Rob McDonald wrote:
>>> Now, we all know that you can't instantiate an abstract class -- but I
>>> want to anyway...  Actually, I would like my abstract class to be able
>>> to instantiate another instance of whatever concrete class it is at
>>> the time.

>> Your class is abstract, so you can easily have:
>>
>> abstract class AFoo {
>>     public abstract AFoo makeInstance();

> That worked great.  I don't know why I hadn't come up with that
> solution myself.
>
> Most of my online searches had lead down the reflection path and I
> quickly got myself wrapped around the axle.  I'm going to go with the
> above implementation, but I am curious about how it could be made to
> work the other way.

Because you haven't yet read /Effective Java/ by Joshua Bloch.  You must.  We 
all must, and not just once, either.

<http://java.sun.com/docs/books/effective/>
The very first item of which is,
"Item 1: Consider static factory methods instead of constructors"

-- 
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg

[toc] | [prev] | [next] | [standalone]


#565

From"John B. Matthews" <nospam@nospam.invalid>
Date2011-04-06 22:07 -0400
Message-ID<nospam-7DA678.22070606042011@news.aioe.org>
In reply to#557
In article <ini58c$8eh$2@news.albasani.net>, Lew <noone@lewscanon.com> 
wrote:

> Rob McDonald wrote:
> > Joshua Cranmer wrote:
> >> Rob McDonald wrote:
> >>> Now, we all know that you can't instantiate an abstract class -- 
> >>> but I want to anyway...  Actually, I would like my abstract class 
> >>> to be able to instantiate another instance of whatever concrete 
> >>> class it is at the time.
> 
> >> Your class is abstract, so you can easily have:
> >>
> >> abstract class AFoo {
> >>     public abstract AFoo makeInstance();
> 
> > That worked great.  I don't know why I hadn't come up with that 
> > solution myself.
> >
> > Most of my online searches had lead down the reflection path and I 
> > quickly got myself wrapped around the axle.  I'm going to go with 
> > the above implementation, but I am curious about how it could be 
> > made to work the other way.
> 
> Because you haven't yet read /Effective Java/ by Joshua Bloch.  You 
> must.  We all must, and not just once, either.
> 
> <http://java.sun.com/docs/books/effective/>
> The very first item of which is,
> "Item 1: Consider static factory methods instead of constructors"

Generously reprinted in Dr. Dobb's:

<http://drdobbs.com/java/208403883?pgno=1>

For convenient reference, now seen here:

<http://en.wikipedia.org/wiki/Factory_method_pattern>

-- 
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>

[toc] | [prev] | [next] | [standalone]


#543

FromRoedy Green <see_website@mindprod.com.invalid>
Date2011-04-05 19:02 -0700
Message-ID<aainp6p7vtnbqe7l2s9oc9uv0ok0n58q59@4ax.com>
In reply to#537
On Tue, 5 Apr 2011 14:14:50 -0700 (PDT), Rob McDonald
<rob.a.mcdonald@gmail.com> wrote, quoted or indirectly quoted someone
who said :

>Now, we all know that you can't instantiate an abstract class -- but I
>want to anyway...  Actually, I would like my abstract class to be able
>to instantiate another instance of whatever concrete class it is at
>the time.

You can extend an abstract class, with another abstract class then
extend that with a concrete class and instantiate that.

You can extend an abstract class with dummy stubs and instantiate
that, but you can't instantiate an abstract class.  You can
instantiate a concrete class and use an abstract superclass reference
to it.
-- 
Roedy Green Canadian Mind Products
http://mindprod.com
Doing what the user expects with respect to navigation is absurdly important for user satisfaction.
~ anonymous Google Android developer

[toc] | [prev] | [next] | [standalone]


#544

FromRoedy Green <see_website@mindprod.com.invalid>
Date2011-04-05 19:42 -0700
Message-ID<hkknp6l4asu3plk02ok5j3p6qha791bcb0@4ax.com>
In reply to#537
On Tue, 5 Apr 2011 14:14:50 -0700 (PDT), Rob McDonald
<rob.a.mcdonald@gmail.com> wrote, quoted or indirectly quoted someone
who said :

>AFoo a = new (this.getClass());
>AFoo a = new (this).getClass();

Check out the notion of a static factory, a design pattern, also
Class.forName.

See http://mindprod.com/jgloss/classforname.html
http://mindprod.com/jgloss/factorymethod.html
-- 
Roedy Green Canadian Mind Products
http://mindprod.com
Doing what the user expects with respect to navigation is absurdly important for user satisfaction.
~ anonymous Google Android developer

[toc] | [prev] | [next] | [standalone]


#554

FromLothar Kimmeringer <news200709@kimmeringer.de>
Date2011-04-06 18:26 +0200
Message-ID<c1u7degm55pf$.dlg@kimmeringer.de>
In reply to#537
Rob McDonald wrote:

> When I try it, I get a variety of errors depending on different
> attempts...
> 
> AFoo a = new this.getClass();
> Syntax error on token "this", invalid Name
> 
> AFoo a = new (this.getClass());
> AFoo a = new (this).getClass();
> Syntax error on token "new", ClassType expected after this token
> 
> Suggestions appreciated,

getClass().newInstance();


Regards, Lothar
-- 
Lothar Kimmeringer                E-Mail: spamfang@kimmeringer.de
               PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

Always remember: The answer is forty-two, there can only be wrong
                 questions!

[toc] | [prev] | [next] | [standalone]


#558

FromLew <noone@lewscanon.com>
Date2011-04-06 12:49 -0400
Message-ID<ini5i3$9ci$1@news.albasani.net>
In reply to#554
On 04/06/2011 12:26 PM, Lothar Kimmeringer wrote:
> Rob McDonald wrote:
>> When I try it, I get a variety of errors depending on different
>> attempts...
>>
>> AFoo a = new this.getClass();

A very brief study of the Java tutorials will reveal that this is not valid 
syntax.

>> Syntax error on token "this", invalid Name
>>
>> AFoo a = new (this.getClass());

Likewise.

>> AFoo a = new (this).getClass();

And again.

>> Syntax error on token "new", ClassType expected after this token

As explained in the tutorials:
<http://download.oracle.com/javase/tutorial/index.html>

> getClass().newInstance();

You left out the object on which to call 'getClass()'.  How do you get an 
instance on which to call the method?

What if the constructor is not parameterless?

Rob, post a complete class source - not just one-liners.  Make a compilable 
example.  It's ok to be compilable with errors for this purpose - we want to 
analyze the errors.  But we cannot reproduce your work or put our answers in 
context without what's called an "SSCCE"
http://sscce.org/

Remember, "compilable" doesn't necessarily have to be "correct" as in "no 
errors".  If the purpose is to discuss the errors, we want an example that has 
those errors so that we can discuss how to repair them.

But do read the tutorials first.

-- 
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg

[toc] | [prev] | [next] | [standalone]


#559

FromPatricia Shanahan <pats@acm.org>
Date2011-04-06 10:09 -0700
Message-ID<QMadnW49arj1AwHQnZ2dnUVZ_hqdnZ2d@earthlink.com>
In reply to#558
On 4/6/2011 9:49 AM, Lew wrote:
> On 04/06/2011 12:26 PM, Lothar Kimmeringer wrote:
...
>> getClass().newInstance();
>
> You left out the object on which to call 'getClass()'. How do you get an
> instance on which to call the method?

In the context of this thread, the code will be used in a non-static
method in an AFoo subclass instance to build a new instance of the same
AFoo subclass. The getClass() target is the default, "this".

Patricia

[toc] | [prev] | [next] | [standalone]


#564

FromLothar Kimmeringer <news200709@kimmeringer.de>
Date2011-04-07 01:01 +0200
Message-ID<lb9j4psn5s9j.dlg@kimmeringer.de>
In reply to#558
Lew wrote:

> On 04/06/2011 12:26 PM, Lothar Kimmeringer wrote:
>> getClass().newInstance();
> 
> You left out the object on which to call 'getClass()'.  How do you get an 
> instance on which to call the method?

I was quoting
>>> AFoo a = new (this).getClass();
so an educated guess would be "this".

> What if the constructor is not parameterless?

I assumed that there aren't any parameters, since there aren't
any in the text I quoted:
>>> AFoo a = new (this).getClass();


Regards, Lothar
-- 
Lothar Kimmeringer                E-Mail: spamfang@kimmeringer.de
               PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

Always remember: The answer is forty-two, there can only be wrong
                 questions!

[toc] | [prev] | [next] | [standalone]


#562

FromWojtek <nowhere@a.com>
Date2011-04-06 12:41 -0700
Message-ID<mn.32f97db4f2cae5cc.70216@a.com>
In reply to#537
Rob McDonald wrote :
> abstract class AFoo {
>   void doStuff() {

      AFoo a = getNewInstance();

>   }

public absract AFoo getNewInstance();

> }
>
> class Bar extends AFoo {

@Overrides
public Bar getNewInstance()
{
  return new Bar();
}


> }
>
> class Fred extends AFoo {

@Overrides
public Fred getNewInstance()
{
  return new Fred();
}


> }

So "AFoo a" will hold an instance of whatever class extends AFoo, yet 
it can be cast into the subclass.

-- 
Wojtek :-)

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.help


csiph-web