はじめに
デザインパターンの勉強をしていてこんなことを思いました。
「抽象クラス」と「インターフェース」の違いってなんだ?
どう使い分けしたらいいんだろう?
インターフェースっていらなくね?
以上を踏まえて、今回は「抽象クラス」と「インターフェース」について知らべてみました。
抽象クラスとは?
抽象クラスは「継承関係」にあり、実装クラスに「処理の再利用」を行いたいときに使用する。
抽象クラスの特徴
- 抽象クラスを継承した場合、抽象クラス内の抽象メソッドのオーバーライドしないといけない
- インスタンス化できない
- 多重継承はできない
- フィールドをもてる
IS-Aの法則
抽象クラスは「IS-Aの法則」を満たす必要があるといわれています。 例えば、Car(車) は Vehicle(乗り物) であるという関係です(Car is a Vehicle.)。抽象クラスを利用することで、基底クラスの共通機能を継承し、サブクラスにて特定の機能を実装する形が一般的です。
サンプルコード
abstract class Vehicle {
abstract void move();
}
class Car extends Vehicle {
void move() {
System.out.println("Car is moving.");
}
}
インターフェースとは?
インターフェースは、クラス仕様としての「型定義」を行うためのものです。インターフェースを通じて、CAN-DO の関係を構築します。
インターフェースの特徴
- 多重継承が可能
- コンストラクタは不可
- フィールドをもてない
CAN-DOの関係
インターフェースは、オブジェクトに特定の機能を実装させたい場合に用います。例えば、「車は移動できる」「飛行機も移動できる」という共通の機能をインターフェースとして定義し、それぞれのクラスに実装させることができます。
サンプルコード
interface Movable {
void move();
}
class Car implements Movable {
public void move() {
System.out.println("Car is moving.");
}
}
class Airplane implements Movable {
public void move() {
System.out.println("Airplane is flying.");
}
}
両者の違い
機能 | 抽象クラス | インターフェース |
---|---|---|
コンストラクタ | あり | なし |
フィールド | あり | なし |
多重継承 | 不可 | 可能 |
用途 | 共通の実装や状態を保持 | 型定義、機能の提供 |
インターフェースのユースケース
- 多重継承が必要な場合
- 実装を持たせたくない場合
- リファクタやAPI設計において、将来の変更に備えたい場合
例: APIやデータベースの呼び出し先を将来的に変更する場合、インターフェースやそのコントローラー側を修正する必要がなく、実装側の変更だけで済むため、他に影響を与えない疎結合化を実現できる。
抽象クラスのユースケース
- 共通の実装や状態を持たせたい場合
- コードの再利用性を高める
- クラス間に強い関係性がある場合
まとめ
改めて調べることで理解や追加どころはイメージできたけど、
むやみに使いまわすものでもないなと思いました。
小規模なプロジェクトなら使わないほうがむしろいいのかなと。
ご指摘等あればぜひコメントください!