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

PHP 類別繼承實戰:解決程式碼重複的核心模式

     編輯:PHP 相關知識

物件導向程式設計中,繼承是消除程式碼重複、實現多態的核心機制。本文透過完整的商城產品模型實例,深入解析 PHP 類別繼承的原理、語法與最佳實踐,展示如何設計清晰的類別階層結構。

繼承核心概念

繼承允許子類別(Child Class)取得父類別(Parent Class)的公共(public)與受保護(protected)屬性與方法。使用 extends 關鍵字建立繼承關係:

class ChildClass extends ParentClass { /* ... */ }

完整實例:商城產品模型

基礎類別:ShopProduct

<?php
header('Content-Type: text/html; charset=utf-8');

class ShopProduct {
    // 共同屬性
    public $title;
    public $producerMainName;
    public $producerFirstName;
    public $price;
    public $numPages = 0;      // 書籍專用
    public $playLength = 0;    // 光碟專用
    
    public function __construct(
        $title, 
        $firstName, 
        $mainName, 
        $price, 
        $numPages = 0, 
        $playLength = 0
    ) {
        $this->title = $title;
        $this->producerFirstName = $firstName;
        $this->producerMainName = $mainName;
        $this->price = $price;
        $this->numPages = $numPages;
        $this->playLength = $playLength;
    }
    
    // 共同方法
    public function getProducer() {
        return "{$this->producerFirstName} {$this->producerMainName}";
    }
    
    public function getSummaryLine() {
        return "{$this->title} ({$this->producerMainName}, {$this->producerFirstName})";
    }
}
?>

子類別:CdProduct(繼承並擴展)

class CdProduct extends ShopProduct {
    // 擴展方法:取得播放長度
    public function getPlayLength() {
        return $this->playLength;
    }
    
    // 覆寫方法:提供光碟專屬摘要
    public function getSummaryLine() {
        $base = parent::getSummaryLine(); // 呼叫父類別方法
        return "{$base}: playing time - {$this->playLength}";
    }
}

子類別:BookProduct(繼承並擴展)

class BookProduct extends ShopProduct {
    // 擴展方法:取得頁數
    public function getNumberOfPages() {
        return $this->numPages;
    }
    
    // 覆寫方法:提供書籍專屬摘要
    public function getSummaryLine() {
        $base = parent::getSummaryLine(); // 呼叫父類別方法
        return "{$base}: page count - {$this->numPages}";
    }
}

使用範例

<?php
// 實例化子類別(自動呼叫父類別建構子)
$product1 = new BookProduct("PHP 物件導向", "陳", "大明", 580, 350);
$product2 = new CdProduct("Laravel 實戰教學", "林", "小華", 1200, 0, "12小時");

// 存取繼承的方法
echo "作者: {$product2->getProducer()}<br>"; // 輸出: 林 小華

// 存取覆寫的方法(多態表現)
echo "書籍: {$product1->getSummaryLine()}<br>";
echo "光碟: {$product2->getSummaryLine()}<br>";
?>

關鍵機制深度解析

1. 方法搜尋順序

呼叫 $product2->getProducer() 時:

  1. 先在 CdProduct 尋找 getProducer()
  2. 找不到則向上查找 ShopProduct
  3. 仍找不到則拋出錯誤

屬性存取遵循相同邏輯。

2. 建構子繼承行為

子類別未定義 __construct() 時,自動使用父類別建構子。但這導致父類別需處理所有子類別專屬參數,違反單一職責原則。

3. 覆寫與擴展

  • 覆寫:子類別重新定義同名方法,完全取代父類別實作
  • 擴展:透過 parent::method() 呼叫父類別實作,再添加子類別邏輯

進階改善:建構子責任分離

上述設計中,父類別建構子處理所有參數,不符合封裝原則。改善版本請參考下一篇文章「PHP parent 關鍵字應用」。

可見性與繼承規則

修飾詞子類別可存取外部可存取說明
public是是完全公開
protected是否僅類別內部與子類別
private否否僅定義該類別內部

最佳實踐原則

  1. 組合優於繼承:需求變化時,組合更靈活
  2. 里氏替換原則:子類別必須能替換父類別而不破壞功能
  3. 避免深層繼承:超過 3 層難以維護,考慮介面或 Trait
  4. Final 關鍵字:防止關鍵方法被覆寫 final public function criticalMethod()
  5. 抽象類別:定義介面契約,強制子類別實作 abstract class BaseProduct

總結

PHP 類別繼承透過 extends 關鍵字實現程式碼復用與多態。良好的繼承設計需遵循單一職責、開放封閉等 SOLID 原則,合理劃分父子類別責任邊界。理解方法搜尋機制、建構子繼承行為與可見性規則,是掌握 PHP 物件導向程式設計的關鍵基石。實際專案中,配合介面、Trait 與組合模式,能構建更彈性、可維護的系統架構。

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