PHP 5 建立完整物件模型,PHP 7/8 持續強化型別系統與介面能力。本文深度解析抽象類、介面、Final 關鍵字、類別常數四大進階特性,提供語法細節、設計模式應用與選型決策指南。
abstract class ClassName { ... }new AbstractClass() 致命錯誤。abstract public function name();)與具體方法。<?php
abstract class Animal {
public $name;
public $age;
abstract public function cry(); // 強制子類別實作
public function getName() { return $this->name; } // 具體方法可直接繼承
}
class Cat extends Animal {
public function cry() { echo 'Meow~'; }
}
$cat = new Cat();
$cat->name = 'Kitty';
$cat->cry(); // Meow~
interface InterfaceName { ... }public abstract,不可有方法體;PHP 8.0+ 允許 private 方法與靜態方法體。const),不可定義屬性。implements 實作,必須實作所有方法。class A implements I1, I2 {}。interface C extends A, B {}。class C extends Base implements I1, I2 {}。<?php
interface iUsb {
public function start();
public function stop();
const VERSION = '2.0';
}
class Camera implements iUsb {
public function start() { echo 'Camera Start'; }
public function stop() { echo 'Camera Stop'; }
}
class Phone implements iUsb {
public function start() { echo 'Phone Start'; }
public function stop() { echo 'Phone Stop'; }
}
// 依賴介面程式設計
function connect(iUsb $device) {
$device->start();
}
connect(new Camera());
connect(new Phone());
| 需求 | 選擇 | 理由 |
|---|---|---|
| 需要共享程式碼/屬性/建構子 | 抽象類 | 介面無狀態、無建構子 |
| 定義「是什麼」能力契約 | 介面 | 多型核心、解耦 |
| 類別已有父類別 | 介面 | 單一繼承限制 |
| 需要預設方法實作(PHP 8.0+) | 介面 | 可定義 private/static 方法體 |
| 標記/標識用途(Marker Interface) | 介面 | 如 Serializable, JsonSerializable |
final class SecurityManager {} → 禁止繼承,常用於工具類、單例、不可變值物件。final public function calculateTax(): float {} → 禁止覆寫,但可繼承呼叫。保護核心演算法不被修改。readonly(PHP 8.1+)實現不可變。<?php
class TaxCalculator {
final public function getRate(float $salary): float {
return $salary * 0.08; // 稅率邏輯鎖死
}
}
class RegionalTaxCalculator extends TaxCalculator {
// 錯誤:Cannot override final method
// public function getRate(float $salary): float { return $salary * 0.01; }
}
<?php
class Config {
const TAX_RATE = 0.08;
const MAX_RETRY = 3;
public function calculateTax(float $income): float {
return $income * self::TAX_RATE; // 內部存取
}
}
echo Config::TAX_RATE; // 外部存取:類別名::常數名
echo Config::MAX_RETRY;
$obj = new Config();
echo $obj::TAX_RATE; // 物件也可存取(PHP 5.3+)
$ 符號。public。<?php
// 1. 介面定義契約
interface PaymentGateway {
public function charge(float $amount, string $currency): PaymentResult;
public function refund(string $transactionId): RefundResult;
}
// 2. 抽象基類提供共用邏輯
abstract class BaseGateway implements PaymentGateway {
protected string $merchantId;
protected string $apiKey;
public function __construct(string $merchantId, string $apiKey) {
$this->merchantId = $merchantId;
$this->apiKey = $apiKey;
}
protected function sign(array $params): string { /* 簽名邏輯 */ }
protected function request(string $endpoint, array $data): array { /* HTTP 客戶端 */ }
}
// 3. 具體實作
final class StripeGateway extends BaseGateway {
public function charge(float $amount, string $currency): PaymentResult {
$response = $this->request('/charges', [
'amount' => $amount * 100,
'currency' => $currency,
]);
return new PaymentResult($response['id'], $response['status']);
}
public function refund(string $transactionId): RefundResult { /* ... */ }
}
final class PayPalGateway extends BaseGateway { /* ... */ }
// 4. 工廠根據配置建立實例
class GatewayFactory {
public static function create(string $type): PaymentGateway {
return match ($type) {
'stripe' => new StripeGateway(config('stripe.id'), config('stripe.key')),
'paypal' => new PayPalGateway(config('paypal.id'), config('paypal.key')),
default => throw new InvalidArgumentException("Unknown gateway: $type"),
};
}
}
// 5. 使用
$gateway = GatewayFactory::create('stripe');
$result = $gateway->charge(99.00, 'USD');
readonly 屬性、match 表達式、介面預設方法、::class 常數,善用現代特性簡化程式碼。靈活運用抽象類、介面、Final 與常數,能構建高內聚、低耦合、易測試、易擴充的 PHP 企業級架構。