PHP 面向對象高級特性是構建健壯、可擴展系統的基石。本文系統講解靜態成員、Final 關鍵字、數據訪問機制(parent/self/static)、接口契約,並提供完整代碼示例與最佳實踐指南。
屬於類而非實例,所有實例共享同一份數據。無需實例化即可訪問。
class NBAPlayer {
// 靜態屬性:所有球員共用聯盟主席
public static $commissioner = 'David Stern';
// 靜態方法:只能訪問靜態成員
public static function changeCommissioner( $name ) {
self::$commissioner = $name; // 內部用 self 或 static
}
}
// 外部訪問:類名::
echo NBAPlayer::$commissioner; // David Stern
NBAPlayer::changeCommissioner('Adam Silver');
echo NBAPlayer::$commissioner; // Adam Silver
| 場景 | 語法 | 說明 |
|---|---|---|
| 類內部訪問靜態屬性 | self::$prop 或 static::$prop | static 支援晚期靜態綁定 (LSB) |
| 類內部訪問靜態方法 | self::method() 或 static::method() | 同上 |
| 外部訪問 | ClassName::$prop / ClassName::method() | 不需要實例 |
| 子類訪問父類靜態成員 | parent::$prop / parent::method() | 繼承鏈向上查找 |
| 靜態方法中禁用 | $this-> | 無實例上下文 |
class A {
public static function who() { echo __CLASS__; }
public static function test() { static::who(); } // LSB
}
class B extends A {
public static function who() { echo __CLASS__; }
}
B::test(); // 輸出 B(而非 A)
防止繼承與重寫,鎖定設計意圖。
| 用法 | 效果 |
|---|---|
final class X | 類不可被繼承 |
final public function foo() | 方法不可被子類重寫 |
final public $prop = 1; | 屬性不可被子類覆蓋 (PHP 8.1+) |
final class SecurityCore {
final public function encrypt( $data ) {
// 核心加密邏輯,禁止子類修改
}
}
// class Hack extends SecurityCore {} // Fatal Error
// class Sub extends SecurityCore { public function encrypt() {} } // Fatal Error
| 關鍵字 | 用途 | 訪問範圍 |
|---|---|---|
$this-> | 實例屬性/方法 | 當前對象(含繼承) |
self:: | 類靜態成員/常量/方法 | 當前類定義(不含子類覆蓋) |
static:: | 靜態成員/方法(LSB) | 運行時實際調用類(含子類覆蓋) |
parent:: | 父類成員/方法 | 直接父類(可訪問被重寫的成員) |
ClassName:: | 指定類靜態成員 | 外部訪問 |
class Base {
public static $val = 'base';
public static function test() { echo "Base::test\n"; }
}
class Child extends Base {
public static $val = 'child';
public static function test() {
echo "Child::test\n";
parent::test(); // 調用被重寫的父類方法
self::test(); // 調用 Child::test (無限遞歸風險)
static::test(); // 調用 Child::test (LSB)
}
}
Child::test();
定義行為契約,支援多實現、多繼承、類型提示。
publicimplements 實現(而非 extends)interface B extends A)instanceof 判斷interface CanEat {
public function eat( $food );
}
interface CanPee extends CanEat {
public function pee();
}
class Human implements CanEat {
public function eat( $food ) {
echo "Human eating $food<br />";
}
}
class Demon implements CanPee {
public function eat( $food ) {
echo "Demon eating $food<br />";
}
public function pee() {
echo "Demon peeing<br />";
}
}
$human = new Human();
$human->eat('apple');
$demon = new Demon();
$demon->eat('soul');
$demon->pee();
// 逆向檢查
var_dump( $human instanceof CanEat ); // true
var_dump( $demon instanceof CanPee ); // true
var_dump( $demon instanceof CanEat ); // true (繼承關係)
final。static:: (LSB) 以支援繼承擴展;需明確調用父類實現用 parent::;內部調用自身定義用 self::。| 陷阱 | 後果 | 修正 |
|---|---|---|
靜態方法中使用 $this | Fatal Error | 改用 self::/static:: |
| 子類重寫父類 final 方法 | Fatal Error | 移除 final 或不重寫 |
| 接口方法聲明為 protected/private | Fatal Error | 接口方法必須 public |
self:: 調用被子類重寫的靜態方法 | 調用父類版本(非預期) | 改用 static:: 實現 LSB |
| 實現接口但缺少方法 | Fatal Error | 補全所有接口方法 |
掌握這四大高級特性,能編寫出結構清晰、擴展性強、運行時行為可預測的 PHP 面向對象代碼。