首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 面向對象基礎深度解析:類、繼承、魔術方法與靜態延遲綁定

     編輯:PHP 相關知識

PHP 面向對象基礎深度解析

本文針對已有 PHP 基礎的開發者,系統梳理類結構、構造/析構、可見性、魔術方法、繼承機制、重載與靜態延遲綁定等核心概念,並附代碼實例驗證行為差異。

一、類與對象基本概念

  • 類:具有相同屬性和方法的對象集合的抽象。
  • 對象:類的具體實例。
class Person {
    private $name = 'PersonName';
    public static $gender = 'PersonGender';
    public function test() { echo $this->name . '
'; } }

二、構造函數 `__construct`

關鍵差異:PHP **不會**自動調用父類構造函數,需手動 `parent::__construct()`。

class Person {
    public function __construct() { echo 'Person construct
'; } } class Teacher extends Person { public function __construct() { parent::__construct(); // 必須手動調用 echo 'Teacher construct
'; } } $t = new Teacher; // 輸出:Person construct → Teacher construct

多構造函數模擬:PHP 不支援多載,利用 `func_get_args()` 實現:

public function __construct() {
    $args = func_get_args();
    $count = func_num_args();
    if ($count === 0) { /* ... */ }
    elseif ($count === 1 && is_array($args[0])) { /* ... */ }
}

三、析構函數 `__destruct`

物件銷毀前自動調用,繼承時同樣需手動 `parent::__destruct()`,每類僅能有一個。

四、可見性控制

關鍵字類內子類類外
public✓✓✓
protected✓✓✗
private✓✗✗

五、魔術方法 `__get`、`__set`、`__isset`、`__unset`

用於攔截不可見屬性的存取,實現資料驗證、日誌、代理等:

class D {
    public $name = 'D name';
    protected $gender = 'male';
    private $age = 18;

    public function __set($name, $value) {
        $allow = ['gender', 'age'];
        if (in_array($name, $allow)) $this->$name = $value;
    }
    public function __get($name) {
        $allow = ['gender', 'age'];
        return in_array($name, $allow) ? $this->$name : null;
    }
    public function __isset($name) { return isset($this->$name); }
    public function __unset($name) { $allow = ['tail']; if (in_array($name, $allow)) unset($this->$name); }
}

注意:`public` 屬性**不會**觸發 `__get`/`__set`,必須是 `protected` 或 `private`。

六、繼承深度解析

1. 單向性

子類繼承父類,父類無法存取子類成員。

2. 重載/覆寫行為差異

父類可見性子類重寫父類方法內存取 $this->prop子類方法內存取 $this->prop
publicpublic子類值子類值
privatepublic父類值(私有不繼承)子類值
protectedprotected/public子類值子類值

原則:`private` 成員在定義它的類中存取時,永遠綁定該類自己的值。

3. 靜態屬性與 `self` vs `static`

class G {
    public static $attr = 'G';
    public function oper() { echo self::$attr; } // 永遠輸出 G
}
class H extends G {
    public static $attr = 'H';
    public function oper() { echo static::$attr; } // 輸出 H(延遲綁定)
}
  • `self::` 編譯期綁定,指向定義該方法的類。
  • `static::` 執行期綁定(Late Static Binding),指向實際調用的類。

七、靜態延遲綁定實例

class I {
    public static function who() { echo __CLASS__; }
    public static function test() { static::who(); }
}
class J extends I {
    public static function who() { echo __CLASS__; }
}
J::test(); // 輸出 J

八、其他魔術方法速查

  • `__call` / `__callStatic`:攔截不存在的方法調用
  • `__toString`:物件轉字串
  • `__invoke`:物件當函數調用
  • `__clone`:複製物件時觸發
  • `__sleep` / `__wakeup`:序列化/反序列化
  • `__set_state`:`var_export()` 導出
  • `__debugInfo`:`var_dump()` 顯示自定義屬性

最佳實踐建議

  1. 屬性預設 `private`,透過 `__get`/`__set` 或 Getter/Setter 控制存取。
  2. 構造函數注入依賴,避免在構造函數執行複雜邏輯。
  3. 善用 `static::` 實現靈活的靜態工廠模式。
  4. 介面定義契約,類實現介面,依賴倒置。
  5. 避免深層繼承,優先使用組合/策略模式。

深入理解這些機制,能寫出更健壯、可維護、可擴展的 PHP 面向對象代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved