Javaにおける継承とコンポジション(構成)の違い徹底解説
Javaのオブジェクト指向設計において、「継承(Inheritance)」と「コンポジション(構成・Composition)」はどちらもコードの再利用性を実現する重要な手法です。しかし、その考え方や使い方には大きな違いがあります。
コンポジションとは、あるクラスの中に別クラスのインスタンスをフィールドとして持たせる設計技法です。一方、継承とは、既存のクラスを拡張(extends)することで、親クラスのプロパティや動作を子クラスが引き継ぐ仕組みです。
本記事では、両者の違いを比較表とサンプルコードを使ってわかりやすく解説します。
継承とコンポジションの違い一覧
| No. | 比較項目 | 継承(Inheritance) | コンポジション(Composition) |
|---|---|---|---|
| 1 | 基本概念 | 「is-a(〜である)」の関係を表す。例:犬は動物である | 「has-a(〜を持つ)」の関係を表す。例:大学は学生を持つ |
| 2 | コード再利用 | 1つのクラスが直接継承できるのは1つのクラスのみのため、再利用範囲が限定される | 複数のクラスで同じコードを柔軟に再利用できる |
| 3 | 適用タイミング | コンパイル時に機能が決定される(静的) | 実行時(ランタイム)に容易に実現できる(動的) |
| 4 | finalクラスの扱い | finalクラスは継承できないため、コードを再利用できない | finalクラスであっても、インスタンスを持つことでコードを再利用できる |
| 5 | メソッドへのアクセス | 親クラスのpublicおよびprotectedメソッドがすべて公開される | 内部メソッドは公開されず、publicインターフェースを通じてのみやり取りする |
継承のコード例
以下は、DogクラスがAnimalクラスを継承し、親クラスのフィールドを利用する例です。
class Animal {
String name = "Orio";
}
class Dog extends Animal {
String type = "Dog";
public static void main(String args[]) {
Dog p = new Dog();
System.out.println("Name:" + p.name);
System.out.println("Type:" + p.type);
}
}extendsキーワードにより、DogクラスはAnimalクラスのnameフィールドをそのまま使えるようになります。
コンポジションのコード例
以下は、CollegeクラスがStudentクラスのインスタンスをフィールドとして保持する例です。
public class Student {
}
public class College {
private Student student;
public College() {
this.student = new Student();
}
}CollegeクラスはStudentを継承していませんが、内部にインスタンスを持つことでその機能を利用できます。これが「has-a」の関係です。
まとめ
一般的に、柔軟性や保守性を考慮すると、継承よりもコンポジションの方が推奨される場面が多いと言われています。「is-a」の関係が明確に成り立つ場合のみ継承を使い、それ以外はコンポジションを選ぶのが良い設計の基本です。
-
Javaにおける例外(Exception)とエラー(Error)の違いを徹底解説
Javaにおいて、例外(Exception)とエラー(Error)はどちらも Throwable クラスのサブクラスです。しかし、両者には明確な違いがあり、堅牢なアプリケーションを開発するうえで、それぞれの特性を正しく理解することは非常に重要です。 エラー(Error)とは エラーは、主にシステムリソースの不足によって発生する深刻な問題を示します。この種の問題はアプリケーション側でキャッチ(捕捉)すべきものではなく、基本的にプログラマーが対処できる範囲を超えています。代表的な例としては、システムクラッシュやメモリ不足(OutOfMemoryError)などが挙げられます。 エラーはほとんどの
-
Javaにおけるシリアライズ(Serializable)と外部化(Externalizable)の違いを徹底解説
Javaのシリアライズ(直列化)と外部化(Externalizable)は、どちらもオブジェクトをバイトストリームに変換し、そのバイトストリームをデータベースやメモリに保存するための仕組みです。java.io.Serializableインターフェースを実装したクラスは自動的にシリアライズ可能となります。一方、外部化はアプリケーションの要件に応じてカスタマイズされたシリアライズを行いたい場合に使用され、Externalizableインターフェースはjava.io.Serializableを継承しています。以下の表に、両者の主な違いをまとめました。No.比較項目シリアライズ(Serializabl