【保存版】Javaの「継承」と「コンポジション」の違いと使い分けをやさしく解説!

Java

はじめに

Javaの学習を進めていくと、必ず出てくるのがこの2つの考え方:

  • 継承(Inheritance)
  • コンポジション(Composition)

「どちらを使えば良いのか分からない…」「違いがあいまいで困る…」という声をよく聞きます。

この記事では、そんなモヤモヤをスッキリ解消!
継承とコンポジションの違い・使い分け方を、小学生でもわかるように図とコードで解説します。


継承(Inheritance)とは?

意味:親の機能を子が引き継ぐ

継承とは、あるクラスが別のクラスの機能を「引き継ぐ(extend)」仕組みです。

ポイント

  • 「DogはAnimalである」= is-a の関係
  • 子クラスは親クラスのメソッドをそのまま使える
  • コードの再利用がしやすい
  • 複数のサブクラスを同じ親クラスとして扱える(ポリモーフィズム)

コンポジション(Composition)とは?

意味:部品を組み合わせて使う

コンポジションは、あるクラスが別のクラスの「インスタンスを持つ」ことで機能を実現します。

ポイント

  • 「CarはEngineを持っている」= has-a の関係
  • 機能を自由に組み合わせられる
  • 部品の変更・差し替えが簡単
  • テストや保守がしやすい

【図解】継承 vs コンポジション

継承とコンポジションの図解

どっちを使えばいい?使い分け早見表

判断基準継承(Inheritance)コンポジション(Composition)
関係性is-a(〜である)has-a(〜を持っている)
拡張性親の仕様に依存しやすい柔軟で差し替えやすい
保守性親の変更に弱い部品の変更に強い
柔軟性固定的な構造組み合わせ自由
安全性実装に強く依存インターフェースに依存

実例で比較!「車」と「エンジン」の設計

継承を使う例(あまりオススメしない)

この例だと、CarはEngineであるという関係になってしまい、現実とは違いますよね?

コンポジションで書き直す(自然な設計)

この方が、「車はエンジンを持っている」という設計として自然です。


Effective Javaも「コンポジション推奨」

Javaの名著『Effective Java』でも、次のように書かれています:

継承は強力だが、誤って使うと壊れやすい設計になる
多くの場合、コンポジションを使った方が柔軟で安全。

特に、他人が作ったクラスを継承する場合、内部実装の変更に弱くなるため、コンポジションを使う方が良いとされています。


よくある間違いと落とし穴

継承しすぎてクラスが複雑になる

  • 継承を繰り返すと、変更の影響範囲が広がり、バグが出やすくなります。

継承してはいけないクラスを継承する

  • HashSet を継承して機能追加したら、内部の addAll() が原因でバグが発生した…という実例も。

コンポジションで forwarding が面倒になる

  • 部品のメソッドを「転送」するコードが増えることもありますが、安全性とのトレードオフと考えましょう。

おすすめの判断基準

迷ったらコンポジションにしておく!
と覚えておくと、安全で柔軟なコードになります。


まとめ:継承とコンポジションは「道具の使い分け」

  • 継承は「同じ型として扱いたいとき」「完全に同種のクラスであるとき」に使う
  • コンポジションは「部品を組み合わせたいとき」「将来変更される可能性があるとき」に使う
  • 設計の自由度・安全性を重視するならコンポジションの方が有利

次にするべきこと

自分でコードを書いて試してみよう!

このように、自分で「どっちを使うのが自然か?」を考えてみましょう。


自己学習したい方へ

絶対にJavaプログラマーになりたい人へ。」を読んで、自己学習を進めるのがオススメです。

絶対にJavaプログラマーになりたい人へ。


わからないとき・転職したいときは?

  • 「コードレビューをしてほしい」
  • 「学習が一人では難しい」
  • 「Javaで転職したい!」

そんなときは、サイゼントアカデミーがあなたを全力サポートします。

サイゼントアカデミー

コメント

タイトルとURLをコピーしました