プロが教えるわが家の防犯対策術!

親クラスと子クラスのフィールドとメソッドについて

以下のサンプルソースを実行した時の動作の原理について
教えてください。

oya型変数にkoクラスのインスタンスを作成した場合、
メソッドはkoクラスのものなのに、
フィールドはoyaクラスのものになるということが
イマイチすっきり理解できません。

どういうことなんでしょうか。



-------------------------------------------------------
[ソース]

public class exec {
public static void main( String args[]){
oya obj = new ko();
System.out.println(obj.str_field);
obj.disp_field();
}
}

public class oya{
String str_field="親実行";
public void disp_field(){
System.out.println(str_field);
}
}

public class ko extends oya {
String str_field = "子実行";
public void disp_field(){
System.out.println(str_field);
}
}
-------------------------------------------------------
[実行結果]

> 親実行
> 子実行

-------------------------------------------------------

A 回答 (2件)

一言で答えるなら、「メソッドはオーバーライドできるが、フィールドはオーバーライドできないから」です。



もう少し説明してみます。区別のために、oyaクラスのstr_fieldをF1、koクラスのstr_fieldをF2と呼ぶことにします。
oyaクラスのオブジェクトは当然F1しか持っていませんが、実はkoクラスのオブジェクトはF1とF2の両方を持っています。
さらに、フィールドのアクセスは内部的にはフィールドの名前ではなくて「このオブジェクトのn番目のフィールド」という形で行われます。
execクラスとoyaクラスでのstr_fieldへのアクセスは1番目のフィールド(F1)へのアクセス、koクラス内でのstr_fieldへのアクセスは2番目のフィールド(F2)へのアクセスとして理解されます。
したがって、execクラス内でobjが指しているのがkoクラスのオブジェクトであっても、koのF1へアクセスするので「親実行」の文字列が得られます。

この回答への補足

解答ありがとうございます。

> メソッドはオーバーライドできるが、
> フィールドはオーバーライドできないから

ソースを書き換え、ko型変数にkoクラスのインスタンスを
作成するように変更した場合は、str_fieldへのアクセスが
koクラスのものになることに説明がつかないように感じます。

恐縮ですが、こちらについてもご回答いただけないでしょうか。

補足日時:2010/01/24 13:27
    • good
    • 0

Javaの仕様ではフィールドにアクセスする場合には変数の型に依存します。


質問文ではoyaクラスの変数objからobj.str_fieldとなっていますので、
oyaクラスのフィールドの値である"親実行"が表示されます。
koクラスの変数objでobj.str_fieldとすれば
koクラスのフィールドの値である"子実行"が表示されます。
言語仕様のサイトのフィールドとメソッドの名前解決に関するリンクを紹介しておきます。
http://www.y-adagio.com/public/standards/tr_java …
http://www.y-adagio.com/public/standards/tr_java …
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!