Knowledge Log

【Java】「抽象クラス(abstract)」って何?継承とインターフェースのいいとこ取りをしよう!

denson
1

はじめに

みなさんどうも、おげんです。

前回、前々回と「継承」や「インターフェース」についてお話ししてきました。

「同じコードをまとめる継承」と「能力のルールを決めるインターフェース」。

この2つを使いこなせれば、もう立派なJava使いの仲間入りです。

でも、こんな「ワガママな悩み」が出てくることはありませんか?

「共通の便利なコード(名前の管理とか)は親で書きたい!でも、攻撃の方法(メソッド)だけは子クラスで自由に、かつ強制的に書かせたい……!」

継承とインターフェースの「いいとこ取り」をしたい。

そんなエンジニアの願いを叶えてくれるのが、今回紹介する「抽象クラス(abstract)」です。

今回は、一見地味だけど実は「最強の土台」になる抽象クラスについて、RPGの例えで攻略していきましょう!

この記事はこんな人におすすめ!
  • 「普通のクラス」と「抽象クラス」の違いがピンとこない人
  • インターフェースと抽象クラス、どっちを使えばいいか迷っている人
  • 先輩が作った「土台のコード」をスムーズに理解したい人
  • 「 abstract 」という単語を聞いて、難しそう…と腰が引けている人
2

抽象クラスは「未完成の設計図」

「抽象(abstract)」という言葉を聞くと難しく感じますが、プログラミングの世界では「あえて未完成にしておく」という意味で使われます。

「キャラクター」という生き物はいない?

RPGの世界を想像してみてください。「戦士」や「魔法使い」は実在しますが、「キャラクター」という名前の生き物そのものが歩いていることはありませんよね。

「キャラクター」はあくまで、戦士や魔法使いをまとめるための概念(共通の土台)です。

このように、「共通の項目(名前やHP)は持っているけれど、それ単体では存在しないもの」をJavaで表現するのが抽象クラスです。

抽象クラスの役割:あえて「実体化」させない

抽象クラスにすると、以下のようなルールが生まれます。

  • インスタンス化(new)ができない: new Character() と書くとエラーになります。「未完成なんだから、これだけで作っちゃダメだよ!」とJavaが止めてくれるんです。
  • 子クラスへの「宿題」: 「攻撃の方法(attack)は、子クラスで必ず具体的に書きなさい!」という強制力を持たせることができます。

「共通部分は親が世話し、具体的な個性は子に任せる」という、絶妙なバランスを保つための仕組みなんですね。

3

Javaでの書き方:abstract

抽象クラスを作るには、クラス名とメソッド名の前に abstract と付けるだけです。

① 抽象クラス(未完成の土台)を作る

共通で使いたい「名前(name)」と、子クラスで必ず中身を書いてほしい「攻撃(attack)」を定義してみましょう。

// abstract をつけると抽象クラスになる
abstract class Character {
    String name;

    // 普通のメソッド:共通の動きを書ける
    void introduce() {
        System.out.println("私は " + name + " です。");
    }

    // 抽象メソッド:中身( { } )は書かず、セミコロンで終わる
    abstract void attack(); 
}

② 子クラスで「宿題」を完成させる

抽象クラスを継承したクラスは、親が残した abstract メソッドの中身を必ず書かなければなりません。

public class Warrior extends Character {
    
    // 親の「宿題(attack)」を具体的に書く
    @Override
    void attack() {
        System.out.println(name + " の剣攻撃!");
    }
}
  • abstract メソッド: 「名前だけ決めて、中身は子クラスに丸投げする」という命令です。
  • 強制力: 子クラスで attack() を書き忘れると、コンパイルエラーになります。これにより、「攻撃方法が決まっていないキャラクター」が生まれるのを防いでくれます。

「共通の処理(自己紹介)」は親で一括管理しつつ、「個別の処理(攻撃)」は子に強制させる。これで、バグの少ない綺麗な設計ができるようになります。

4

インターフェースとの使い分け

「抽象クラス」と「インターフェース」。

どちらも「メソッドの中身を子クラスに任せる」という点は同じですが、実は明確な使い分けの基準があります。

一目でわかる比較表

どう選ぶのが正解?

迷ったときは、この基準で考えてみてください。

  1. 「〇〇は、△△の一種である(is-a関係)」なら抽象クラス
    • 例:戦士は「キャラクター」の一種。
    • 名前やHPなど、「共通のデータ」を持たせたい時に使いましょう。
  2. 「種類に関係なく、この能力を持たせたい」ならインターフェース
    • 例:魔法使いもドローンも「空を飛べる(Flyable)」。
    • 種類(親子関係)を超えて、「動きのルールだけ」を共通化したい時に使いましょう。

実務での黄金パターン

実は、これらは「セットで使う」ことが多いです。

「キャラクター」という大きな抽象クラスを作り、その中で必要なキャラにだけ「空を飛ぶ」というインターフェースを実装する。

このように組み合わせることで、無駄がなく、かつ柔軟なプログラムが出来上がります。

5

まとめ:オブジェクト指向のパズル、完成!

今回は、共通の土台を作りつつ、子クラスにルールを強制する「抽象クラス(abstract)」について学びました。

これまでに学んだ武器を整理してみましょう。

  • カプセル化: 大事なデータを「金庫」に入れて守る。
  • 継承: 親から子へ、「共通のコード」を引き継いで楽をする。
  • ポリモーフィズム: 相手が誰でも「同じ命令」で動かせるようにする。
  • インターフェース: 種類を問わず「共通のスキル(資格)」をセットする。
  • 抽象クラス: 「未完成の設計図」で、強力な土台を作る。

これらは別々に存在するのではなく、すべてが連携して一つの大きなプログラムを支えています。

最初は「どれを使えばいいの?」と迷うのが当たり前です。

でも、自分でコードを書いていくうちに、「あ、ここはインターフェースにした方が後で楽だな」とか「これは共通の抽象クラスにまとめられそう」という感覚が必ず芽生えてきます。

オブジェクト指向という強力な武器を手に入れたあなたなら、もうどんな複雑なプログラムも一歩ずつ形にしていけるはずです。

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

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