class B{
B(){
f();
}
public void f(){
System.out.println("B ctor");
}
}
class A extends B{
A(){
f();
}
@Override
public void f(){
System.out.println("A ctor");
}
public static void main(String[] args) {
A a = new A();
a.f();
B b = new B();
b.f();
}
}
上述程序的输出是
A ctor
A ctor
A ctor
B ctor
B ctor
任何人都可以解释我们是如何获得输出的。
答案 0 :(得分:1)
让我们尝试通过添加更多打印来可视化发生的事情:
class B{
B(){
System.out.println("binit");
f();
}
public void f(){
System.out.println("B ctor");
}
}
class A extends B{
A(){
System.out.println("ainit");
f();
}
@Override
public void f(){
System.out.println("A ctor");
}
public static void main(String[] args) {
System.out.println(1);
A a = new A();
System.out.println(2);
a.f();
System.out.println(3);
B b = new B();
System.out.println(4);
b.f();
}
}
我们的输出现在是:
1
binit
A ctor
ainit
A ctor
2
A ctor
3
binit
B ctor
4
B ctor
那么这里发生了什么?在1和2之间我们有两个初始化,即使我们只实例化了A.这是因为子类(A扩展B)默认情况下将调用超类(在本例中为B)构造函数作为实例化的第一件事。 B的构造函数调用f()。但是这个f已被A覆盖,而不是打印" B ctor"将打印" A ctor"。 之后,A的构造函数运行,并打印" A ctor"通过调用他自己的overrode f。
2之后发生的事情非常简单。唯一的区别是,当我们实例化B(在4之后)时,我们不使用覆盖f,而是使用原始覆盖f,因此我们打印" B ctor"。
知道了吗?