构造器决不能调用可被覆盖的方法
2012-08-29 12:10
519 查看
在继承中,构造器决不能调用可被覆盖的方法,无论是直接调用还是间接调用。如果违反了这条规则,很可能导致程序失败。下面来看一个例子:
输出结果是:
调用子类方法
调用子类方法
因为超类中的构造器调用overrideMe方法是会调用子类中的覆盖版本,这是多态的特性。稍微改动一下代码:
这时会抛出NullPointerException,因为子类中的overrideMe覆盖版本将会在子类实例化完成之前就被父类构造器调用,而此时list尚未被实例化,因此抛出异常。
总结:构造器绝不能调用可以被覆盖的方法。构造器中唯一能安全调用的是基类中的private和final方法,因为他们不会被覆盖。
import java.util.ArrayList; class Super { public Super() { overrideMe(); } public void overrideMe() { System.out.println("调用父类方法"); } } public class Sub extends Super { private ArrayList list = new ArrayList(); Sub() { } @Override public void overrideMe() { System.out.println("调用子类方法"); } public static void main(String[] args) { Super s = new Sub(); s.overrideMe(); } } |
调用子类方法
调用子类方法
因为超类中的构造器调用overrideMe方法是会调用子类中的覆盖版本,这是多态的特性。稍微改动一下代码:
import java.util.ArrayList; class Super { public Super() { overrideMe(); } public void overrideMe() { } } public class Sub extends Super { private ArrayList list = new ArrayList(); Sub() { } @Override public void overrideMe() { System.out.println(list.size()); } public static void main(String[] args) { Super s = new Sub(); s.overrideMe(); } } |
总结:构造器绝不能调用可以被覆盖的方法。构造器中唯一能安全调用的是基类中的private和final方法,因为他们不会被覆盖。
相关文章推荐
- Super不要在Super构造器中调用覆盖方法
- 继承的约束:构造器不可调用被覆盖的方法
- 从父类构造器调用子类覆盖方法看Java初始化过程
- 重写的时候,构造器中调用方法容易错的问题
- java this 子类调父类,父类再调用子类已覆盖的方法及属性(又一次理解)
- EasyJS 教程五 - 抽象方法以及覆盖方法的调用
- java this 子类调父类,父类再调用子类已覆盖的方法及属性(又一次理解)
- java 构造方法的相互调用(在一个构造器中,通过this调用另一个构造器)
- 方法的重载,调用,构造器,我对它们的理解!
- js中的4种函数调用模式:函数调用、方法调用、构造器调用、间接调用
- java 关于继承中构造器和方法的调用
- 调用内部类的私有方法,其中内部类和外部类的构造器都是私有的
- Java 类加载、调用构造器、执行方法的过程
- java声明子类时,静态语句块、实例代码块、构造器方法这3者的调用顺序
- 21天精通java基础之Day19调用指定的属性方法构造器
- javascript四种调用方式——方法调用模式、函数调用模式、构造器调用模式和Apply或Call调用模式
- java程序练习:尝试创建一个父类,在父类中创建两个方法,在子类中覆盖第二个方法,为子类创建一个对象,将他向上转型到基类并调用这个方法。
- 用jni API 访问java对象的属性,方法,调用构造器
- 如何防止覆盖(override)toString方法时产生递归调用
- 反射之字段、方法、构造器的调用(二)