Ido*_*dos 2 java methods inheritance constructor overriding
我偶然发现了这段代码.
我试着猜测在实际操作之前运行它的结果是什么.当我看到它们并需要一些解释时,我真的很困惑.
这是代码:
public class A {
String bar = "A.bar";
A() { foo(); }
public void foo() {
System.out.println("A.foo(): bar = " + bar);
}
}
public class B extends A {
String bar = "B.bar";
B() { foo(); }
public void foo() {
System.out.println("B.foo(): bar = " + bar);
}
}
public class C {
public static void main(String[] args) {
A a = new B();
System.out.println("a.bar = " + a.bar);
a.foo();
}
}
Run Code Online (Sandbox Code Playgroud)
输出是:
B.foo(): bar = null
B.foo(): bar = B.bar
a.bar = A.bar
B.foo(): bar = B.bar
Run Code Online (Sandbox Code Playgroud)
这是为什么?
bar = null?a.bar = A.bar甚至出现?我根本没有实例化A.A出现,为什么会之后 B?在我开始解释代码执行过程中的每一步之前,您应该了解一些事实:
super()放置隐含在每一个构造函数,即使你不把它存在自己(如果你调用它不叫super(int x, int y)为例).现在让我们一步一步地分解您的代码:
B通过调用其默认构造函数来实例化B().super()是隐式添加到任何构造函数,因此A()立即调用.A()你打电话里面foo(),在课堂上被覆盖B,这就是为什么foo()要从中调用B.B的foo(),你得到的输出B.foo(): bar = null,因为Java的没有得到初始化B的领域,但(其构造尚未执行!)和对象类型的字段将初始化为null默认.A()我们回到构造函数B().foo()一次,而这又是B的foo().但与上次不同的是,B将其字段初始化(在调用之后super()),以便获得预期B.foo(): bar = B.bar.main.a.bar,并因为正如我所说的字段引用是基于引用类型解决,你得到的场bar的A.a.foo()这再次触发B的foo(),其打印b.bar一次.我们完成了!:)
进一步的参考和值得阅读的材料:
静态和动态绑定解释
了构造函数调用的顺序
| 归档时间: |
|
| 查看次数: |
146 次 |
| 最近记录: |