導入
前回はそれぞれの型(Dog型、Cat型)の変数から sound() を呼びました。では、親の型(Animal型)の変数 に子のインスタンスを入れて呼んだら、どちらの sound() が実行されるでしょうか?
説明
答えは「実際に代入されているインスタンスの型」の sound() が呼ばれます。これを 動的束縛(実行時ポリモーフィズム) と呼びます。
public class Main {
public static void main(String[] args) {
Animal a1 = new Dog();
Animal a2 = new Cat();
a1.sound();
a2.sound();
}
}
class Animal {
void sound() {
System.out.println("なんらかの音");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("ワン");
}
}
class Cat extends Animal {
@Override
void sound() {
System.out.println("ニャー");
}
}
a1 の 型(見た目)は Animal ですが、実際に入っているのは Dog の インスタンス(実体) です。a1.sound() を呼ぶと、変数の型ではなく 実体の型(Dog)に応じたメソッド が実行され、「ワン」と表示されます。「呼ばれるメソッドは、コンパイル時(型を見た時点)ではなく、実行時(実際のインスタンスを見た時点)で決まる」——これが動的束縛です。
やってみよう
下のエディタで Animal a1 = new Cat(); のように組み合わせを変えて実行し、いつも「実体の型」の sound() が呼ばれることを確認しましょう。
演習
Bird extends Animal を作り、sound() を "チュンチュン" にオーバーライドしてください。main で Animal a = new Bird(); として Animal 型の変数に Bird のインスタンスを代入し、a.sound() を呼んでください。
ヒント1を見る
Bird クラスの作り方はレッスン11と同じです。
ヒント2を見る
main で Animal a = new Bird(); a.sound();。変数の型は Animal ですが、実体は Bird です。