Java 在继承中,基构造函数调用虚方法,为什么类是Dervied并调用Dervied方法?
我遇到了一个问题。以下代码未按预期运行:Java 在继承中,基构造函数调用虚方法,为什么类是Dervied并调用Dervied方法?,java,inheritance,constructor,Java,Inheritance,Constructor,我遇到了一个问题。以下代码未按预期运行: public class Dervied extends Base { private String name = "dervied"; public Dervied() { System.out.println(this.getClass().toString()); this.tellName(); } public void tellName() { System.ou
public class Dervied extends Base {
private String name = "dervied";
public Dervied() {
System.out.println(this.getClass().toString());
this.tellName();
}
public void tellName() {
System.out.println("Dervied tell name: " + name);
}
public static void main(String[] args) {
Base base = new Dervied();
}
}
class Base {
private String name = "base";
public Base() {
System.out.println(this.getClass().toString());
this.tellName();
}
public void tellName() {
System.out.println("Base tell name: " + name);
}
}
结果是:
class Dervied
Dervied tell name: null
class Dervied
Dervied tell name: dervied
但是为什么呢?环境是jdk1.8.0_60和Windows 10。当
new Dervied()
运行Dervied()
方法时,调用基构造函数base()
。但是为什么Base()
中的打印类是Dervied
?而this.tellName()
将Dervied
类中的方法作为多态性调用?这就是为什么我们不应该从构造函数调用虚拟方法的原因。当构造函数运行时,有不同的阶段。首先运行基类构造函数,然后运行派生类构造函数
因此,虚拟调用将取决于构造函数所处的阶段,它可能会在尚未存在的对象上调用方法
这就是为什么会显示null,因为派生类中的“name”实例变量尚未初始化,因为基类构造函数正在运行,它调用派生类对象的tellName()
以下是约书亚·布洛赫(Joshua Bloch)的《有效的Java-第二版》中的相关引用:
超类构造函数在子类构造函数之前运行,因此
子类中的重写方法将在
子类构造函数已运行。如果重写方法依赖于任何
由子类构造函数执行初始化时,该方法将
表现不如预期
这就是为什么我们不应该从构造函数调用虚拟方法的原因。当构造函数运行时,有不同的阶段。首先运行基类构造函数,然后运行派生类构造函数 因此,虚拟调用将取决于构造函数所处的阶段,它可能会在尚未存在的对象上调用方法 这就是为什么会显示null,因为派生类中的“name”实例变量尚未初始化,因为基类构造函数正在运行,它调用派生类对象的tellName() 以下是约书亚·布洛赫(Joshua Bloch)的《有效的Java-第二版》中的相关引用: 超类构造函数在子类构造函数之前运行,因此 子类中的重写方法将在 子类构造函数已运行。如果重写方法依赖于任何 由子类构造函数执行初始化时,该方法将 表现不如预期
字段不具有多态性。字段不具有多态性。