Java方法覆盖和变量阴影

问题描述:

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());
    }

}

我无法理解上面代码的输出。输出为:

Hi, I am having trouble understanding the output of the code above. The output is:

Radius = 10.0
Radius = 10.0
Radius = 100.0
Radius = 10.0

我理解为什么gc.r是10.我也理解为什么gc。 getR()为10(因为GraphicCircle中的getR()方法会覆盖Circle的getR()方法)。但是我不明白为什么cr是100,而c.getR()是10(当你按照上面的代码进行类型转换为祖先类时,我很难理解继承中会发生什么)。

I understand why gc.r is 10. I also understand why gc.getR() is 10 (because the getR() method in the GraphicCircle overrides the getR() method of Circle). But I don't understand why c.r is 100, and c.getR() is 10 (I am having trouble understanding what happens in inheritance when you typecast to an ancestor class as the code has done above).

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

Method calls are virtual in Java, which means that the method from an object's actual type is called, regardless of what type the reference was which you used to access the object. Direct field access on the other hand is not virtual, so which r you access will depend on the type of the reference through which you reached it.