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

PHP 類別封裝與繼承深度解析:從基礎到實戰

     編輯:PHP 相關知識

PHP 類別封裝與繼承深度解析:從基礎到實戰

物件導向程式設計 (OOP) 的三大支柱為封裝、繼承、多型。本文深入淺出講解 PHP 中的封裝機制與單一繼承模型,並透過完整程式碼示範核心概念與最佳實務。

一、封裝:資料保護與存取控制

封裝將資料(屬性)與操作資料的方法(方法)結合在類別內部,透過可視性關鍵字控制外部存取權限,達到資料隱藏與安全性提升。

三種可視性修飾詞比較

修飾詞類別內部子類別外部程式碼預設值
public✅✅✅是(未指定時)
protected✅✅❌否
private✅❌❌否

程式碼示範:封裝實作

<?php
class MyClass {
    public    $public    = 'Public';    // 公開屬性
    protected $protected = 'Protected'; // 受保護屬性
    private   $private   = 'Private';   // 私有屬性

    public function sayHello() {
        echo "Hello from {$this->public}!";
    }

    // 透過公用方法存取私有屬性(Getter/Setter 模式)
    public function getPrivate() {
        return $this->private;
    }

    public function setPrivate($value) {
        $this->private = $value;
    }
}

$obj = new MyClass();
echo $obj->public;        // ✅ 輸出:Public
// echo $obj->protected;  // ❌ Fatal Error
// echo $obj->private;    // ❌ Fatal Error

// 正確方式:透過公用方法
echo $obj->getPrivate();  // ✅ 輸出:Private
$obj->setPrivate('New Value');
echo $obj->getPrivate();  // ✅ 輸出:New Value

魔術方法 __get() / __set() 實現動態屬性存取

class DynamicProperty {
    private $data = array();

    public function __set($name, $value) {
        $this->data[$name] = $value;
    }

    public function __get($name) {
        return isset($this->data[$name]) ? $this->data[$name] : null;
    }
}

$obj = new DynamicProperty();
$obj->dynamic = '動態屬性';  // 觸發 __set()
echo $obj->dynamic;          // 觸發 __get(),輸出:動態屬性

二、繼承:程式碼復用與擴充

PHP 採用 單一繼承 模型:一個子類別只能繼承一個父類別(extends),但可實作多個介面(implements)。

基本語法與執行流程

<?php
// 父類別(基類別)
class Father {
    protected $name;

    public function __construct($name) {
        $this->name = $name;
        echo "Father 建構子執行\n";
    }

    public function work() {
        echo "{$this->name} 正在工作\n";
    }

    public function __destruct() {
        echo "Father 解構子執行\n";
    }
}

// 子類別
class Son extends Father {
    // 未定義建構子 → 自動繼承父類別建構子
    // 若需自訂建構子,務必呼叫 parent::__construct()

    public function play() {
        echo "{$this->name} 正在玩遊戲\n";
    }
}

// 實例化
$father = new Father('爸爸');  // 輸出:Father 建構子執行
$father->work();               // 輸出:爸爸 正在工作

$son = new Son('兒子');        // 輸出:Father 建構子執行(繼承)
$son->work();                  // 輸出:兒子 正在工作(繼承方法)
$son->play();                  // 輸出:兒子 正在玩遊戲(自有方法)

關鍵規則與陷阱

  • 建構子繼承:子類別未定義 __construct() 時自動呼叫父類別建構子;自定義時必須手動 parent::__construct()。
  • 方法覆寫:子類別可重新定義父類別方法,若需保留父類別邏輯請呼叫 parent::method()。
  • final 關鍵字:標記 final 的類別不可被繼承,標記 final 的方法不可被覆寫。
  • 無多重繼承:class A extends B extends C ❌ 錯誤語法。需用介面或 Trait 替代。
  • Trait 橫向復用:PHP 5.4+ 引入 Trait 解決單一繼承限制,實現程式碼片段跨類別復用。

三、最佳實務建議

  1. 預設使用 private:屬性盡可能私有,透過公用方法(Getter/Setter)控制存取邏輯。
  2. 善用 protected:預期子類別需存取的內部資料或方法。
  3. 介面優於繼承:定義契約用 interface,共用實作用 Trait,減少繼承層級深度。
  4. 避免過度繼承:超過 3 層繼承通常意味著設計問題,考慮組合模式替代。
  5. 型別宣告:PHP 7+ 支援標量型別宣告與回傳型別,強化程式碼可讀性與 IDE 提示。

延伸閱讀

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