Reputation: 11257
I have 3 classes:
public class Alpha {
public Number number;
}
public class Beta extends Alpha {
public String number;
}
public class Gama extends Beta {
public int number;
}
Why does the following code compile? And, why does the test pass without any runtime errors?
@Test
public void test() {
final Beta a = new Gama();
a.number = "its a string";
((Alpha) a).number = 13;
((Gama) a).number = 42;
assertEquals("its a string", a.number);
assertEquals(13, ((Alpha) a).number);
assertEquals(42, ((Gama) a).number);
}
Upvotes: 81
Views: 81106
Reputation: 34215
Java Hiding a field
When successor has a field with the same name as a superclass's field it is called - Hiding a field
Java's field does not support polymorphism and does not take a field's type into account
class A {
String field = "A: field";
String foo() {
return "A: foo()";
}
}
class B extends A {
//B's field hides A's field
String field = "B: field";
String foo() {
return "B: foo()";
}
}
@Test
public void testPoly() {
A a = new A();
assertEquals("A: field", a.field);
assertEquals("A: foo()", a.foo());
B b = new B();
assertEquals("B: field", b.field);
assertEquals("B: foo()", b.foo());
//B cast to A
assertEquals("A: field", ((A)b).field); //<--
assertEquals("B: foo()", ((A)b).foo());
}
Upvotes: 5
Reputation: 199
As a workaround, you can use getter methods:
class A {
private String field = "A: field";
String getField() {
return field;
}
}
class B extends A {
private String field = "B: field";
@Override
String getField() {
return field;
}
}
Upvotes: 3
Reputation: 206796
Member variables cannot be overridden like methods. The number
variables in your classes Beta
and Gama
are hiding (not overriding) the member variable number
of the superclass.
By casting you can access the hidden member in the superclass.
Upvotes: 98
Reputation: 1500405
Fields can't be overridden; they're not accessed polymorphically in the first place - you're just declaring a new field in each case.
It compiles because in each case the compile-time type of the expression is enough to determine which field called number
you mean.
In real-world programming, you would avoid this by two means:
Upvotes: 61