アップキャスト - 継承 - 萌えJava超入門
クラスの継承

アップキャスト

継承関係にあるクラスはキャストできます。
上位のクラスへのキャストをアップキャストといいます。

Animal animal = dog;
class Dog extends Animal

目次

1. アップキャスト

継承関係にあるクラスはキャスト(型変換)が可能です。
上位のクラス(スーパークラス側)に変換することをアップキャスト

重要
アップキャストは、
インスタンスをスーパークラス型の変数に代入することで、暗黙的に行えます。

アップキャスト 書式
  Dog dog = new Dog();
  Animal animal = dog;
class Dog extends Animal



2. アップキャストの例


以下のサンプルでは、Animal_01クラスをスーパークラスにして、
Dog_61、Cat_61、というサブクラスを作りました。
Dog_61、Cat_61、のインスタンスを、Animal_01型の配列に代入しています。
これがアップキャストです。

Animal_01.java(再出)
  //Animal_01.java

  public class Animal_01{

        protected static String = "生き物です。";
        protected String name;

        public Animal_01(){
            this.name = "no_name";
        }
        public Animal_01(String name){
            this.name = name;
        }
        public static void printGroup(){
            System.out.println(group);
        }
        public void printName(){
            System.out.println(name + "だぞ! ガオー!");
        }
  }

//Dog_61.java
public class Dog_61 extends Animal_01{
    public Dog_61(String name){
        super(name);
    }
    //以下オーバーライドしたメソッド
    @Override
    public void printName(){
        System.out.println(name + "だワン!");
    }

    //追加したメソッド
    public void printBow(){
        System.out.println(name + "は棒には当たらないワン!");
    }
}

//Cat_61.java
public class Cat_61 extends Animal_01{
    public Cat_61(String name){
        super(name);
    }
    //オーバーライドしたメソッド
    @Override
    public void printName(){
        System.out.println(name + "なのにゃ!");
    }

    //追加したメソッド
    public void printKoban(){
        System.out.println(name + "は小判が欲しいのにゃ!");
    }
}

//Driver_61.java

public class Driver_61{

  public static void main(String[] args){
      Animal_01[] animalArray = new Animal_01[9];
      animalArray[0] = new Animal_01("ゴン太くん");
      animalArray[1] = new Animal_01("ふなっしー");
      animalArray[2] = new Animal_01("アニマル浜口");
      animalArray[3] = new Dog_61("ヨーゼフ");		//アップキャスト
      animalArray[4] = new Dog_61("パトラッシュ"); //アップキャスト
      animalArray[5] = new Dog_61("白いお父さん"); //アップキャスト
      animalArray[6] = new Cat_61("ニャース"); 		//アップキャスト
      animalArray[7] = new Cat_61("ドラえもん"); 	//アップキャスト
      animalArray[8] = new Cat_61("ニャンパス"); 	//アップキャスト

      //すべての要素で printNameメソッドを実行
      for(int i=0; i<animalArray.length; i++){
          animalArray[i].printName();
      }
  }
}

萌えJava超入門 萌えJava超入門
Dog や Cat のインスタンスを
Animalクラス型の配列に
代入したんすね?
萌えJava超入門
そう。
とてもよく使う書き方だ。
コマンドライン
>cd ws
ws>javac -encoding UTF-8 Driver_61.java
ws>java Driver_61
ゴン太くんだぞ! ガオー!
ふなっしーだぞ! ガオー!
アニマル浜口だぞ! ガオー!
ヨーゼフだワン!
パトラッシュだワン!
白いお父さんだワン!
ニャースなのにゃ!
ドラえもんなのにゃ!
ニャンパスなのにゃ!


重要
アップキャストしても、オーバーライドが効いています。

サブクラスのインスタンスを、Animal_01型の変数に代入していますが、
オーバーライドが効いている点に注意してください。
インスタンス自体はサブクラスのものです。

萌えJava超入門
スーパークラスのメソッドを
まとめて実行したいときの
定番の書き方だ。


3. キャスト先のクラスに無いメソッドは実行できない


重要
キャスト先のクラスに無いメソッドは実行できません。

例えば、Cat_61クラスのインスタンスを、Animal_01クラスにアップキャストした場合、
Cat_61 のメソッド printKoban を実行しようとしても、
printKoban は、Animal_01クラスには無いので実行できません

