请考虑以下代码。
class Base{
Base() {
print();
}
void print() {
System.out.println("Base");
}
}
class Child extends Base{
int i = 4;
public static void main(String[] args){
Base base = new Child();
base.print();
}
void print() {
System.out.println(i);
}
}
程序将打印0,4。
我理解的是,将根据实际对象的类选择要执行的方法,因此在这种情况下为Child
。因此,当调用Base
的构造函数时,会调用Child
的打印方法,因此将打印0,4。
请告诉我是否理解正确吗?
如果是,我还有一个问题,而基类构造函数正在运行JVM如何调用Child
的方法,因为Child
的对象未被创建?
答案 0 :(得分:7)
[...]将根据实际对象的类别选择要执行的方法
是的,您的理解是正确的:根据正在创建的对象的类型选择方法,因此呼叫将发送到Child.print()
而不是Base.print()
。
当
Base
类构造函数正在运行时,JVM如何调用Child
的方法,因为Child
的对象未创建?
当Base
的构造函数正在运行时,Child
对象已经创建。但是,它未完全初始化。这正是避免调用可以在构造函数内部覆盖的方法的原因:语言允许它,但程序员在执行时应该格外小心。
有关基类构造函数调用可覆盖方法时可能发生的问题的更多信息,请参阅this Q&A。
答案 1 :(得分:0)
将根据实际对象的类别选择要执行的方法
是的,这是正确的。
Base base = new Child();
。它不会以你认为它while Base class constructor is running how come JVM can call Child's method since Child's object is not created?
的方式发生。
这里发生的是,Child实例被创建,而Child实例是通过Child的默认构造函数创建的,它首先调用超级构造函数that is where the 0 get printed