Knowledge Log

【Java】不完全なクラスが設計を救う!「抽象クラス」の役割と使い方

denson
1

はじめに

前回までの記事で、継承を使って共通の機能をまとめ、オーバーライドで個性を出す方法を解説しました。

しかし、開発を進めていると、ある疑問にぶつかります。

「『人間』クラスは共通部分をまとめるのに便利だが、ゲームの中に『ただの人間』というキャラは登場しない。

戦士や魔法使いとしてしか存在しないはずなのに、new Human() と実体化できてしまうのは不自然ではないか」

このように、「共通の型としては必要だが、それ単体では実体化させたくない」という時に使うのが、今回紹介する「抽象クラス」です。

あえてクラスを「未完成」にすることで、設計をより強固にする方法を解説します。

この記事はこんな人におすすめ!
  • 継承は理解したが、親クラスをそのまま使わせたくないと感じている人
  • 「抽象メソッド」をなぜわざわざ書くのか、その理由を知りたい人
  • チーム開発でもバグが起きにくい、堅牢なコードを書きたい人
2

抽象クラスは「実体を持たないコンセプト」

抽象クラス(Abstract Class)とは、一言で言えば「インスタンス化(new)できない不完全なクラス」のことです。

通常のクラスが「製品の設計図」だとしたら、抽象クラスは「製品のコンセプト」のようなものだと考えてください。

  • 通常のクラス: 「車」(実際に製造して走らせることができる)
  • 抽象クラス: 「乗り物」(「乗り物」という名前の物体はこの世に存在せず、車や船、飛行機といった具体的な形になって初めて実体化する)

Javaでは、クラス名の前に abstract と記述することで、「このクラスは未完成なので、そのままでは使えない」と宣言します。

これは一見不便に思えますが、「中身が決まっていないもの」を無理やり作らせないための、非常に強力なブレーキとして機能します。

3

抽象メソッドで「ルール」を強制する

抽象クラスの真の価値は、中身のないメソッドである「抽象メソッド(Abstract Method)」にあります。

これは、メソッドの「名前」と「戻り値」だけを定義し、具体的な「処理内容({ }の中身)」をあえて書かないという手法です。

// 抽象クラス(未完成のクラス)
public abstract class Character {
    String name;

    // 普通のメソッド(共通の動き)
    public void run() {
        System.out.println(name + "は走った!");
    }

    // 抽象メソッド(名前だけで中身がない!)
    public abstract void attack();
}

この attack() メソッドには処理が書かれていません。

これは、継承先の子クラスに対して「キャラクターなら必ず攻撃手段を持っているはずだから、具体的な攻撃方法は子クラス側で必ず決めてください」という強力な「命令」になります。

共通の動作(走る)は親クラスで一度だけ書き、個別の動作(攻撃)は子クラスに強制させる。

この「不完全さ」が、設計の漏れを防ぐための重要なルールとなるのです。

4

継承先で「実体」を与える

抽象クラスを継承した子クラスには、避けては通れないルールがあります。

それは、親が投げっぱなしにした「抽象メソッド」を、必ずオーバーライドして中身を記述することです。

これを専門用語で「実装(じっそう)」と呼びます。

// 子クラス(戦士)
public class Warrior extends Character {
    @Override
    public void attack() {
        // 親が「攻撃してね」と言ったので、具体的に書く
        System.out.println("剣で力強く斬りつける!");
    }
}

もし子クラスで attack() メソッドを書き忘れたままプログラムを動かそうとすると、Javaは

「未完成な部分が残っているから、まだ実体にはなれないよ」

とコンパイルエラーを出して教えてくれます。

未完成だからこそ、ミスが防げる

「書き忘れたらエラーになる」というのは、一見厳しい制約に見えるかもしれません。

しかし、大規模な開発ではこの厳しさが味方になります。

例えば、新しく「魔法使い」や「武闘家」というクラスを追加した際、抽象メソッドのおかげで「攻撃方法を定義し忘れる」というミスを物理的に防ぐことができるのです。

「何があっても、これだけは絶対に書いておけ」という意思表示をコードで示せるのが、抽象クラスの最大のメリットといえます。

5

まとめ:「未完成」が強固なシステムを作る

今回は、あえてインスタンス化を禁止する 「抽象クラス(abstract)」 について解説しました。

最後に、大切なポイントを振り返ります。

  • 抽象クラスとは: new して実体を作ることができない、コンセプトとしてのクラス。
  • 抽象メソッドの役割: 名前だけ決めて中身を空にすることで、子クラスに「実装」を強制する。
  • 設計のメリット: 多人数での開発や機能追加の際、必要なメソッドの書き忘れ(実装漏れ)を物理的に防ぐことができる。

プログラミングの世界では、何でも自由に書けることよりも、「間違った使い方ができないように制限をかけること」の方が重要視される場面が多くあります。

抽象クラスを使いこなせるようになると、「とりあえず動くコード」ではなく、「誰が使っても壊れにくい、安全な設計図」を書けるようになります。

一歩ずつ、こうした「設計の視点」を養っていきましょう。

最後まで読んでいただき、ありがとうございました!

ABOUT ME
おげん
おげん
駆け出しエンジニア
文系未経験からエンジニアになるために挑戦を開始したアラサー。転職活動を終え、2026年4月からIT企業で勤務予定。自分が学習で苦労した経験を『誰かのための道しるべ』として発信中。
記事URLをコピーしました