Java方法覆写和可变阴影

The*_*ard 7 java inheritance

public class Circle {
    public float r = 100;
    public float getR() {
        return r;
    }
}

public class GraphicCircle extends Circle {
    public float r = 10;
    public float getR() {
        return r;
    }

    // Main method
    public static void main(String[] args) {
        GraphicCircle gc = new GraphicCircle();
        Circle c = gc;
        System.out.println("Radius = " + gc.r);
        System.out.println("Radius = " + gc.getR());
        System.out.println("Radius = " + c.r);
        System.out.println("Radius = " + c.getR());
    }

}
Run Code Online (Sandbox Code Playgroud)

嗨,我在理解上面代码的输出时遇到了麻烦。输出为:

Radius = 10.0
Radius = 10.0
Radius = 100.0
Radius = 10.0
Run Code Online (Sandbox Code Playgroud)

我理解为什么gc.r是10。我也理解为什么gc.getR()是10(因为GraphicCircle中的getR()方法覆盖了Circle的getR()方法)。但是我不明白为什么cr是100,而c.getR()是10(我很难理解当您像上面的代码那样键入到祖先类时继承中会发生什么)。

Mic*_*ski 6

方法调用在Java中是虚拟的,这意味着将调用对象实际类型中的方法,而无论引用是用来访问对象的类型是什么。另一方面,直接字段访问不是虚拟的,因此r您要访问的字段将取决于通过其访问的引用的类型。


Adv*_*cer 6

您可以覆盖方法,而不是字段或类变量。因此getR()被覆盖,它实际上显示了您的期望。

让c.r您访问circle的类变量而不是GC的类变量。

公开类变量也是一个坏习惯。它们应该是私有的,或者至少是受保护的,并且可以使用getter和setter(更多关于私有字段)来访问它们。