当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《在抽象类的构造函数中使用抽象的init()函数》经验,为你挑选了1个好方法。

我有这样的事情:

    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中使用吗?

谢谢你的答案.



1> polygenelubr..:

不要从构造函数中发现过多的方法.

来自Effective 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构造函数调用时overrideMe,Child尚未完成初始化final int x,并且该方法获取错误的值.这几乎肯定会导致错误和错误.

相关问题

从父类构造函数调用重写方法

当Base类构造函数在Java中调用重写方法时,Derived类对象的状态

也可以看看

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

推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有