这是代码,我定义了两个名为Father和Son的类,并在main函数中创建它们:
public class Test {
public static void main(String[] args) {
Father father = new Son();
}
}
class Father {
private String name = "father";
public Father() {
who();
tell(name);
}
public void who() {
System.out.println("this is father");
}
public void tell(String name) {
System.out.println("this is " + name);
}
}
class Son extends Father {
private String name = "son";
public Son() {
who();
tell(name);
}
public void who() {
System.out.println("this is son");
}
public void tell(String name) {
System.out.println("this is " + name);
}
}
我得到了这样的输出:
this is son
this is father
this is son
this is son
但我无法理解这是怎么发生的?任何人都可以告诉我为什么?
答案 0 :(得分:9)
让我们从Son
的构造函数开始。
public Son() {
super(); // implied
who();
tell(name);
}
调用父的构造函数。
public Father() {
who();
tell(name);
}
由于who()
会覆盖Son
,因此会调用Son
的版本,打印“这是儿子”。
tell()
也被覆盖,但传入的值为Father.name
,打印“这是父亲”。
最后,who()
的构造函数中的tell(name)
和Son
调用将分别打印“this is son”和“this is son”。
答案 1 :(得分:6)
以下是所谓的:
new Son()
=>
Son._init
=> first every constructor calls super()
Father._init
Object._init
who() => is overridden, so prints "son"
tell(name) => name is private, so cannot be overridden => "father"
who() => "son"
tell(name) => "son"
要学习的经验教训:
答案 2 :(得分:3)
当您创建Son
实例时,将调用父类的构造函数(即Father()
);这里调用了who()
方法,但它是你在Son
中声明的重写版本,所以这是你的第一行(其中String在方法中被硬编码)。
第二行来自tell(name)
内Father()
,其中tell()
被覆盖但name == "father"
因为调用来自Father
的构造函数, name
是private
类的Father
字段。
控制返回Son()
构造函数,最后两行直接来自Son
类构造函数。
答案 3 :(得分:2)
Father()
之前调用 Son()
。隐式调用超类默认构造函数,我们这里不需要super()
语句。
who()
的构造函数中的Father()
调用重写方法。
答案 4 :(得分:0)
上面的代码特别是Bad Style(TM)。 ; - )
会发生什么:没有父实例,只有Son实例。 (然而,它与父亲的任务兼容。)
Son构造函数调用父构造函数。后者调用重写的(!)方法,因此永远不会调用Father.who和Father.tell!在子构造函数完成之前(!)调用重写的方法。
我的建议: