本文深入解析 PHP 面向物件三大進階支柱:介面定義契約、多型實現靈活行為、抽象類別提供部分實作,附完整代碼範例與設計原則。
介面宣告方法簽名,不包含實作。實作類別 必須 實現所有介面方法。支援多重實作,解耦「做什麼」與「怎麼做」。
<?php
interface Shop {
public function buy($gid);
public function sell($gid);
public function view($gid);
}
class BaseShop implements Shop {
public function buy($gid) {
echo "購買商品 ID: $gid";
}
public function sell($gid) {
echo "出售商品 ID: $gid";
}
public function view($gid) {
echo "查看商品 ID: $gid";
}
}
// 使用介面作為型別提示
function processOrder(Shop $shop, $gid) {
$shop->buy($gid);
}
$shop = new BaseShop();
processOrder($shop, 101); // 輸出:購買商品 ID: 101
多型允許不同類別對同一方法呼叫做出不同回應。PHP 不支援方法重載,但可透過介面、繼承、可變參數實現多型效果。
interface User {
public function getName();
public function setName($name);
}
class NormalUser implements User {
private $name;
public function getName() { return $this->name; }
public function setName($name) { $this->name = $name; }
}
class UserAdmin {
public static function changeUserName(User $user, $newName) {
$user->setName($newName);
}
}
$user = new NormalUser();
UserAdmin::changeUserName($user, "Tom");
echo $user->getName(); // Tom
function open_database($db, $cache_size_or_values = null, $cache_size = null) {
switch (func_num_args()) {
case 1: return select_db($db);
case 2: return select_db($db, $cache_size_or_values);
case 3: return select_db($db, $cache_size_or_values, $cache_size);
}
return false;
}
abstract class AbstractClass {
abstract protected function getValue();
abstract protected function prefixValue($prefix);
public function printOut() {
echo $this->getValue() . " ";
}
}
class ConcreteClass1 extends AbstractClass {
protected function getValue() { return "ConcreteClass1"; }
public function prefixValue($prefix) { return "{$prefix}ConcreteClass1"; }
}
class ConcreteClass2 extends AbstractClass {
protected function getValue() { return "ConcreteClass2"; }
public function prefixValue($prefix) { return "{$prefix}ConcreteClass2"; }
}
$obj1 = new ConcreteClass1();
$obj1->printOut(); // ConcreteClass1
echo $obj1->prefixValue('FOO_'); // FOO_ConcreteClass1
$obj2 = new ConcreteClass2();
$obj2->printOut(); // ConcreteClass2
echo $obj2->prefixValue('FOO_'); // FOO_ConcreteClass2
| 特性 | 介面 | 抽象類別 | 具體類別 |
|---|---|---|---|
| 可實例化 | 否 | 否 | 是 |
| 方法實作 | 無 | 可部分實作 | 全部實作 |
| 繼承關係 | implements(多重) | extends(單一) | extends(單一) |
| 適用場景 | 定義契約、跨層級共享行為 | 共享核心邏輯、強制子類實作 | 完整實體 |
善用介面定義契約、抽象類別封裝共同邏輯、多型實現擴展性,是編寫可維護、可擴展 PHP 系統的關鍵。遵循「依賴倒置原則」:依賴抽象而非具體實作。