luk*_*uku 11 java polymorphism inheritance constructor overriding
类在构造函数中A
调用public方法f()
.B类f()
使用自己的实现覆盖方法.
假设你intantiate对象B
..方法f()
对象B
将在对象的构造函数被调用A
,虽然对象B
未完全初始化.
谁能解释这种行为?
编辑:是的,它不推荐练习..但我不明白为什么 Java不调用f()
基类的实现A
而不是"伸出"到f()
派生类的实现B
.
码:
class A {
A() {
System.out.println("A: constructor");
f();
}
public void f() {
System.out.println("A: f()");
}
}
class B extends A {
int x = 10;
B() {
System.out.println("B: constructor");
}
@Override
public void f() {
System.out.println("B: f()");
this.x++;
System.out.println("B: x = " + x);
}
}
public class PolyMethodConst {
public static void main(String[] args) {
new B();
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
A: constructor
B: f()
B: x = 1
B: constructor
Run Code Online (Sandbox Code Playgroud)
你是对的,这就是它的工作方式.但是不建议这样做,因为从你的班级继承的人可能会无意中破坏它.
每当您创建子类的实例时,首先调用超类构造函数(隐式super()
)。所以它打印
a: constructor
Run Code Online (Sandbox Code Playgroud)
f()
接下来调用,并且由于子类覆盖超类方法,因此f()
调用子类。所以你会看到
B: f()
Run Code Online (Sandbox Code Playgroud)
现在,子类还没有初始化(仍然 super() 正在执行)所以x
默认值为该值,0
因为这是 type 的默认值int
。因为你增加了它 ( this.x++;
) 它变成1
B: x = 1
Run Code Online (Sandbox Code Playgroud)
现在,超类构造函数完成并在子类构造函数处恢复,因此
B: constructor
Run Code Online (Sandbox Code Playgroud)
实例变量现在设置为您指定的值(针对与类型相对应的默认值(0
对于数字、false
对于boolean
和null
对于引用))
注意:如果您现在x
在新创建的对象上打印 的值,它将是10
由于这是一种不好的做法,如果您尝试这样做,静态代码分析工具(PMD、FIndBugs 等)会警告您。