Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用变量类实例化抽象类_Java_Abstract - Fatal编程技术网

Java 使用变量类实例化抽象类

Java 使用变量类实例化抽象类,java,abstract,Java,Abstract,出于显而易见的原因,我们不能像这样直接实例化抽象类: AbstractObj obj = new AbstractObj(); 其中AbstractObj是以下形式的一个类: public abstract class AbstractObj { //... Body omitted } 但是,如果我们有扩展类,例如: public class ConcreteObj extends AbstractObj { //... Body omitted } public class Ano

出于显而易见的原因,我们不能像这样直接实例化抽象类:

AbstractObj obj = new AbstractObj(); 
其中AbstractObj是以下形式的一个类:

public abstract class AbstractObj {
//... Body omitted 
}
但是,如果我们有扩展类,例如:

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

public class AnotherObj extends AbstractObj {
//... Body omitted
}
是否可以按以下方式实例化对象?这将根据传入的变量的类确定必须使用哪个构造函数。现在假设o1和o2保证为同一类型

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

例如,在上面的例子中,如果o1是ConcreteObj类型,是否有一种方法可以在运行时识别它是否是这种类型,并使用适当的构造函数?

您可以使用instanceof语句。您可以将o1强制转换为ConcreteObj并使用此类的方法或字段

if(o1 instanceof ConcreteObj){
  //((ConcreteObj)o1).someMethod();
}
在这里:

您可以使用
o1.getClass()
获得具体的
o1
类。然后,如果这个具体类有一个默认构造函数,那么可以使用
class.newInstance()
调用它:

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

这绝对是代码气味。不要使用instanceof。不要使用反射。

绝对不要继续走这条路

所有的
AbstractObj
实例都实现了一组通用的操作。由于您的
computeDiff
在AbstractObjs上运行,因此它不能依赖于它接收的不同实现的任何特殊特性

因此,方法接收或返回什么类型的对象并不重要,只要它们都符合AbstractObj定义。如果需要,可以返回扩展AbstractObj的匿名类或任何其他子类。您甚至可以为此创建一个特定的子类。但无论您返回什么,它都不能返回比AbstractObj更多的内容


将参数和返回值声明为
AbstractObj
是您与调用您的方法的人签订的合同。不要破坏契约。

在构造对象后要调用构造函数吗?可以使用:
o1.getClass()
。然后,如果它有一个默认构造函数,可以使用
o1.getClass().newInstance()调用它
。抽象类不能实例化,但可以实例化它的具体化。您可以使用
instanceof
检查
o1
是否确实是
ConcreteObj
。您面临的此类问题通常是一个。这会起作用,但是它确实要求
AbstractObj
的所有子类都有一个无参数构造函数。@Jesper是的,这通常是处理反射的类的要求。
protected AbstractObj computeDiff(AbstractObj o1, AbstractObj o2) throws IllegalAccessException, InstantiationException{
   AbstractObj delta = o1.getClass().newInstance();
}