理系学生日記

おまえはいつまで学生気分なのか

フィールドの隠蔽

プログラミング言語 Java より.

public class SuperShow {
	public String str = "SuperStr";
	public void show() {
		System.out.println("Super.show: " + str);
	}
}

public class ExtendShow extends SuperShow {
	public String str = "ExtendShow";
	
	public void show() {
		System.out.println("Extend.show: " + str);
	}
	
	public static void main(String[] args) {
		ExtendShow ext = new ExtendShow();
		SuperShow  sup = ext;
		sup.show();
		ext.show();
		System.out.println("sup.str = " + sup.str);
		System.out.println("ext.str = " + ext.str);
	}
}

これを実行させると,次のような出力が得られる.

Extend.show: ExtendShow
Extend.show: ExtendShow
sup.str = SuperStr
ext.str = ExtendShow

show メソッドは ExtendShow クラスでオーバライドしているので,sup.show() であろうと ext.show() であろうと結局は ExtendShow の show メソッドが呼び出されるわけで,この点はまぁ分かりやすいのであるが,メンバ変数(Java ではフィールドって言った方が正しい?)str に関しては,sup.str は SuperShow クラスの str 変数を参照するようになる.

そもそもサブクラスにて親クラスを持つフィールドと同名のフィールドを定義するのなんて禁止しとけよとちょっと思ったのだけれど,これは許されている.なぜなら,サブクラスが定義された後に親クラスにフィールドが追加される場合,サブクラスの持つフィールドと名前が衝突するフィールドを定義してしまうと,子クラスが使えなくからということらしい.