導入
継承はとても便利ですが、使いどころを間違えると混乱のもとになります。最後に、継承を使うべき場面の見極め方と、次の章で本格的に学ぶ「オーバーライド」の入り口を見ておきましょう。
説明
継承を使うべきかどうかの目安は、「AはBの一種か?(is-a の関係)」 が成り立つかどうかです。「犬は動物の一種」「学生は人間の一種」は成り立つので継承が向いています。一方、「車はエンジンを持っている」は “has-a”(持っている)の関係であり、“is-a”(〜の一種)ではないので、継承ではなく別の仕組み(フィールドとして持たせる)で表すべきです。
もう1つ、継承には大事な機能があります。親クラスと 同じ名前・同じ引数のメソッド を子クラスで定義すると、親の処理を「上書き」できます。これを オーバーライド と呼びます。
public class Main {
public static void main(String[] args) {
Animal a = new Animal();
a.sound();
Dog d = new Dog();
d.sound();
}
}
class Animal {
void sound() {
System.out.println("鳴く");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("ワン!");
}
}
Dog は Animal の sound() と同じ名前のメソッドを定義することで、内容を「ワン!」に上書きしています。@Override は「これは親のメソッドを上書きするものです」という目印(アノテーション)です。オーバーライドについては、次の第4章で詳しく学びます。
やってみよう
下のエディタを実行し、Animal と Dog で sound() の中身が違うことを確認しましょう。@Override を消しても動くこと(ただしコンパイラのチェックが効かなくなる)も確認してみてください。
演習
Cat extends Animal を作り、sound() を "ニャー!" と表示するようにオーバーライドしてください。main で new Cat() を作って sound() を呼んでください。
ヒント1を見る
class Cat extends Animal { @Override void sound() { System.out.println("ニャー!"); } }。
ヒント2を見る
main で Cat c = new Cat(); c.sound();。