在抽象类的构造函数中使用抽象init()函数

我有这样的事情:

    public abstract class Menu {

public Menu() {

init();

}

protected abstract void init();

protected void addMenuItem(MenuItem menuItem) {

// some code...

}

}

public class ConcreteMenu extends Menu {

protected void init() {

addMenuItem(new MenuItem("ITEM1"));

addMenuItem(new MenuItem("ITEM2"));

// ....

}

}

//Somewhere in code

Menu menu1 = new ConcreteMenu();

如您所见,超类的init方法是抽象的,并在创建对象后由构造函数自动调用。

当我需要创建这种类型的对象且其结构不会及时更改时,我很好奇我是否会遇到这样的代码问题。

有什么更好的办法吗?它可以在Java中运行,但是可以在C ++和ActionScript中运行吗?

谢谢你的答案。

回答:

请勿从构造函数中调用过多的方法。

引用 有效Java 2nd Edition,条款17:继承的设计和文档,或者禁止它

类必须遵守一些其他限制以允许继承。 直接或间接

。如果违反此规则,将导致程序失败。超类构造函数在子类构造函数之前运行,因此子类中的重写方法将在子类构造函数运行之前被调用。如果重写方法依赖于子类构造函数执行的任何初始化,则该方法将无法正常工作。

这是一个示例说明:

public class ConstructorCallsOverride {

public static void main(String[] args) {

abstract class Base {

Base() { overrideMe(); }

abstract void overrideMe();

}

class Child extends Base {

final int x;

Child(int x) { this.x = x; }

@Override void overrideMe() {

System.out.println(x);

}

}

new Child(42); // prints "0"

}

}

在此,当Base构造函数调用时overrideMeChild尚未完成对的初始化final int

x,并且该方法获得了错误的值。这几乎肯定会导致错误和错误。

也可以看看

  • FindBugs-从超类的构造函数调用的未初始化的字段方法读取

以上是 在抽象类的构造函数中使用抽象init()函数 的全部内容, 来源链接: utcz.com/qa/405953.html

回到顶部