【Java】初心者が間違えがち?継承によるメンバ変数の隠蔽

  • 2018年4月25日
  • 2018年9月24日
  • 技術系
  • 1429view
  • 0件

少し前から「Oracle Certified Java Programmer, Gold」の勉強をしているのですが「継承によるメンバ変数の隠蔽」で、

同じ間違いを何度もしたので自戒の念も込めて書きます。

メンバ変数の隠蔽とは?

メンバ変数の隠蔽とはサブクラス内で、スーパークラスで定義しているメンバ変数(フィールド)と同じ名前で再定義することです。

以下の例だと、Superクラスを継承したSubクラス内でメンバ変数の”hoge”を再定義しています。

で、どんな間違いをしたのか

まずは、以下のコードを見てください。

このコードをコンパイル、実行した結果は、

Super

となります。

「いやいや、そんなの当たり前でしょ!」と思った方はさすがです。続きを読んでも何も得られるものはないので、そっとブラウザバックしてください><

 

「え、なんで??」と思った方、僕と同じです。解説しますね。

注目すべきは、変数”obj”を宣言する時の型

メンバ変数へのアクセスは参照範囲内の変数にアクセスします。先ほどのコードだと”obj”はSuperクラス型で宣言しているので”obj”の参照範囲はSuperクラス内になります。

 

“obj”の型をSubクラス型に変更して実行すると結果は、

Sub

となります。

“obj”をSubクラス型で宣言した場合は、Superクラスの”hoge”が隠蔽されてSubクラスの”hoge”にアクセスします。

 

参照範囲に関連して少し話を変えます。以下のコードを見てください。

このコードは、19行目でコンパイルエラーが発生します。

“obj”をSuperクラス型で宣言してるのに、19行目でSuperクラスの参照範囲外である”huga”にアクセスしようとしているので、「そんなメンバ変数、Superクラスに定義されてねーよ!」と怒られちゃうわけです。

“obj”の型をSubクラスに変更し、19行目で”hoge”にアクセスするように変更した場合はエラーは発生しません。SubクラスはSuperクラスを継承しているため、Superクラス内のメンバ変数も参照範囲に含まれるためです。※ただし”hoge”のアクセス修飾子がprivate の時は参照できません。

まとめ

継承によるメンバ変数の隠蔽は次のポイントを抑えとく。

●変数をSuperクラスで宣言した場合

Superクラス内のメンバ変数にアクセスする

●変数をSubクラスで宣言した場合

Superクラス内で定義しているメンバ変数と同名の変数を定義している場合は、Superクラスのメンバ変数が隠蔽されてSubクラス内のメンバ変数にアクセスする

ちなみに、メンバ変数を例にしてましたが、staticメソッドの場合もメンバ変数の隠蔽と同様のルールです。

Superクラス内のstaticメソッドと同名のstaticメソッドをサブクラス内で再定義することは、オーバライドではなく隠蔽なので注意が必要です。

 

 

これが初投稿ですが、ものすごく時間がかかった…。

もっとスラスラ  かつ 見やすく書けるようになりたい。