クラスの継承
アップキャスト
継承関係にあるクラスはキャストできます。
上位のクラスへのキャストをアップキャストといいます。
Animal animal = dog;
目次
1. アップキャスト
継承関係にあるクラスはキャスト(型変換)が可能です。
上位のクラス(スーパークラス側)に変換することをアップキャスト、
重要
アップキャストは、
インスタンスをスーパークラス型の変数に代入することで、暗黙的に行えます。
2. アップキャストの例
以下のサンプルでは、Animal_01クラスをスーパークラスにして、
Dog_61、Cat_61、というサブクラスを作りました。
Dog_61、Cat_61、のインスタンスを、Animal_01型の配列に代入しています。
これがアップキャストです。
//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();
}
}
}
Dog や Cat のインスタンスを
Animalクラス型の配列に
代入したんすね?
そう。
とてもよく使う書き方だ。
コマンドライン
>cd ws
ws>javac -encoding UTF-8 Driver_61.java
ws>java Driver_61
ゴン太くんだぞ! ガオー!
ふなっしーだぞ! ガオー!
アニマル浜口だぞ! ガオー!
ヨーゼフだワン!
パトラッシュだワン!
白いお父さんだワン!
ニャースなのにゃ!
ドラえもんなのにゃ!
ニャンパスなのにゃ!
重要
アップキャストしても、オーバーライドが効いています。
サブクラスのインスタンスを、Animal_01型の変数に代入していますが、
オーバーライドが効いている点に注意してください。
インスタンス自体はサブクラスのものです。
スーパークラスのメソッドを
まとめて実行したいときの
定番の書き方だ。
3. キャスト先のクラスに無いメソッドは実行できない
重要
キャスト先のクラスに無いメソッドは実行できません。
例えば、Cat_61クラスのインスタンスを、Animal_01クラスにアップキャストした場合、
Cat_61 のメソッド printKoban を実行しようとしても、
printKoban は、Animal_01クラスには無いので実行できません。
ここポイント。
//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個
サブクラスを作ったのに
独自のメソッドが使えないとは
4. サンプル
スーパークラスと共通しているメソッドを一度に実行する場合、
スーパークラス型の配列に代入(アップキャスト)して
for文などで実行すると、きれいに書けますよね(Driver_61)。
でも、「サブクラスで追加したメソッド」は、アップキャストすると使えません。
実行するには、サブクラス型の変数に代入しておく必要があります。
こんな感じにすると
上手くいく。
以下の例では、
スーパークラス型の配列 と サブクラス型の配列 を用意して、
サブクラスのインスタンスは、
スーパークラス型の配列 と サブクラス型の配列 の両方に代入しています。
(インスタンス自体は一つです。)
//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
後述の「インターフェイス」を使う方法もご検討ください。
きれいに書けると思います。
お疲れ様でした。