• ベストアンサー

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

<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"と表示されると思うのですが、どうしてこうなるのでしょうか?教えてください。

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

  • ベストアンサー
  • covachan
  • ベストアンサー率38% (46/120)
回答No.2

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

ab5
質問者

お礼

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

その他の回答 (1)

  • UKY
  • ベストアンサー率50% (604/1207)
回答No.1

これだと、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
ab5
質問者

お礼

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

関連するQ&A

専門家に質問してみよう