Reputation: 953
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
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).
Upvotes: 9
Views: 2297
Reputation: 20658
First of all, the field r
is not shadowed, it is hidden.
Second, the technical term in respect to overriding methods is called dynamic binding. That simply means that at runtime the actual class of the instance is being consulted when looking up the method that is being called.
On the other hand, for fields we have static binding. That means that the compiler already resolves all field accesses, and the compiler only knows about declared types.
So the conclusion is:
System.out.println("Radius = " + c.r);
This prints 100.0
as the variable is of type Circle
, so the compiler writes the access to field Circle.r
into the byte code.
Upvotes: 4
Reputation: 1330
You can override methods, not fields or class variables. So getR()
is overridden and it actually displays what you're expecting.
Getting c.r
you access circle's class variable and not GC's.
It also a bad habit to make class variables public. They should be private or at least protected and accessed them using getters and setters (more about private fields).
Upvotes: 7
Reputation: 10020
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.
Upvotes: 8