我对这段包含 Counter 类、MyCounter1 类和 Java 中的 MyCounter2 类的代码有疑问;
我想知道为什么主方法中的两个输出会导致
output 1:
cnt1: 2 cnt2: 2
cnt1: 5 cnt2: 0
output 2:
cnt1: 3 cnt2: 3
cat1: 5 cnt2: 0
据我了解,当我在第一行代码(Counter m = new myCounter 1();) int main方法中调用构造函数mycounter1时,我先调用了基类Counter的构造函数,它调用了该方法公司()。
由于 inc() 方法在 myCounter1 类中被覆盖,我必须向 cnt1 和 cnt2 添加 2。 既然我的cnt1是5,为什么cnt1的输出仍然是2而不是5+2=7? cnt=5 和 cnt=0 的第二个结果来自哪里?
class Counter {
int cnt1 = 5;
int cnt2;
void inc() {
cnt1 = cnt1 + 1;
cnt2 = cnt2 + 1;
}
public Counter() {
inc();
cnt1 = cnt2 = 0;
}
}
class MyCounter1 extends Counter {
int cnt1 = 5;
void inc() {
cnt1 = cnt1 + 2;
cnt2 = cnt2 + 2;
System.out.println("cnt1: " + cnt1 + " cnt2: " + cnt2);
}
public MyCounter1() {
System.out.println("cnt1: " + cnt1 + " cnt2: " + cnt2);
}
}
class MyCounter2 extends MyCounter1 {
int cnt1;
void inc() {
cnt1 = cnt1 + 3;
cnt2 = cnt2 + 3;
System.out.println("cnt1: " + cnt1 + " cnt2: " + cnt2);
}
}
public static void main(String[] b) {
Counter m = new MyCounter1(); ``
m = new MyCounter2();
}
弄清楚发生了什么情况的最简单方法是使用 IDE 中的调试器并单步执行每行代码,检查每一步中所有变量的值。
cnt1
中的字段 MyCounter1
阴影 Counter
中同名的字段。另一方面,inc()
中的方法MyCounter1
覆盖了Counter
中同名的方法。当您调用
new MyCounter1()
时,它会隐式调用
super()
。因此
Counter()
被调用,然后又调用
inc()
。它被
Counter1
覆盖,因此它调用
Counter1
的
inc()
。这将运行
cnt1 = cnt1 + 2;
,但
Counter1
实例尚未完全初始化。超类构造函数在子类字段初始化之前运行。因此,此时
cnt1
的初始值仍然是 0,因为直到
super()
构造函数返回之后它才会被设置为 5。由此,你就可以弄清楚剩下的事情了。基本上,在超类构造函数中使用子类字段是令人困惑的,也是一个坏主意。另外,用
@Override
注释覆盖的字段也是个好主意。