PHP 不允許類實現多個聲明同名方法的無關接口(報錯 Can't inherit abstract function)。本文解析衝突原因,提供接口繼承共同父接口的標準解法,並對比其他語言處理方式。
<?php
interface A { public function x(); }
interface B { public function x(); }
class C implements A, B { // Fatal Error
public function x() {}
}
// Can't inherit abstract function B::x() (previously declared abstract in A)
?>
原因:PHP 要求實現類對每個接口方法提供唯一實現。兩個無關接口各自聲明 x(),PHP 無法確認是否為「同一語義契約」,強制報錯防止隱性 Bug。
<?php
interface Base { public function x(); } // 定義核心契約
interface A extends Base {} // 繼承契約
interface B extends Base {}
class C implements A, B {
public function x() { echo "success"; } // 唯一實現滿足所有接口
}
$c = new C();
$c->x(); // success
?>
此模式明確表達:「A、B 都要求實現 Base 定義的 x() 行為」,消除歧義。
| 語言 | 機制 | 示例 |
|---|---|---|
| Java 8+ | 默認方法 + 顯式選擇 | class C implements A,B { public void x(){ A.super.x(); } } |
| C# | 顯式接口實現 | void A.x(){} void B.x(){} 可分別實現 |
| Go | 隱式實現 | 只要方法簽名匹配即滿足所有接口,無衝突概念 |
| TypeScript | 結構類型 | 同 Go,簽名兼容即可 |
UserRepository::saveUser()、CacheRepository::saveCache()Trait 組合,避免接口爆炸<?php
interface Logger { public function log(string $msg); }
abstract class BaseLogger implements Logger {
protected string $prefix = '';
public function log(string $msg): void {
$this->write($this->prefix . $msg);
}
abstract protected function write(string $msg): void;
}
class FileLogger extends BaseLogger {
protected function write(string $msg): void { file_put_contents('log.txt', $msg.PHP_EOL, FILE_APPEND); }
}
class SysLogger extends BaseLogger {
protected function write(string $msg): void { syslog(LOG_INFO, $msg); }
}
?>
抽象類封裝通用邏輯(如格式化、過濾),具體類只關注輸出方式,接口保持純契約。