简体   繁体   中英

Instantiate abstract class using class of variable

For obvious reasons, we cannot instantiate an abstract class directly like so:

AbstractObj obj = new AbstractObj(); 

Where AbstractObj is a class of the form:

public abstract class AbstractObj {
//... Body omitted 
}

However if we have extending classes, such as the following:

public class ConcreteObj extends AbstractObj {
//... Body omitted
}

public class AnotherObj extends AbstractObj {
//... Body omitted
}

Is it possible to instantiate an object in the following manner? This determines which constructor has to be used based on the class of the variable passed in. Assume for now that o1 and o2 are guaranteed to be of the same type.

protected AbstractObj computeDiff(AbstractObj o1, AbstractObj o2){
    AbstractObj delta = ...?
}

For example, in the above, if o1 is of type ConcreteObj, is there a way to recognise at runtime whether or not it is of this type and use the appropriate constructor?

Here :

protected AbstractObj computeDiff(AbstractObj o1, AbstractObj o2){
   AbstractObj delta = ...?
}

You can get the concrete class of o1 with o1.getClass() . Then, if this concrete class has a default constructor, you can call it with Class.newInstance() :

protected AbstractObj computeDiff(AbstractObj o1, AbstractObj o2) throws IllegalAccessException, InstantiationException{
   AbstractObj delta = o1.getClass().newInstance();
}

You can use instanceof statement. You can cast o1 to ConcreteObj and use this class' methods or fields.

if(o1 instanceof ConcreteObj){
  //((ConcreteObj)o1).someMethod();
}

This is definitely code smell. Do not use instanceof. Do not use reflection.

Absolutely do not continue on this path.

All your AbstractObj instances implement a common set of operations. Since your computeDiff operates on AbstractObjs, it must not depend on any special features of the different implmentations it receives.

Therefore it does not matter what type of an object the method receives or returns, as long as they all adhere to the AbstractObj definition. You can return an anonymous class that extends AbstractObj if you want or any other subclass. You can even create a specific subclass for just this purpose. But whatever you return, it must not return anything more than AbstractObj.

Declaring the parameters and the return value as AbstractObj is a contract you sign with whoever calls your method. Don't break your contracts.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM