こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

メソッドが同じオブジェクトのフィールドを参照しません

<test1.javaファイル>
import java.awt.*;

public class test1 {
//フィールドの定義
public int x = 10;

//メソッドの定義
public void drawMoji(Graphics g) {
g.drawString("xの値は、" + x, 20, 20);
}
}

<test2.javaファイル>
public class test2 extends test1 {
//フィールドの定義
public int x = 20;
}

<mt.javaファイル>
import java.awt.*;
import java.applet.*;

/*
<applet code = "mt" width = 300 height = 200>
</applet>
*/
public class mt extends Applet {
public void paint(Graphics g) {
//インスタンスの作成
test2 t2 = new test2();

//xの値を表すメソッドの実行
t2.drawMoji(g);
}
}

上記の3つのファイルをコンパイルして、mt.javaファイルをアプレットビュアーで実行したら、"xの値は、20"と表示したいのに、"xの値は、10"と表示されます。t2オブジェクトのフィールドのxの値が20だから、t2.drawMoji(g)で"xの値は、20"と表示されると思うのですが、どうしてこうなるのでしょうか?教えてください。

投稿日時 - 2005-03-24 17:50:11

QNo.1288765

ab5

困ってます

質問者が選んだベストアンサー

このケースはJAVA言語仕様でいうところの、変数の隠蔽と呼ばれるものです。
スーパークラスの変数へアクセスする際には「super」を使用します。このケースでは「super.x」となります。
隠蔽とは継承されたクラスでスーパーなクラスの持つ変数、メソッドと同じシグネチャを持つものを持たせ、スーパーなクラスへのアクセスを制限すると言うものです。
継承関係にあるクラスはスーパーなクラスのメソッド、変数をそれぞれ独立して持ちます。
継承したクラスに宣言せずともスーパーなクラスのメソッドを呼べるのは決まりとしてスーパーのメソッドを呼び出すという仕様になっているからです。
しかし、同じシグネチャのメソッドを継承クラスで宣言すると別々の動きを行う同じシグネチャのメソッドが複数存在することが可能になります。
変数も同様です。ですので、superを使用することにより複数の空間を使い分けることが可能な仕様となっています。
オーバーライドという手法はインターフェイスとしてこのうちの継承クラスの機能のみを公開するという方法です。

投稿日時 - 2005-03-30 03:40:49

お礼

丁寧な解説をありがとうございました。

投稿日時 - 2005-04-01 10:50:11

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.1

UKY

これだと、test1 と test2 で《それぞれ一つずつ》 x というフィールドを定義したことになります。
サブクラスで同じ名前のフィールドを宣言しても「上書き」したことにはなりません。

g.drawString("xの値は、" + x, 20, 20);
の「x」は (メソッドと同じクラスである) test1 の x なので、表示されるのは「10」になります。

私の過去の回答を参考にしてください。
http://oshiete1.goo.ne.jp/kotaeru.php3?q=1201607&rev=1

参考URL:http://oshiete1.goo.ne.jp/kotaeru.php3?q=1201607&rev=1

投稿日時 - 2005-03-24 18:39:22

お礼

ありがとうございました。

投稿日時 - 2005-04-01 10:51:33

あなたにオススメの質問