java中继承和变量阴影的编码问题

问题描述 投票:0回答:1

我对这段包含 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();       
}
java inheritance overwrite shadowing
1个回答
0
投票

弄清楚发生了什么情况的最简单方法是使用 IDE 中的调试器并单步执行每行代码,检查每一步中所有变量的值。

cnt1
中的字段
MyCounter1
阴影
Counter
中同名的字段。另一方面,
inc()
中的方法
MyCounter1
覆盖了Counter
中同名的方法。

当您调用

new MyCounter1()

 时,它会隐式调用 
super()
。因此 
Counter()
 被调用,然后又调用 
inc()
。它被 
Counter1
 覆盖,因此它调用 
Counter1
inc()
。这将运行 
cnt1 = cnt1 + 2;
,但 
Counter1
 实例尚未完全初始化。超类构造函数在子类字段初始化之前运行。因此,此时 
cnt1
 的初始值仍然是 0,因为直到 
super()
 构造函数返回之后它才会被设置为 5。

由此,你就可以弄清楚剩下的事情了。基本上,在超类构造函数中使用子类字段是令人困惑的,也是一个坏主意。另外,用

@Override

 注释覆盖的字段也是个好主意。

© www.soinside.com 2019 - 2024. All rights reserved.