オブジェクト指向プログラミング

抽象クラス ちゅうしょうくらす

オブジェクト指向継承抽象メソッドインターフェースポリモーフィズム具象クラス
抽象クラスについて教えて

簡単に言うとこんな感じ!

「乗り物」って概念は分かるけど、「乗り物そのもの」を作ることはできないよね?車・バス・自転車という具体的な形にして初めて使えるんだ。抽象クラスはまさにそれで、「共通のルールと骨組みだけ定めた設計書」のことだよ!


抽象クラスとは

抽象クラス(Abstract Class)とは、オブジェクト指向プログラミングにおいて、直接インスタンス(実体)を生成できない、設計のひな形となるクラスのことです。「このクラスを継承する子クラスは、こういうメソッドを必ず実装しなければならない」というルールを強制しながら、共通の処理はまとめて定義しておけるのが特徴です。

抽象クラスには 「抽象メソッド(Abstract Method)」 を含めることができます。抽象メソッドとは、メソッドの名前と引数の定義だけがあって、中身(処理の実装)が書かれていないメソッドのこと。子クラス側で必ず実装を書かなければいけない、いわば「空欄の問題用紙」のような存在です。一方で、実装済みのメソッドも同時に持てるため、インターフェースとは異なり「共通処理の共有」もできるのが大きな強みです。

ビジネス的な視点で言えば、抽象クラスは「仕様書の標準テンプレート」に近いイメージです。プロジェクトごとに必ず記載すべき項目(抽象メソッド)を強制しつつ、どのプロジェクトでも同じ共通文言(実装済みメソッド)は使い回せる。チーム開発での品質統一や保守性向上に直結する重要な概念です。


抽象クラスの構造と役割

抽象クラス・具象クラス・インターフェースの比較

特徴抽象クラス具象クラスインターフェース
インスタンス生成❌ できない✅ できる❌ できない
実装済みメソッド✅ 持てる✅ 持てる△ default実装のみ(言語による)
抽象メソッド✅ 持てる❌ 持てない✅ 持てる(全メソッドが対象)
フィールド(状態)✅ 持てる✅ 持てる❌ 基本持てない
継承できる数1つのみ(多重継承不可)1つのみ複数実装できる
主な用途共通処理の共有+ルール強制実際に使うオブジェクトルールのみ強制

抽象クラスの典型的な構造(Java風の例)

┌────────────────────────────────────┐
│  abstract class Animal             │  ← 抽象クラス(直接は使えない)
│                                    │
│  ✅ void breathe() { ... }         │  ← 実装済み(共通処理)
│  ❌ abstract void sound();         │  ← 抽象メソッド(中身なし)
│  ❌ abstract void move();          │  ← 抽象メソッド(中身なし)
└──────────────┬─────────────────────┘
               │ 継承(extends)
      ┌────────┴────────┐
      ▼                 ▼
┌──────────────┐  ┌──────────────┐
│  class Dog   │  │  class Bird  │  ← 具象クラス(実際に使える)
│              │  │              │
│ sound(){"ワン"}│  │ sound(){"チュン"}│  ← 必ず実装が必要
│ move(){走る} │  │ move(){飛ぶ} │  ← 必ず実装が必要
└──────────────┘  └──────────────┘

覚え方:「幽霊設計図」と覚える!

抽象クラスは「実体のない幽霊のような設計図」と覚えましょう。幽霊(抽象クラス)は直接触れないけど、確かにそこに存在して子孫(子クラス)に影響を与える。インスタンスを生成しようとすると「幽霊を捕まえようとしてもつかめない=コンパイルエラー」!というイメージです。

抽象クラスが活きる場面

【発注システムの例】

abstract class 注文処理 {
    // 共通処理(実装済み)
    void ログ記録()   { ... }
    void 在庫確認()   { ... }

    // チャネルごとに異なる処理(抽象)
    abstract void 決済処理();
    abstract void 通知送信();
}

class EC注文処理    extends 注文処理 { ... }  // クレカ決済・メール通知
class 店舗注文処理  extends 注文処理 { ... }  // 現金決済・レシート印刷
class 電話注文処理  extends 注文処理 { ... }  // 代引き決済・SMS通知

