We help IT Professionals succeed at work.

Instantiate subclass of abstract class

allelopath
allelopath asked
on
If I have an abstract class and classes that extend it:
MyAbstractClass
  MyConcreteClassA
  MyConcreteClassB
  MyConcreteClassC
 
and then a method():

public void doSomething(MyAbstractClass myClass) {
  MyAbstractClass myNewClass = new ???(myClass);
}

How do I instantiate myNewClass given that it could be MyConcreteClassA, MyConcreteClassB, or MyConcreteClassC?
 
 
Comment
Watch Question

for e.g.,

MyAbstractClass myNewClass = new MyConcreteClassA() ;
or you can create a factory which returns appropriate instance of impl class

Author

Commented:
I want to base myNewClass on the same class as the input myClass.
Top Expert 2016

Commented:
>>public void doSomething(MyAbstractClass myClass) {


Here, 'myClass' is already instantiated, or it wouldn't be able to be passed. If it's really of type class, you can use reflection
MyAbstractClass myNewClass = null ;
if( myClass instanceof MyConcreteClassA ){
  myNewClass = new MyConcreteClassA(myClass ) ;
}

Author

Commented:
CEHJ:
Yes, myClass is instantiated.
Do you mean reflection as in the example code given by ksivananth?
>>MyAbstractClass myNewClass = new ???(myClass);

what exactly you wanted to do here?

Author

Commented:
ksivananth:
Your code does what I want. I guess now I'm wondering if it is the cleanest way to do it. Suppose, for example, I had 50 subclasses, instead of 3.

MyAbstractClass myNewClass = null ;
if( myClass instanceof MyConcreteClassA ){
  myNewClass = new MyConcreteClassA(myClass ) ;
}
else if MyAbstractClass myNewClass = null ;
if( myClass instanceof MyConcreteClassB ){
  myNewClass = new MyConcreteClassB(myClass ) ;
}
else if MyAbstractClass myNewClass = null ;
if( myClass instanceof MyConcreteClassC ){
  myNewClass = new MyConcreteClassCA(myClass ) ;
}
... and so on.

Open in new window

Top Expert 2016

Commented:
I'm not quite sure what exactly you want to do and why, but it sounds like you need to use the Factory pattern

Author

Commented:
this doesn't work (compile error on getName())
myNewClass = Class.forName(myClass.getName().newInstance();
I guess because myClass is MyAbstract class in the parameter list

Author

Commented:
The code below does exactly what I want, its just not pretty if I have a lot of classes.
MyAbstractClass myNewClass = null ;
if( myClass instanceof MyConcreteClassA ){
  myNewClass = new MyConcreteClassA(myClass ) ;
}
else if MyAbstractClass myNewClass = null ;
if( myClass instanceof MyConcreteClassB ){
  myNewClass = new MyConcreteClassB(myClass ) ;
}
else if MyAbstractClass myNewClass = null ;
if( myClass instanceof MyConcreteClassC ){
  myNewClass = new MyConcreteClassC(myClass ) ;
}
... and so on.

Open in new window

Top Expert 2016

Commented:
So, you want to take an instance of say, MyConcreteClassA and create another MyConcreteClassA from it? Why do you want to do that btw?

Author

Commented:
>>MyConcreteClassA and create another MyConcreteClassA from it?
Yes, Creating a copy so that changes to myNewClass do not make their way to myClass.

Author

Commented:
>>Creating a copy
and I guess that's my answer, create a copy method in each subclass.
Top Expert 2016
Commented:
Taking care how you implement clone, you could just do
AbstractParent a = (AbstractParent)concreteChild.clone();

Open in new window

Top Expert 2016

Commented:
>>if( myClass instanceof MyConcreteClassA )

Of course, with the above, you need an if statement for every subclass type