―Javaプログラミングの前提知識―

@ITハイブックス編
2003/2/27
Javaプログラミング
ワンポイントレクチャーについて

   ThisとSuperを使い分ける

   ワンポイントQuestion

 次のプログラムを実行したときの結果として正しいものはどれですか? (単一選択)

1: class This_Super{
2:   int i=1;
3:
4:   void print(){
5:     System.out.print(i);
6:   }
7: }
8:
9: class Sub_This_Super extends This_Super{
10:  int i=2;
11:  void print(){
12:    int i=3;
13:    super.print();
14:    System.out.print(this.i);
15:    System.out.print(super.i);
16:  }
17:}
18:
19:class Create{
20:  public static void main(String args[]){
21:    Sub_This_Super st=new Sub_This_Super();
22:    st.print();
23:  }
24:}

A コンパイルエラーで実行できない
B 1
C 121
D 111
E 222
FF 212

   配列の宣言方法

 キーワード「this」と「super」は、それぞれ自オブジェクトの参照、親オブジェクトの参照を意味するキーワードです。例えば、以下のようなコードがあります。

class MyClass {
  int i = 10;
  void func() { }
}
class MySubClass extends MyClass {
  int x = 0;
  void func() {
    this.x = 20;
    super.func();
  }
}

 MySubClass内のfunc()メソッドでthisとsuperを使用しています。thisは自分自身のオブジェクト参照ですので、

this.x = 20;

は、MySubClassのメンバ変数xに20を代入します。また、superはスーパークラスのオブジェクト参照ですので、

super.func();

は、MyClassのfunc()メソッド呼び出しになります。

 参照データ型変数の使用方法と同様に、thisやsuperの後に「.(ドット)」をつけて、自オブジェクトや親オブジェクトの変数やメソッドを利用することができます(下図)

thisとsuper

 また、thisやsuperを使ってコンストラクタを呼び出すこともできます。

例) thisを使ったコンストラクタ呼び出し
class MyClass {
  int i;
  MyClass() { }
  MyClass(int arg) {
    this();
    i = arg;
  }
}

 この例のthis();は、引数なしのコンストラクタMyClass()を呼び出しています。

例) superを使ったコンストラクタ呼び出し
class MyClass {
  MyClass() { }
}
class MySubClass extends MyClass {
  MySubClass() {
    super();
  }
}

  この例のsuper();は、MySubClassのスーパークラスであるMyClassのコンストラクタMyClass()を呼び出しています。

 thisやsuperをコンストラクタ呼び出しに使用することができますが、文法的な規則として、thisやsuperのコンストラクタ呼び出しは、そのコンストラクタの先頭に記述する必要があります。記述が先頭にない場合は、コンパイルエラーとなります。

 本設問のソースファイルには3つのクラスが定義されています。1行目からの「This_Super」クラスはスーパークラス、9行目からの「Sub_This_Super」クラスは「This_Super」のサブクラス、19行目からの「Create」クラスはmainメソッドをもち、実行時に「Sub_This_Super」クラスのオブジェクトをつくります。「This_Super」クラスと「Sub_This_Super」クラスは継承関係にあります。

 そして、それぞれのクラスにint型の変数iが別の初期値で宣言されています。superは継承関係にあるクラスのスーパークラスの要素をさします。よって「Sub_This_Super」クラスでsuperを指定した場合、「This_Super」クラスの要素をさします。また、thisは自クラスの要素をさしますので、「Sub_This_Super」クラスでthisを指定した場合、「Sub_This_Super」クラスの要素を指します。

 プログラムの実行経過を以下で説明します。

(1)Createクラスを実行するとmainメソッドが呼び出され、処理を開始します。処理はまずSub_This_Superクラスのオブジェクトを作成してprintメソッドを呼び出します。

(2)Sub_This_Superのprintメソッドでは、スーパークラスのprintメソッドを呼び出しています(13行目)。この場合、This_Superのprintメソッドが呼び出されます。

(3)
This_Superのprintメソッドでは変数iの値を表示します。この場合に表示される変数iは2行目で宣言されているiなので、値は「1」となります。

(4)
続いて再び変数iを表示しますが、14行目では「this.i」と自クラスの要素iを指定しているので値「2」が、15行目では「super.i」とスーパークラスの要素iを指定しているので値「1」が表示されます。

よって、プログラムの実行により表示されるのは「121」となります。

POINT

クラスのメンバ変数とそのクラスがもつメソッド内のローカル変数が同一変数名の場合(例えば本設問のSub_This_Superクラスの変数iです)、ローカル変数が優先されるので、メンバ変数側を操作したい場合は、明示的にthisを指定する必要があります。


KEYWORD
■スーパークラス
クラス定義でキーワード「extends」の後に指定されたクラスです。

■コンストラクタ
クラスがインスタンス化されるときに呼び出される特殊なメソッドです。

   ワンポイントQuestionの解答

正解 C

Java2ラーニングブック −310-035 編−

本記事は@ITハイブックスシリーズ「Java2ラーニングブック −310-035 編−」(技術評論社)から、一部の内容を編集し転載したものです。本書の詳細は「@ITハイブックス」サイトでご覧いただけます。


Javaプログラミング・ワンポイントレクチャー INDEX





Java Agile フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Java Agile 記事ランキング

本日 月間