封裝與繼承是 PHP 面向對象編程(OOP)的兩大基石。本文通過代碼實例,系統講解訪問控制(public/protected/private)、屬性/方法可見性、單繼承機制、構造/析構函數繼承規則,並澄清常見誤區。
PHP 提供三種訪問修飾符,控制類成員(屬性、方法)的可見範圍:
| 修飾符 | 類內部 | 子類 | 外部代碼 | 說明 |
|---|---|---|---|---|
public | ✅ | ✅ | ✅ | 默認,完全公開 |
protected | ✅ | ✅ | ❌ | 僅類層級可見,對外隱藏 |
private | ✅ | ❌ | ❌ | 僅當前類可見,子類不可見(但可重新定義同名成員) |
class MyClass {
public $public = 'Public';
protected $protected = 'Protected';
private $private = 'Private';
public function sayHello() {
echo $this->public; // ✅
echo $this->protected; // ✅
echo $this->private; // ✅
}
}
$obj = new MyClass();
echo $obj->public; // ✅ 輸出 Public
// echo $obj->protected; // ❌ Fatal Error
// echo $obj->private; // ❌ Fatal Error
__get()/__set() 實現受控訪問若需外部讀寫 private/protected 屬性,可定義魔術方法:
class User {
private $name;
public function __get($name) {
if ($name === 'name') return $this->name;
}
public function __set($name, $value) {
if ($name === 'name' && is_string($value)) $this->name = $value;
}
}
$user = new User();
$user->name = '張三'; // 觸發 __set
echo $user->name; // 觸發 __get
PHP 採用單繼承:一個子類只能繼承一個父類(class Child extends Parent)。不支援多重繼承(class A extends B extends C 非法),但可用 Trait 或 介面 實現代碼復用。
public、protected 成員。private 成員。protected 方法,子類只能是 protected 或 public)。__construct()、析構函數 __destruct() 若子類未定義,將自動調用父類對應方法。class Father {
protected $name;
public function __construct($name) { $this->name = $name; }
public function work() { echo "{$this->name} 正在工作\n"; }
public function __destruct() { echo "Father 銷毀\n"; }
}
class Son extends Father {
// 未定義構造函數,自動繼承父類構造函數
public function play() { echo "{$this->name} 正在玩遊戲\n"; }
}
$father = new Father('爸爸');
$father->work(); // 爸爸 正在工作
$son = new Son('兒子');
$son->work(); // 兒子 正在工作(繼承自父類)
$son->play(); // 兒子 正在玩遊戲(子類擴展)
private + Getter/Setter:將屬性設為 private,通過公共方法暴露,便於加入驗證邏輯、日誌、延遲加載等。class B { private $a; })。final class)或方法被重寫(final public function),保護核心邏輯。static 屬性/方法屬於類,非實例。子類繼承時共享同一靜態變量(晚期靜態綁定 static:: 可解決)。深入理解封裝與繼承,是編寫高內聚、低耦合、可維護 PHP 代碼的關鍵。