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);
}
メンバー変数はメソッドのようにオーバーライドできません。クラスnumber
およびBeta
のGama
変数は、スーパークラスのメンバー変数number
の-非表示(オーバーライドではない)です。
キャストすることにより、スーパークラスの非表示のメンバーにアクセスできます。
フィールドをオーバーライドにすることはできません。そもそも多態的にアクセスされることはありません。それぞれの場合に新しいフィールドを宣言するだけです。
いずれの場合も、式のコンパイル時のタイプは、whichnumber
というフィールドを意味するのに十分であるため、コンパイルされます。
実際のプログラミングでは、次の2つの方法でこれを回避します。