本文へスキップ
BecomeCoder

Javaオブジェクト指向コース · 第5章 抽象クラスとインタフェース ― 型で「約束」する · レッスン16

抽象クラス ― 共通の骨組みだけ決める

ブラウザで完結

導入

Animalsound() は、実際には DogCat が必ずオーバーライドするので、親クラスに書いた中身は一度も使われません。意味のない実装を書くくらいなら、「中身は書かないが、必ずオーバーライドしてね」と強制できたら便利です。

説明

抽象クラス(abstract class) は、それ自体は インスタンス化できない クラスです。中に 抽象メソッド(abstract method) ――中身({ })を持たないメソッドの宣言だけを書くことができ、サブクラスに実装を 強制 できます。

public class Main {
    public static void main(String[] args) {
        Animal d = new Dog();
        Animal c = new Cat();
        d.sound();
        c.sound();
    }
}

abstract class Animal {
    abstract void sound();
}

class Dog extends Animal {
    @Override
    void sound() {
        System.out.println("ワン");
    }
}

class Cat extends Animal {
    @Override
    void sound() {
        System.out.println("ニャー");
    }
}
  • abstract class Animal { ... } … クラス宣言に abstract をつけます。new Animal() はできません(抽象クラスは「設計図の下書き」であり、そのままでは実体化できないためです)。
  • abstract void sound(); … 中身のないメソッド宣言。Animal継承するクラスは、必ず sound() をオーバーライドしなければなりません。書き忘れるとコンパイルエラーになります。

「意味のないダミー実装」を書く必要がなくなり、かつ「サブクラスは必ず実装すること」を型のレベルで強制できるのが抽象クラスの利点です。

やってみよう

下のエディタを実行して、DogCat がそれぞれ sound() を実装していることを確認しましょう。Animalsound() に中身を書こうとするとどうなるか(abstract メソッドには中身を書けない)も考えてみてください。

演習

Bird extends Animal を作り、sound()"チュンチュン" と実装してください。mainAnimal b = new Bird(); として sound() を呼んでください。

ヒント1を見る

class Bird extends Animal { @Override void sound() { System.out.println("チュンチュン"); } }

ヒント2を見る

mainAnimal b = new Bird(); b.sound();

実際に動かしてみよう

下のエディタにJavaを書いて「実行」を押すと、学習用シミュレータが System.out.println の出力を表示します(本物のJVMではなく、教材の範囲を再現した軽量エンジンです)。クラス・継承・コレクションなども動きます。Scanner で入力を読む例は「標準入力」欄に値を入れてください。本文の例を書き換えて動かしてみましょう(Stream・ラムダ・スレッド・ファイル入出力など一部の機能は対象外です)。

Java — ブラウザ内で実行(学習用シミュレータ)

Javaの教材サブセットを動かす学習用シミュレータを読み込みます(本物のJVMではなく、動きを再現した軽量な自作エンジンです)。
スクロールして表示された時点でも自動で読み込まれます。