基本上,我想做的是强制子类调用抽象超类方法(在子类中实现),所以每次创建新的时都不必显式写它子类。
我在超类的构造函数中写了一次,因为我希望它强制它用于每个实现。
public abstract class SupahClass {
public SupahClass() {
doStuff(); // It IS executed when the subclass constructor is called
init(); // NOT executed, even though it's implemented
}
private void doStuff() { ... }
protected abstract void init();
}
public class SomeSubClass extends SupahClass {
// The problem lies HERE: this is executed AFTER init() ... so it gets NULL again
private TextBox myTextBox = null;
public SomeSubClass() {
super(); // invokes the super constructor, so init() should be called
// I could call init(); here EACH time i create a new subclass... but no :)
}
@Override
public void init() {
this.myTextBox = new TextBox(); // Executed BEFORE its declared as null above
}
}
当然,超类不能真正调用它,因为它是一个抽象(如此未定义)的方法,但它是一个ABSTRACT类,所以它不能实例化,它必须将任务委托给它的子类,所以为什么它们不能调用它摘要但现在实施的方法?
修改
请参阅子类属性myTextBox
和init()
实现
您认为我应该采取哪种方法?删除属性声明中的= null
(duhhh)
或删除超类中的init()
并在子类构造函数中显式调用它(这是我想要避免的,因为我必须在100%的时间内编写它。)
答案 0 :(得分:8)
我无法重现这一点。假设没有先抛出异常,将调用init()
。简短而完整的例子:
abstract class Superclass {
public Superclass() {
init();
}
protected abstract void init();
}
class Subclass extends Superclass {
public Subclass() {
super();
}
@Override
public void init() {
System.out.println("Subclass.init called");
}
}
public class Test {
public static void main(String[] args) throws Exception {
new Subclass();
}
}
按预期打印“Subclass.init”。我怀疑你没有向我们展示的代码中有其他错误。
请注意,在构造函数中调用虚方法是一项有风险的业务 - 子类尚未初始化 - 例如,所有变量都将具有默认值。这通常是一种需要避免的模式。
答案 1 :(得分:2)
抽象类可以调用抽象方法。
答案 2 :(得分:2)
您可以通过将声明更改为:
来解决此问题private TextBox myTextBox;
赋值为null没有任何用处。如果没有超类,它将什么也不做,因为无论如何字段都被初始化为null。由于有一个超类,它起到了脚的枪声。所以,摆脱它。
答案 3 :(得分:0)
您是否使用调试器来了解代码的作用?
施工顺序是 1.基类的构造函数 2.初始化派生类的所有成员 3.派生类的构造函数。
在您的情况下,步骤1初始化成员(在派生类的init中 - 通过多态调用调用),但步骤2将其设置为null。