我有3个班级:
public class Alpha {
public Number number;
}
public class Beta extends Alpha {
public String number;
}
public class Gama extends Beta {
public int number;
}
为什么以下代码会编译?而且,为什么测试通过而没有任何运行时错误?
@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);
}
答案 0 :(得分:62)
成员变量不能像方法一样被覆盖。您的班级number
和Beta
中的Gama
个变量隐藏(不会覆盖)超类的成员变量number
。
通过强制转换,您可以访问超类中的隐藏成员。
答案 1 :(得分:43)
字段不能重写;它们首先不是多态访问的 - 你只是在每种情况下声明一个新字段。
它编译,因为在每种情况下,表达式的编译时类型足以确定您所指的number
字段。
在实际编程中,您可以通过两种方式避免这种情况:
答案 2 :(得分:0)
当后继者的字段与超类的字段具有相同的名称时,该字段称为-隐藏字段
Java的字段不支持多态,并且不考虑字段的类型
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());
}