共通部分を定義し単独では実体化できない基底クラス。
抽象クラスとは、複数のクラスに共通する部分を定義する一方で、中身が未完成な部分を含むため、それ単独では実体(インスタンス)を作れない基底クラスのことです。基底クラスとは、他のクラスのもとになる親クラスのことです。
抽象クラスには、中身を書かずに名前だけ宣言した抽象メソッド(=処理の中身を子クラスに任せる、未完成のメソッド)を持たせられます。未完成なので、その抽象クラスから直接オブジェクトを作ることはできません。
身近な例で考えると、「図形」という言葉に似ています。「図形」は円や長方形に共通する考え方ですが、「図形そのもの」を1つ描くことはできません。実際に描けるのは円や長方形といった具体的な図形だけです。上の図解で、親の Shape は実体化できず、子の Circle や Rectangle だけが実体化できる様子を確認してください。
抽象クラスとよく似たものにインタフェース(=クラスが満たすべき操作だけを定めた仕様)があります。どちらも単独では実体化できませんが、次の点が違います。
| 項目 | 抽象クラス | インタフェース |
|---|---|---|
| 実装済みメソッド | 持てる | 原則として持たない(仕様だけ) |
| 属性(データ) | 持てる | 原則として持たない |
| 主な役割 | 共通の中身を子に引き継ぐ | 満たすべき操作の約束を決める |
| 同時に持てる数 | 通常は1つだけ継承 | 複数を同時に実装できる |
ざっくり言うと、抽象クラスは「共通の中身を持った未完成の親」、インタフェースは「中身を持たず、操作の名前だけを約束する仕様書」です。共通の処理をまとめて引き継がせたいなら抽象クラス、ただ「この操作を備えていること」だけを約束させたいならインタフェースを使います。
身近な例で言えば、抽象クラスは「半完成の料理キット」(共通の下ごしらえ済み、仕上げだけ自分で行う)、インタフェースは「レシピの完成条件リスト」(作り方は自由だが満たすべき条件だけ決まっている)のような関係です。
抽象クラスは、複数の子クラスに共通する部分をまとめつつ、子ごとに違う部分を必ず実装させたいときに使います。主な用途は次の通りです。
・共通処理の集約:子クラスに共通する属性やメソッドを親に1か所だけ書き、重複を減らせます
・実装の強制:抽象メソッドを置くと「子クラスは必ずこの操作を実装すること」を強制でき、書き忘れを防げます
・共通の型として扱う:「図形なら何でも」というように、子をまとめて親の型として扱い、同じ手順で処理できます
身近な例で考えると、会社の「マニュアルの雛形」のようなものです。共通のあいさつや手順は雛形(親)に書いておき、各部署(子)が自分たちの担当部分だけを必ず埋める──こうすれば全体の統一感を保ちつつ、抜け漏れを防げます。