カテゴリ: JavaSilver試験対策 更新日: 2026/03/26

Javaの抽象クラスとメソッド呼び出しの仕組みを徹底解説

048
Javaの抽象クラスとメソッド呼び出しの仕組み

先生と生徒の会話形式で理解しよう

生徒

「抽象クラスで定義されたメソッドから、サブクラスのメソッドが呼び出されることってあるんですか?」

先生

「はい、抽象クラス内のメソッドで抽象メソッドを呼び出すと、サブクラスでオーバーライドされたメソッドが実行されます。コードを見ながら詳しく説明しますね!」

1. 抽象クラスとメソッド呼び出しの仕組み

1. 抽象クラスとメソッド呼び出しの仕組み
1. 抽象クラスとメソッド呼び出しの仕組み

抽象クラスは、オブジェクト指向プログラミングの重要な要素であり、継承を通じてコードの再利用性を向上させるために使われます。抽象クラスには、抽象メソッド(実装のないメソッド)と具象メソッド(実装を持つメソッド)の両方を定義できます。

抽象クラスのメソッド内で抽象メソッドを呼び出す場合、実際に実行されるのはサブクラスでオーバーライドされたメソッドです。以下のコードを例に考えてみましょう:


abstract class AbstractExample {
    public void execute() {
        System.out.println("Start");
        run(); // 抽象メソッドを呼び出す
        System.out.println("End");
    }

    protected abstract void run(); // 抽象メソッド
}

class SubExample extends AbstractExample {
    @Override
    protected void run() {
        System.out.println("Running...");
    }
}

public class Main {
    public static void main(String[] args) {
        AbstractExample example = new SubExample();
        example.execute();
    }
}

実行結果は次のようになります:


Start
Running...
End

このコードでは、executeメソッド内で呼び出されるrunメソッドが、サブクラスSubExampleの実装に置き換わっています。

2. サブクラスの抽象メソッド実装

2. サブクラスの抽象メソッド実装
2. サブクラスの抽象メソッド実装

サブクラスは、抽象クラスに定義された抽象メソッドをすべて実装する必要があります。実装しない場合、サブクラスも抽象クラスとして定義される必要があります。以下の例を見てみましょう:


abstract class AbstractVehicle {
    public abstract void start();

    public void stop() {
        System.out.println("Vehicle stopped.");
    }
}

class Car extends AbstractVehicle {
    @Override
    public void start() {
        System.out.println("Car started.");
    }
}

public class Main {
    public static void main(String[] args) {
        AbstractVehicle vehicle = new Car();
        vehicle.start(); // 出力: Car started.
        vehicle.stop();  // 出力: Vehicle stopped.
    }
}

このコードでは、Carクラスが抽象メソッドstartを実装しています。そのため、抽象クラスAbstractVehicleを継承したクラスとして正常に動作します。

3. 実行時のメソッド解決

3. 実行時のメソッド解決
3. 実行時のメソッド解決

実行時のメソッド解決は、オブジェクトの実際の型に基づいて行われます。抽象クラス型の変数にサブクラスのインスタンスを代入しても、サブクラスでオーバーライドされたメソッドが実行されます。

実行時の動作を確認するには、次のコードを参考にしてください:


abstract class Animal {
    public abstract void speak();
}

class Dog extends Animal {
    @Override
    public void speak() {
        System.out.println("Woof");
    }
}

class Cat extends Animal {
    @Override
    public void speak() {
        System.out.println("Meow");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myAnimal = new Dog();
        myAnimal.speak(); // 出力: Woof

        myAnimal = new Cat();
        myAnimal.speak(); // 出力: Meow
    }
}

Javaをこれから始める人や、 オブジェクト指向の考え方を基礎から理解したい人には、 定番の入門書がこちらです。

スッキリわかるJava入門 第4版をAmazonで見る

※ Amazon広告リンク

4. 試験対策ポイント

