メソッドのオーバーライド

広告

クラスを継承した時に元になっているスーパークラスで定義されているメソッドを継承したサブクラスにて同じメソッド名(と同じ引数)で書き換えることができます。つまり上書きするということです。これをメソッドのオーバーライドと言います。

具体的な例で考えてみます。スーパークラスとしてクラスAを用意し、クラスAを継承したクラスB1、クラスB2があったとします。スーパークラスであるクラスAには「disp」というメソッドが定義されています。ここでクラスB1で「disp」というメソッドをオーバーライドしてみます。

class A{
  public void disp(){
    System.out.println("電化製品です");
  }
}

class B1 extends A{
  public void disp(){
    System.out.println("エアコンです");
  }
}

class B2 extends A{
}

クラスB2のオブジェクトを作成し、「disp」メソッドを呼んだ場合、クラスB2自身には「disp」メソッドが定義されていませんのでスーパークラスであるクラスAで定義されている「disp」メソッドが呼ばれ"電化製品です"と表示されます。これに対してクラスB1のオブジェクトを作成し「disp」メソッドを呼んだ場合には、クラスB1自体に「disp」メソッドが定義されているのでクラスB1の「disp」メソッドが呼ばれ"エアコンです"と表示されます。

なぜこのようなことをするのかと言えば、スーパークラスで「disp」メソッドを定義することで、スーパークラスを継承した全てのサブクラスでは共通したメソッド名である「disp」メソッドが使えることになります。ただサブクラスによってはそのメソッドの定義を独自の内容に書き換えたい場合があります。このような場合に同じメソッド名と引数を使って再定義することで、メソッド名は共通ですが中身は定義しているクラスの合わせた内容に変更する事が出来るわけです。

サブクラス全部に共通のメソッド名を持たせながら、中身は自由に書き換えることが出来るというわけです。

では実際に試してみましょう。

ctest16.java

class ctest16{
  public static void main(String args[]){
    B1 b1 = new B1();
    b1.disp();

    B2 b2 = new B2();
    b2.disp();
  }
}

class A{
  public void disp(){
    System.out.println("電化製品です");
  }
}

class B1 extends A{
  public void disp(){
    System.out.println("エアコンです");
  }
}

class B2 extends A{
}

実際に実行してみると下記のようになります。

p6

スーパークラスのメソッドを呼び出す

オーバーライドしている場合でも、明示的にスーパークラスの方で定義されたメソッドの方を呼び出すことが可能です。その場合には「super」を使って下記のように呼び出します。

class A{
  public void disp(){
    System.out.println("電化製品です");
  }
}

class B extends A{
  public void disp(){
    System.out.println("エアコンです");
    super.disp();
  }
}

「super」を付けて呼び出した場合には、自身で定義したメソッドではなくスーパークラスで定義されたメソッドを呼び出します。

簡単なサンプルで試して見ましょう。

ctest17.java

class ctest17{
  public static void main(String args[]){
    C c = new C();
    c.disp();
  }
}

class A{
  public void disp(){
    System.out.println("電化製品です");
  }
}

class B extends A{
  public void disp(){
    System.out.println("エアコンです");
    super.disp();
  }
}

class C extends B{
  public void disp(){
    System.out.println("三菱製です");
    super.disp();
  }
}

実際に実行してみると下記のようになります。

p7

今回はクラスAをクラスBが継承し、クラスBをクラスCが継承しています。クラスCの「disp」メソッドを呼び出した場合、まずクラスCで定義されている「disp」メソッドが呼ばれます。次に「super.disp()」によってクラスCのスーパークラスであるクラスBで定義された「disp」メソッドが呼ばれています。つまり「super」を付けてメソッドを呼び出した場合は、一番大元のクラスのメソッドではなく、一つ上のクラスのメソッド(つまり継承している1つ上のスーパークラスのメソッド)が呼び出されます。

今回の場合は、クラスCのスーパークラスであるクラスBの「disp」メソッド内で、クラスBのスーパークラスであるクラスAの「disp」メソッドを呼び出すように記述しましたので、結果的に「クラスCのdispメソッド」、「クラスBのdispメソッド」、「クラスAのdispメソッド」が順に呼ばれることになります。

( Written by Tatsuo Ikura )

プロフィール画像

著者 / TATSUO IKURA

これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。