在庫確認やログ記録は全チャネル共通なので親クラスにまとめ、決済と通知はチャネルごとに異なるので抽象メソッドとして強制実装させる——これが抽象クラスの真骨頂です。


歴史と背景

  • 1960年代:Simula 67(世界初のオブジェクト指向言語)でクラスと継承の概念が登場。この時点でのクラス設計が後の抽象クラスの原型となる
  • 1970〜80年代:Smalltalk・C++が登場し、クラス階層の設計パターンが実務で洗練されていく。C++では純粋仮想関数= 0)として抽象クラスに相当する機能が実装される
  • 1990年代Javaが登場し、abstractキーワードとして抽象クラスが言語仕様に明示的に組み込まれる。同時にインターフェースも導入され、両者の使い分けが議論されるように
  • 2000年代以降:GoF(Gang of Four)のデザインパターン(Template MethodパターンやFactory Methodパターン)が普及し、抽象クラスを活用した設計手法がエンタープライズ開発の標準になる
  • 現在PythonKotlinSwiftC#など主要言語が抽象クラスをサポート。型安全性と再利用性を両立させる基盤として、現代のフレームワーク設計に欠かせない概念となっている

抽象クラスとインターフェースの使い分け

抽象クラスとよく混同される概念がインターフェースです。どちらも「実装を強制する設計図」ですが、目的と使い方が異なります。

抽象クラス vs インターフェース 抽象クラス Abstract Class ✅ 実装済みメソッドを持てる (共通処理をまとめられる) ✅ フィールド(状態)を持てる (データを保持できる) ⚠️ 継承は1つのみ (多重継承はできない) 向いている場面 「〜の一種」という is-a関係・共通処理がある時 インターフェース Interface ✅ 複数を同時に実装できる (多重実装が可能) ✅ ルールのみを定義する (実装は子クラス任せ) ⚠️ 共通処理は書けない (原則、実装は持たない) 向いている場面 「〜できる」という 能力・契約だけを定めたい時 vs

実務でどちらを選ぶべきか?

抽象クラスを選ぶとき:

  • 複数の子クラスで「共通の処理(コード)」を使い回したい
  • 「犬は動物の一種」のような is-a関係 がある
  • 子クラスに共通の状態(フィールド)を持たせたい

インターフェースを選ぶとき:

  • 「飛べる」「印刷できる」など能力・機能の契約だけを定めたい
  • 全く異なる種類のクラスに同じルールを課したい(多重実装が必要)
  • Javaなら8以降の default メソッドで部分的に実装も可能になった

Template Methodパターン:抽象クラスの代表的活用法

抽象クラスが最も活きるデザインパターンが Template Method(テンプレートメソッド)パターンです。処理の「骨格(順序)」を親クラスに定義し、各ステップの実装を子クラスに委ねる設計手法です。

abstract class レポート生成 {
    // テンプレートメソッド(処理の骨格を定義)
    final void 生成する() {
        ヘッダー出力();    // ← 共通処理(実装済み)
        本文出力();        // ← 抽象メソッド(子クラスが実装)
        フッター出力();    // ← 共通処理(実装済み)
    }
    abstract void 本文出力();
}

class 売上レポート extends レポート生成 {
    void 本文出力() { /* 売上グラフを出力 */ }
}

class 在庫レポート extends レポート生成 {
    void 本文出力() { /* 在庫一覧を出力 */ }
}

関連用語

  • ./046-class.md — クラス:オブジェクトの設計図。抽象クラスもクラスの一種
  • ./048-interface.md — インターフェース:実装を持たない純粋な契約・ルール定義
  • ./049-inheritance.md — 継承:親クラスの性質を子クラスが引き継ぐ仕組み
  • ./050-polymorphism.mdポリモーフィズム:同じ操作で異なる動作をする仕組み。抽象クラスが支える核心概念
  • ./051-concrete-class.md — 具象クラス:抽象クラスを継承してすべてのメソッドを実装した、実際に使えるクラス
  • ./052-design-pattern.md — デザインパターン:Template MethodなどGoFパターンで抽象クラスが活躍
  • ./053-encapsulation.mdカプセル化:内部実装を隠す概念。抽象クラスとともにOOPの基本原則
  • ./045-oop.md — オブジェクト指向プログラミング:抽象クラスが属するプログラミングパラダイムの全体像