4. 試験対策ポイント
4. 試験対策ポイント
  • 抽象クラス内のメソッドから抽象メソッドを呼び出す場合、サブクラスでオーバーライドされたメソッドが実行される。
  • 抽象クラスはインスタンス化できないが、型として使用可能。
  • サブクラスは抽象メソッドをすべて実装する必要がある。

5. 抽象クラスから呼び出されるメソッドの流れ

5. 抽象クラスから呼び出されるメソッドの流れ
5. 抽象クラスから呼び出されるメソッドの流れ

抽象クラスのメソッドから抽象メソッドを呼び出す処理は、オブジェクト指向における「動的バインディング」によって実現されています。 これは、実行時に実際のオブジェクトの型に応じてメソッドが決定される仕組みです。

つまり、抽象クラスのコード内であっても、呼び出されるメソッドは実際のサブクラスの実装になります。 次の例で流れを確認してみましょう。


abstract class Processor {

    public void process() {
        System.out.println("Process start");
        execute();
        System.out.println("Process end");
    }

    abstract void execute();
}

class FileProcessor extends Processor {

    @Override
    void execute() {
        System.out.println("File processing...");
    }
}

このように、processメソッドの中で呼び出されるexecuteは、 サブクラスFileProcessorの実装が実行されます。

6. 抽象クラス型の変数を使うメリット

6. 抽象クラス型の変数を使うメリット
6. 抽象クラス型の変数を使うメリット

抽象クラス型の変数を使用することで、複数のサブクラスを共通の型として扱うことができます。 これはポリモーフィズム(多態性)と呼ばれる重要な概念です。

次のコードを見てみましょう:


abstract class Shape {
    abstract void draw();
}

class Circle extends Shape {
    void draw() {
        System.out.println("Draw Circle");
    }
}

class Square extends Shape {
    void draw() {
        System.out.println("Draw Square");
    }
}

public class Main {
    public static void main(String[] args) {

        Shape shape = new Circle();
        shape.draw();

        shape = new Square();
        shape.draw();
    }
}

このように抽象クラス型を使うことで、異なるクラスのオブジェクトを同じ方法で扱えるようになります。 プログラムの柔軟性を高める重要なテクニックです。

7. 抽象メソッド呼び出し時の注意点

7. 抽象メソッド呼び出し時の注意点
7. 抽象メソッド呼び出し時の注意点

抽象クラスで抽象メソッドを呼び出す設計には注意点もあります。 特にコンストラクタ内で抽象メソッドを呼び出す場合には慎重に設計する必要があります。

次のコードを見てみましょう:


abstract class Base {

    Base() {
        initialize();
    }

    abstract void initialize();
}

class Child extends Base {

    int value = 10;

    void initialize() {
        System.out.println(value);
    }
}

このような設計では、サブクラスのフィールドがまだ初期化されていない状態で 抽象メソッドが呼び出される可能性があります。 そのため、コンストラクタ内で抽象メソッドを呼び出す設計は慎重に行う必要があります。

まとめ

まとめ
まとめ

本記事では、Javaの抽象クラスとそのメソッド呼び出しの仕組みについて解説しました。抽象クラスは、継承を通じて共通の動作を提供しつつ、特定の処理はサブクラスに委ねる柔軟な設計が可能です。また、抽象クラス内で抽象メソッドを呼び出すと、サブクラスでオーバーライドされた実装が実行されるという重要なポイントも理解しました。

さらに、抽象メソッドを実装しない場合は、サブクラスも抽象クラスとして定義する必要があることや、実行時のメソッド解決がオブジェクトの実際の型に基づいて行われる仕組みも確認しました。これらの知識は、オブジェクト指向プログラミングを深く理解し、効率的なコード設計を行う上で非常に役立ちます。

以下に抽象クラスの応用例を示します:


abstract class Appliance {
    public abstract void turnOn();

    public void turnOff() {
        System.out.println("Turning off appliance.");
    }
}

