带有抽象类的Java方法,作为返回子类实例的参数

时间:2014-09-30 12:41:51

标签: java abstract-class

我确定以前会问过这个问题,但是在搜索了一段时间后我找不到它。

我需要一个可以执行以下操作的函数:

public static AbstractClass createClass(Class<AbstractClass> theChildClass, int someVariable){
    AbstractClass theInstance = theChildClass.newInstance(someVariable);
    return theInstance;
}

然后在AbstractClass上我想像这样定义它:

public abstract class AbstractClass{

    private int someVariable;

    public AbstractClass(int someVariable){
        this.someVariable = someVariable;
        initOnChild();
    }

    protected abstract void initOnChild();

}

然后在子课上我理想地不想定义公共ChildClass(int someVariable){}&#34;方法,所以它们看起来像这样:

public class ChildClass extends AbstractClass{

    @Override
    protected void initOnChild(){
        //do some stuff
    }

}

我之后的理想结果是能够像这样调用方法:

ChildClass theInstance = UtilityClass.createClass(ChildClass.class, 1);

这甚至可能吗?任何解决方案或建议都非常赞赏。

2 个答案:

答案 0 :(得分:1)

没有。构造函数不是继承的(因此不是JLS中的成员)。根据具体情况,您可能希望应用策略模式,比如说。

(ObNote:一般来说,从构造函数中调用可重写方法被认为是个坏主意,反射几乎总是一个非常糟糕的主意。)

答案 1 :(得分:0)

不,但有一个解决方案。

首先在构造函数中调用overriden方法的问题:

abstract class A {

    A() {
        init();
    }

    protected abstract void init();
}

class B extends A {

    public String x = null;
    public String y;

    @Override
    protected void init() {
        x = "x";
        y = "y";
    }
}

public static void main(String[] args) {
    B b = new B();
    System.out.printf("x=%s, y=%s%n", b.x, b.y);
}

当然会给:

x=null, y=y
  • in B() - 所有字段归零
  • super()调用,A()
  • 在A()B.init()中称为
  • 在B()字段初始化中完成

但是从表面上阅读并不明显,并且在基类中使用字段时,可能会变得不那么明显。

现在的解决方案。

由于您有静态工厂方法,可以将此方法放在AbstractClass中。然后它可以在构造之后调用init。

public static <T extends AbstractClass> T create(Class<T> childClass, int param) {
    T instance = childClass.getConstructor().newInstance();
    instance.init(param);
    return instance;
}

这将执行默认构造函数。

如果这仍然不能令人满意,那么它可能只是某些数据结构不在正确的继承级别中,或者应该重新构建。