在 PHP 物件導向程式設計中,類別的繼承、多型與封裝是核心三大支柱。本文將系統整理 PHP 類別相關的關鍵知識點,包含最終類別與方法、抽象類別與介面、屬性與方法多載(魔術方法)等,並附上完整程式碼範例與執行結果,幫助開發者快速掌握進階 OOP 技巧。
final 可修飾類別或方法:
final class Base {} // 錯誤:無法繼承 final 類別
class ParentClass {
final public function lockedMethod() {} // 子類別不可覆寫
}
抽象類別(abstract class)不可實例化,專為繼承設計;抽象方法(abstract method)僅宣告簽名,無方法主體。
abstract class Animal {
public abstract function makeSound(); // 必須由子類別實作
}
class Dog extends Animal {
public function makeSound() { echo "汪汪!"; }
}
規則摘要:
介面(interface)可視為「純抽象類別」,僅包含常數與抽象方法(無需 abstract 關鍵字)。
interface Flyable {
public function fly();
}
class Bird implements Flyable {
public function fly() { echo "飛行中..."; }
}
介面 vs 抽象類別關鍵差異:
| 特性 | 抽象類別 | 介面 |
|---|---|---|
| 成員組成 | 屬性、常數、抽象/具體方法 | 常數、抽象方法 |
| 繼承機制 | 單繼承(extends) | 多實作(implements a, b, c) |
| 介面繼承 | 不支援 | 單繼承(interface A extends B) |
PHP 透過雙底線魔術方法攔截不存在的屬性/方法存取,實現「多載」效果。
| 操作 | 觸發魔術方法 |
|---|---|
| 讀取不存在屬性 | __get($name) |
| 寫入不存在屬性 | __set($name, $value) |
isset() 檢查 | __isset($name) |
unset() 銷毀 | __unset($name) |
class PropertyBag {
private $data = [];
public function __get($key) {
return $this->data[$key] ?? "$key not exists";
}
public function __set($key, $val) { $this->data[$key] = $val; }
public function __isset($key) { return isset($this->data[$key]); }
public function __unset($key) { unset($this->data[$key]); }
}
$obj = new PropertyBag();
echo $obj->name; // name not exists
$obj->name = "PHP";
echo $obj->name; // PHP
var_dump(isset($obj->name)); // bool(true)
| 場景 | 觸發魔術方法 |
|---|---|
| 物件呼叫不可存取方法 | __call($name, $args) |
| 靜態呼叫不可存取方法 | __callStatic($name, $args) |
class Dynamic {
public function __call($method, $args) {
echo "動態方法 $method 不存在,參數:" . json_encode($args);
}
public static function __callStatic($method, $args) {
echo "靜態方法 $method 不存在";
}
}
$d = new Dynamic();
$d->run(1, 2); // 動態方法 run 不存在...
Dynamic::fly(); // 靜態方法 fly 不存在
final 保護核心邏輯不被意外覆寫。#[Attribute] 與 match 表達式,部分場景可替代魔術方法。掌握 PHP 類別的進階特性,能讓你設計出更彈性、可維護的物件導向架構。建議結合實際專案場景,逐步將上述概念內化為直覺。