class WashingMachine extends Appliance {
    @Override
    public void turnOn() {
        System.out.println("Washing Machine is now ON.");
    }
}

class Refrigerator extends Appliance {
    @Override
    public void turnOn() {
        System.out.println("Refrigerator is now ON.");
    }
}

public class Main {
    public static void main(String[] args) {
        Appliance wm = new WashingMachine();
        wm.turnOn(); // 出力: Washing Machine is now ON.
        wm.turnOff(); // 出力: Turning off appliance.

        Appliance rf = new Refrigerator();
        rf.turnOn(); // 出力: Refrigerator is now ON.
        rf.turnOff(); // 出力: Turning off appliance.
    }
}

この例では、抽象クラスApplianceWashingMachineRefrigeratorという具体的なクラスに共通の動作を提供しつつ、個別の動作はサブクラスで実装しています。

先生と生徒の振り返り会話

生徒

「抽象クラスの使い方が少しわかった気がします!でも、インタフェースとはどう使い分ければいいんですか?」

先生

「良い質問ですね!抽象クラスは共通の動作を提供したいとき、インタフェースは『型』を共有したいときに使うと考えるといいですよ。用途によって適切なものを選びましょう。」

生徒

「サブクラスで抽象メソッドを必ず実装しなきゃいけないというルールも便利ですね。責任が明確になります!」

先生

「その通りです!抽象クラスとインタフェースを理解して、より良い設計を目指しましょう。」

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

Javaの抽象クラス(abstract class)とは具体的にどのような役割を持つクラスなのですか?

Javaの抽象クラスとは、オブジェクト指向プログラミングにおいて「共通の性質や動作」をまとめるための雛形となるクラスです。キーワードとして abstract を用いて定義されます。抽象クラス自体は実体を持たないため、直接インスタンス化してオブジェクトを生成することはできませんが、他のクラスに継承(extends)されることで、コードの再利用性を高め、プログラム全体の設計を柔軟にする役割を担っています。共通の処理は抽象クラスの具象メソッドとして記述し、具体的な振る舞いが異なる部分は抽象メソッドとして定義することで、サブクラスごとに独自の実装を強制することができます。
JavaSilver試験対策の一覧へ
新着記事
AWS
【AWS】CLIでクエリ(--query)の使い方を徹底解説【JQとの違いも】
【AWS CLI】--queryオプションの使い方を徹底解説!JMESPathとJQとの違いも初心者向けにわかりやすく解説
Java
Java の継承のメリットとは?コードの再利用をしやすくする
Java の継承のメリットとは?コードの再利用をしやすくする方法を初心者向けに解説
Java
Java の継承を使うべき場面と使わないほうがよい場面
Java の継承を使うべき場面と使わないほうがよい場面を初心者向けに解説!
Java
Java の toString() メソッドをオーバーライドしてオブジェクトの情報を表示
Java の toString() メソッドをオーバーライドしてオブジェクトの情報を表示
人気記事
AWS
【AWS】s3 cpコマンド完全ガイド!基本・recursive・exclude/includeも解説
【AWS】s3 cpコマンド完全ガイド!基本・recursive・exclude/includeも解説
AWS
【AWS】VPCエンドポイントとは?種類・使い方・S3連携まで完全解説
【AWS】VPCエンドポイントとは?種類・使い方・S3連携まで完全解説
AWS
インスタンスタイプの料金比較と最適な選び方(最新2026年版)
AWSインスタンスタイプの料金比較と最適な選び方!初心者でもわかる2025年最新ガイド
AWS
【AWS】RDSの料金体系まとめ!ざっくり理解・高いと感じる理由も解説
【AWS】RDSの料金体系まとめ!ざっくり理解・高いと感じる理由も解説

🔌 USBポート不足を解消

Type-C 1本で拡張。
開発・作業環境を一気に快適に

UGREEN USB-Cハブを見る

※ Amazon広告リンク