スーパークラスの変数を使う

広告

継承したクラスのオブジェクトを扱う場合、通常は下記のように利用します。

class test{
  public static void main(String args[]){
    subClass obj = new subClass();
  }
}

class superClass{
  public void dispName(){
    System.out.println("未定義です");
  }
}

class subClass extends superClass{
  public void dispName(){
    System.out.println("製品名はXXXです");
  }

  public void dispVersion(){
    System.out.println("バージョン1.0です");
  }
}

上記のようにオブジェクトを作成するクラスの変数を使うのですが、クラスを継承した場合、スーパークラスの変数に対してサブクラスのオブジェクトを割り当てることが出来ます。

スーパークラス 変数名 = new サブクラス();

具体的には下記のようになります。

class test{
  public static void main(String args[]){
    superClass obj = new subClass();

    obj.dispName();
  }
}

class superClass{
  public void dispName(){
    System.out.println("未定義です");
  }
}

class subClass extends superClass{
  public void dispName(){
    System.out.println("製品名はXXXです");
  }

  public void dispVersion(){
    System.out.println("バージョン1.0です");
  }
}

スーパークラスの変数にサブクラスのオブジェクトを格納した場合、このオブジェクトに対して実行できるメソッドはスーパークラスで定義されているものだけになります。もしサブクラスでオーバーライドされているのであれば、サブクラスの方のメソッドが呼び出されます。

例えば先ほどのサンプルで言えば、サブクラスで新たに追加された「dispVersion」メソッドはスーパークラスの変数に格納されたオブジェクトからは呼び出すことが出来ませんが、スーパークラスで定義されサブクラスでオーバーライドされている「dispName」メソッドは呼び出すことが出来ます。

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

ctest18.java

class ctest18{
  public static void main(String args[]){
    superClass obj = new subClass();

    obj.dispName();
  }
}

class superClass{
  public void dispName(){
    System.out.println("未定義です");
  }
}

class subClass extends superClass{
  public void dispName(){
    System.out.println("製品名はXXXです");
  }

  public void dispVersion(){
    System.out.println("バージョン1.0です");
  }
}

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

p8

上記のように、オーバーライドされたメソッドを呼び出す場合、サブクラスの方で定義されたメソッドが呼び出されます。

スーパークラス変数を使う理由

では何故このようなことをするかですが、同じスーパークラスから複数の種類のサブクラスを作成した場合、スーパークラスの変数を使えばどのサブクラスのオブジェクトでも同じように扱うことが出来るためです。

例えばサブクラスの変数名をそれぞれ使った場合、あるサブクラスの変数に別のサブクラスのオブジェクトを格納することは出来ませんので、それぞれ別々に扱わなければなりません。

class test{
  public static void main(String args[]){
    subClassA obj1 = new subClassA();
    subClassB obj2 = new subClassB();
    subClassC obj3 = new subClassC();

    obj1.dispName();
    obj2.dispName();
    obj3.dispName();
  }
}

class superClass{
  public void dispName(){
    System.out.println("未定義です");
  }
}

class subClassA extends superClass{
  public void dispName(){
    System.out.println("製品名はXXXです");
  }
}

class subClassB extends superClass{
  public void dispName(){
    System.out.println("製品名はYYYです");
  }
}

class subClassC extends superClass{
  public void dispName(){
    System.out.println("製品名はZZZです");
  }
}

これに対してスーパークラスの変数を使う場合には、スーパークラスの変数にはどのサブクラスのオブジェクトでも格納できますので、統一した形で扱うことが出来るようになります。

class test{
  public static void main(String args[]){
    superClass obj[] = new superClass[3];

    obj[0] = new subClassA();
    obj[1] = new subClassB();
    obj[2] = new subClassC();

    for (int i = 0 ; i < 3 ; i++){
      obj[i].dispName();
    }
  }
}

class superClass{
  public void dispName(){
    System.out.println("未定義です");
  }
}

class subClassA extends superClass{
  public void dispName(){
    System.out.println("製品名はXXXです");
  }
}

class subClassB extends superClass{
  public void dispName(){
    System.out.println("製品名はYYYです");
  }
}

class subClassC extends superClass{
  public void dispName(){
    System.out.println("製品名はZZZです");
  }
}

このように同じ型の変数に色々なサブクラスのオブジェクトを格納することで、サブクラスの違いを気にする事なくプログラムを記述できます。またスーパークラスの変数に格納したオブジェクトから利用できるのはスーパークラスで定義されたメソッド(及びサブクラスでオーバーライドされたメソッド)だけですので、どのサブクラスでも同じメソッド名を使うことができるわけです。このように扱うことができるのが継承をつかったプログラミングのメリットの1つです。

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

ctest19.java

class ctest19{
  public static void main(String args[]){
    superClass obj[] = new superClass[3];

    obj[0] = new subClassA();
    obj[1] = new subClassB();
    obj[2] = new subClassC();

    for (int i = 0 ; i < 3 ; i++){
      obj[i].dispName();
    }
  }
}

class superClass{
  public void dispName(){
    System.out.println("未定義です");
  }
}

class subClassA extends superClass{
  public void dispName(){
    System.out.println("製品名はXXXです");
  }
}

class subClassB extends superClass{
  public void dispName(){
    System.out.println("製品名はYYYです");
  }
}

class subClassC extends superClass{
  public void dispName(){
    System.out.println("製品名はZZZです");
  }
}

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

p9

( Written by Tatsuo Ikura )

関連記事 (一部広告含む)