Java override method and variable shadow

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 above code. Output:

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

      

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 () Circle method). But I donโ€™t understand why cr is 100 and c.getR () is 10 (I am having trouble understanding what happens in inheritance when you step into the ancestor class, as the code above did).

+3


source to share


3 answers


Method invocation is virtual in Java, which means that the method is called from the actual type of the object, regardless of what type of reference was used to access the object. Direct access to a field, on the other hand, is not virtual, so which access r

will depend on the type of link through which you reached it.



+2


source


You can override methods, not fields or class variables. This way it is getR()

overridden and actually displays what you expect.

Once c.r

you get it, you will have access to the circle class variable, not the GC.



It's also a bad habit to publish class variables. They should be private, or at least secure and accessible using getters and setters ( more on private fields ).

+4


source


First of all, the field is r

not shaded, it is hidden.

Second, the technical term for overriding methods is called dynamic binding. It simply means that at runtime, the actual class of the instance is examined when looking for the method that is called.

On the other hand, we have static linking for fields. This means that the compiler already permits all field accesses, and the compiler only knows about the declared types.

So the conclusion:

System.out.println("Radius = " + c.r);

      

This prints 100.0

because the variable is of type Circle

, so the compiler writes the field access to Circle.r

byte code.

+2


source







All Articles