三大修飾符對比
| 修飾符 | 類內部 | 子類 | 類外部(實例) |
public | ✅ 可訪問 | ✅ 可訪問 | ✅ 可訪問 |
protected | ✅ 可訪問 | ✅ 可訪問 | ❌ 不可訪問 |
private | ✅ 可訪問 | ❌ 不可訪問 | ❌ 不可訪問 |
代碼驗證
class Base {
public $pub = 'public';
protected $pro = 'protected';
private $pri = 'private';
public function show() {
echo $this->pub . "\n";
echo $this->pro . "\n";
echo $this->pri . "\n"; // 類內部可訪問 private
}
}
class Child extends Base {
public function test() {
echo $this->pub . "\n"; // ✅
echo $this->pro . "\n"; // ✅
// echo $this->pri . "\n"; // ❌ Fatal Error: Cannot access private property
}
}
$obj = new Child();
echo $obj->pub . "\n"; // ✅
// echo $obj->pro . "\n"; // ❌ Fatal Error: Cannot access protected property
// echo $obj->pri . "\n"; // ❌ Fatal Error: Cannot access private property
繼承時的修飾符規則
原則:子類重寫父類方法時,訪問級別只能 擴大或保持,不能縮小。
即:public > protected > private,子類修飾符 ≥ 父類修飾符。
class ParentClass {
protected function foo() {}
public function bar() {}
}
class ChildClass extends ParentClass {
public function foo() {} // ✅ protected -> public(擴大)
protected function bar() {} // ❌ public -> protected(縮小,報錯)
}
最佳實踐建議
- 屬性默認 private:封裝內部狀態,通過公共 getter/setter 控制訪問。
- 方法默認 public:構成類的對外契約(API)。
- 內部協作用 protected:供子類擴展或模板方法模式使用。
- 避免過度使用 protected:會增加耦合,優先考慮組合而非繼承。
靜態成員同理
class Config {
private static $instance = null;
protected static $settings = [];
public static function getInstance() { ... }
protected static function loadSettings() { ... }
}