萌えJava超入門 萌えJava超入門 萌えJava超入門
ここポイント。
//Driver_61NG.java

public class Driver_61NG{

    public static void main(String[] args){
        Animal_01 animal = new Cat_61("ニャース");
        animal.printKoban();//Animal_01クラスにはないメソッド
    }
}

コマンドライン
>cd ws
ws>javac -encoding UTF-8 Driver_61NG.java
Driver_61NG.java:7: エラー: シンボルを見つけられません
      animal.printKoban();//Animal_01クラスにはないメソッドを実行
            ^
  シンボル:   メソッド printKoban()
  場所: タイプAnimal_01の変数 animal
エラー1個


萌えJava超入門
サブクラスを作ったのに
独自のメソッドが使えないとは


4. サンプル


スーパークラスと共通しているメソッドを一度に実行する場合、
スーパークラス型の配列に代入(アップキャスト)して
for文などで実行すると、きれいに書けますよね(Driver_61)。

でも、「サブクラスで追加したメソッド」は、アップキャストすると使えません。
実行するには、サブクラス型の変数に代入しておく必要があります。
萌えJava超入門
こんな感じにすると
上手くいく。

以下の例では、
スーパークラス型の配列 と サブクラス型の配列 を用意して、
サブクラスのインスタンスは、
スーパークラス型の配列 と サブクラス型の配列 の両方に代入しています。

(インスタンス自体は一つです。)

//Driver_63.java

public class Driver_63{

  public static void main(String[] args){
      Dog_61[] dogArray = new Dog_61[3];
      dogArray[0] = new Dog_61("ヨーゼフ");
      dogArray[1] = new Dog_61("パトラッシュ");
      dogArray[2] = new Dog_61("白いお父さん");

      Cat_61[] catArray = new Cat_61[3];
      catArray[0] = new Cat_61("ニャース");
      catArray[1] = new Cat_61("ドラえもん");
      catArray[2] = new Cat_61("ニャンパス");


      Animal_01[] animalArray = new Animal_01[9];
      animalArray[0] = new Animal_01("ゴン太くん");
      animalArray[1] = new Animal_01("ふなっしー");
      animalArray[2] = new Animal_01("アニマル浜口");
      animalArray[3] = dogArray[0]; //アップキャスト
      animalArray[4] = dogArray[1]; //アップキャスト
      animalArray[5] = dogArray[2]; //アップキャスト
      animalArray[6] = catArray[0]; //アップキャスト
      animalArray[7] = catArray[1]; //アップキャスト
      animalArray[8] = catArray[2]; //アップキャスト

      System.out.println("-- animal --");
      for(int i=0; i<animalArray.length; i++){
          animalArray[i].printName();//スーパークラスのメソッド
      }
      System.out.println("-- dog --");
      for(int i=0; i<dogArray.length; i++){
          dogArray[i].printBow(); //Dogクラス独自のメソッド

      }
      System.out.println("-- cat --");
      for(int i=0; i<catArray.length; i++){
          catArray[i].printKoban(); //Catクラス独自のメソッド
      }
  }
}

コマンドライン
>cd ws
ws>javac -encoding UTF-8 Driver_63.java
ws>java Driver_63
-- animal --
ゴン太くんだぞ! ガオー!           printName
ふなっしーだぞ! ガオー!           printName
アニマル浜口だぞ! ガオー!         printName
ヨーゼフだワン!                    printName
パトラッシュだワン!                printName
白いお父さんだワン!                printName
ニャースなのにゃ!                  printName
ドラえもんなのにゃ!                printName
ニャンパスなのにゃ!                printName
-- dog --
ヨーゼフは棒には当たらないワン!    printBow
パトラッシュは棒には当たらないワン!printBow
白いお父さんは棒には当たらないワン!printBow
-- cat --
ニャースは小判が欲しいのにゃ!      printKoban
ドラえもんは小判が欲しいのにゃ!    printKoban
ニャンパスは小判が欲しいのにゃ!    printKoban


後述の「インターフェイス」を使う方法もご検討ください。
きれいに書けると思います。




お疲れ様でした。




© 2019 awasekagami