目次
1. 本記事のポイント
- interfaceとabstractクラスの設計上の役割と使い分けを解説
- PHPの構文・継承制約・実装方法の違いを具体例で示す
- 実務における選定判断や落とし穴もカバー
2. PHPのinterfaceとabstractクラスの違いとは?
PHPにおけるinterface
とabstract
クラスは、いずれも共通の振る舞いを定義する手段ですが、設計目的や使い方に明確な違いがあります。
interface
は、実装すべきメソッドのシグネチャのみを定義し、処理内容(中身)は持ちません。多重継承が可能で、異なるクラス間に共通の契約(仕様)を持たせることが主目的です。
一方、abstract
クラスは、未実装の抽象メソッドと、実装済みの具体メソッドやプロパティを混在させることができます。継承先クラスに基本的な振る舞いを提供しつつ、特定の振る舞いだけをサブクラスに委ねる際に使われます。
実務では、外部連携・プラグイン拡張・契約定義にはinterface
、共通実装の継承やテンプレートメソッドパターンにはabstract
クラスが選ばれる傾向があります。
3. 詳細解説
1. 複数のクラスに共通の機能仕様を持たせたい場合(interface)
PHP
interface Logger {
public function log(string $message): void;
}
class FileLogger implements Logger {
public function log(string $message): void {
// ログをファイルに出力
echo "File: $message\n";
}
}
このように、interfaceは必ずすべてのメソッドを実装しなければなりません。
複数のinterfaceを同時に実装できるため、異なる関心ごとを分離して設計できます。
2. 基底クラスとして共通処理を持たせたい場合(abstractクラス)
PHP
abstract class BaseLogger {
protected string $prefix = '[LOG]';
abstract public function log(string $message): void;
public function format(string $message): string {
return $this->prefix . ' ' . $message;
}
}
class ConsoleLogger extends BaseLogger {
public function log(string $message): void {
echo $this->format($message) . "\n";
}
}
abstractクラスでは、一部を具体的に定義しておき、共通処理の重複を避けられます。format()
のような共通メソッドを継承先でそのまま使えるのが利点です。
3. interfaceとabstractの違いまとめ
比較項目 | interface | abstractクラス |
---|---|---|
多重継承 | 可能 | 不可 |
実装済みメソッド | 不可 | 可能 |
プロパティ定義 | 不可 | 可能 |
実装必須 | すべてのメソッド | 抽象メソッドのみ |
用途 | 契約・仕様の明示 | 部分実装+継承の再利用 |
4. よくあるミス・誤解・落とし穴
interface
にはプロパティやコンストラクタを定義できないため、状態を持たせたい場合には不向きです。abstract
クラスは継承制約が1つのみであるため、多重継承したい場合には不適です。- interfaceに既定処理を入れようとする誤用も見られますが、これは仕様的に不可能です(PHP 8.1以降で
default methods
的な記述は不可)。 - traitとの使い分けも誤解されがちですが、traitはコードの再利用が目的で、interfaceやabstractとは役割が異なります。
5. まとめ
PHPにおいて、interface
は仕様定義、abstract
クラスは共通処理の部分実装に用います。
- 複数の型に共通インターフェースを強制したい →
interface
- 一部共通ロジックを継承させたい →
abstract class
継承制約やメソッド実装の有無、設計意図を踏まえて適切に使い分けましょう。