【发布时间】:2016-09-26 02:33:33
【问题描述】:
假设你有以下代码
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
- 我明白如果没有 int i=2;线,
A a = new B();会调用A类,初始化i为4,调用构造函数,
这将控制权交给class B 中的print() 方法,最后打印4。
a.print() 将调用 B 类中的 print() 方法,因为这些方法将在运行时绑定,这也将使用在 A 类中定义的值 4。
(当然如果我的推理有任何错误,请告诉我)
- 但是,我不明白的是是否存在 int i=2。
为什么如果插入代码,第一部分(创建对象)会突然打印 0 而不是 4?为什么不将变量初始化为i=4,而是赋值为默认值?
【问题讨论】:
-
当你调用某个类的构造函数时,它的超类的构造函数会在它的构造函数之前被调用,我想你知道的。你知道超类的字段也是在构造函数调用之前初始化的吗?
-
一个很好的例子,说明为什么从构造函数调用可覆盖的方法是一个坏主意 - 结果充其量是令人困惑的,更常见的是危险(可能泄漏对部分初始化对象的引用)。
标签: java variables constructor initialization polymorphism