假设您有以下代码
class A {
int i = 4;
A() {
print();
}
void print () {
System.out.println("A");
}
}
class B extends A {
int i = 2; //"this line"
public static void main(String[] args){
A a = new B();
a.print();
}
void print () {
System.out.println(i);
}
}
这将打印 0 2
现在,如果删除标有“此行”的行
代码将打印 4 4
A a = new B();
将调用类 A,将 i 初始化为 4,调用构造函数,
这使得控制权print()
中的方法class B
,最后打印 4。
a.print()
将会通知print()
B 类中的方法,因为这些方法将在运行时绑定,这也将使用 A 类中定义的值,4。
(当然,如果我的推理有任何错误,请告诉我)
为什么如果插入代码,第一部分(创建对象)会突然打印 0 而不是 4?为什么它不将变量初始化为 i=4,而是分配默认值?
它是Java中几种行为的组合。
- 方法重写
- 实例变量阴影
- 构造函数的顺序
我将简单地回顾一下您的代码中发生的情况,看看您是否理解。
从概念上讲,您的代码如下所示(跳过 main()):
class A {
int i = 0; // default value
A() {
A::i = 4; // originally in initialization statement
print();
}
void print () {
System.out.println("A");
}
}
class B extends A {
int i = 0; // Remember this shadows A::i
public B() {
super();
B::i = 2;
}
void print () {
System.out.println(i);
}
}
所以,当你原来的main()
, 你打过电话了A a = new B();
,它正在构建一个B
,发生这种情况:
-
A::i
and B::i
都是默认值0
- super(), which means A's constructor is called
-
A::i
设置为 4
-
print()
叫做。由于后期绑定,必然会B::print()
-
B::print()
正在尝试打印B::i
,仍然是 0
-
B::i
设置为 2
然后当你打电话时a.print()
在你的main()
,它有界于B::print()
正在打印B::i
(此时为 2)。
因此你看到的结果
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)