- ベストアンサー
クラス変数/メソッドとインスタンス変数/メソッドの見え方について
Javaの言語仕様(?)についてお教え下さい。 参照変数の型がインスタンスのスーパークラスの型の時、クラス変数/メソッドとインスタンス変数/メソッドの見え方が納得いかずに困っています。 以下のような条件の時です。 ・クラスが2つあり、1つはもう1つのクラスを継承しています。 それぞれを「スーパー」「サブ」と以下で呼びます。 ・インスタンスは"サブ"の型です。 ・上記インスタンスへの参照変数は"スーパー"のクラスの型です。 ・"スーパー"、"サブ"ともに【同名】の「クラス」変数/メソッド、「インスタンス」変数/メソッドがあります。 この場合に、"サブ"のインスタンスを参照している"スーパー"の型の変数を介し、それらにアクセスしたらどれが見えるか?という疑問です。 実験結果では以下のようになりました。 [フィールド] [メソッド] [1.static ] スーパーの スーパーの [2.非static] スーパーの サブの 納得いかないのは「2.非static」で「フィールド」が、「スーパーの」になるところです。 これも「サブの」になると思っていました。 なぜサブクラスのが見えないのでしょうか? 同名の変数なのでスーパークラスのはサブクラスので隠れされ、サブクラスのが見えると思っていたのですが。 参考書には以下のように書いてありました。 フィールドの場合、参照変数の型のものが見える。 メソッドの場合、インスタンスの型のものが見える。 私には不自然に感じられるのですが、「こういう仕様だから。」と納得するしか無いのでしょうか? 「なぜこうなるか」について説明がある文献、サイトなどありましたらお教えください。 参考までに以下が実験したサンプルコードと結果です。長くて申し訳ありません。 「サンプルコード」 public class Super { static int staticField = 10; int instanceField = 100; static void staticMethod() { System.out.println( "staticField = " + staticField ); } void instanceMethod() { System.out.println( "instanceField = " + instanceField ); } } public class Sub extends Super { static int staticField = 90; int instanceField = 900; static void staticMethod() { System.out.println( "staticField = " + staticField ); } void instanceMethod() { System.out.println( "instanceField = " + instanceField ); } } public class TestStatic { public static void main(String[] args) { // インスタンスはSub、参照変数もSub、という状態。 Sub sub = new Sub(); System.out.println( "実験1" ); System.out.println( "1.クラス変数 " + sub.staticField ); System.out.print( "2.クラスメソッド " ); sub.staticMethod(); System.out.println( "3.インスタンス変数 " + sub.instanceField ); System.out.print( "4.インスタンスメソッド " ); sub.instanceMethod(); // インスタンスはSub、参照変数はSuper、という状態。 Super sup = new Sub(); System.out.println( "実験2" ); System.out.println( "5.クラス変数 " + sup.staticField ); System.out.print( "6.クラスメソッド " ); sup.staticMethod(); System.out.println( "7.インスタンス変数 " + sup.instanceField ); System.out.print( "8.インスタンスメソッド " ); sup.instanceMethod(); } } 「結果」 実験1 1.クラス変数 90 2.クラスメソッド staticField = 90 3.インスタンス変数 900 4.インスタンスメソッド instanceField = 900 実験2 5.クラス変数 10 6.クラスメソッド staticField = 10 7.インスタンス変数 100 8.インスタンスメソッド instanceField = 900 納得が行かないのは7のところです。 以上よろしくお願いいたします。
- みんなの回答 (3)
- 専門家の回答
お礼
ご回答ありがとうございます。 おかげさまで ・メソッドがオーバーライドされる ・フィールドはオーバーライドされない というメカニズムは良く分かりました。 ただ、「フィールドはオーバーライドされない」の理由というか「思想」がやっぱりしっくりきません。 メソッドはポリモルフィズムの実現のためにオーバーライドされるのは自然だと思いますし、 ついでと言ってはなんですが、フィールドも同様にすればいいのにと感じてしまうので・・・ これはもうとりあえず「そういうもの」と受け入れることにします。 今までもオブジェクト指向で 「ルールは分かったが、なんでこんな?」 というのは色々ありました。 ですが「ある日突然腑に落ちた。納得できた。」という瞬間が来ました。 今回もそのうちそういう瞬間が来ることを信じてみます。 色々とご教示ありがとうございました。