parent 是 PHP 存取父類別成員的關鍵字,配合範圍解析運算子 :: 使用。本文詳細說明兩大核心應用場景:建構子鏈呼叫 確保物件完整初始化,以及 覆寫方法中擴充父類邏輯 避免程式碼重複。
子類別定義自己的 __construct() 時,必須主動呼叫 parent::__construct(),否則父類屬性將不會初始化,導致物件狀態不完整。
<?php
class ShopProduct {
public $title;
public $producerFirstName;
public $producerMainName;
public $price;
public function __construct($title, $firstName, $mainName, $price) {
$this->title = $title;
$this->producerFirstName = $firstName;
$this->producerMainName = $mainName;
$this->price = $price;
}
}
class BookProduct extends ShopProduct {
public $numPages;
public function __construct($title, $firstName, $mainName, $price, $numPages) {
// 關鍵:先讓父類完成自身屬性初始化
parent::__construct($title, $firstName, $mainName, $price);
// 再處理子類特有屬性
$this->numPages = $numPages;
}
}
class CdProduct extends ShopProduct {
public $playLength;
public function __construct($title, $firstName, $mainName, $price, $playLength) {
parent::__construct($title, $firstName, $mainName, $price);
$this->playLength = $playLength;
}
}
?>
當子類別需要修改父類方法行為時,透過 parent::methodName() 取得父類執行結果,再加上子類邏輯,實現「核心邏輯在父類,差異邏輯在子類」的分層設計。
<?php
class ShopProduct {
// ... 前述屬性與建構子 ...
public function getSummaryLine() {
$base = "{$this->title} ( {$this->producerMainName},";
$base .= "{$this->producerFirstName} )";
return $base;
}
}
class BookProduct extends ShopProduct {
// ... 建構子 ...
public function getSummaryLine() {
// 1. 取得父類核心摘要
$base = parent::getSummaryLine();
// 2. 追加子類特有資訊
$base .= ":頁數 - {$this->numPages} )";
return $base;
}
}
class CdProduct extends ShopProduct {
// ... 建構子 ...
public function getSummaryLine() {
$base = parent::getSummaryLine();
$base .= ":播放時間 - {$this->playLength} )";
return $base;
}
}
?>
| 技巧 | 說明 | 範例 |
|---|---|---|
| 建構子參數收集 | 子類建構子接收所有參數,透過 ...$args 傳遞給父類 | parent::__construct(...$args); (PHP 5.6+) |
| 避免破壞封裝 | 父類不應知道子類細節,違反依賴倒置原則 | 父類不包含 $numPages、$playLength |
| final 防止覆寫 | 核心邏輯禁止子類修改時使用 | final public function getPrice() |
| 介面替代繼承 | 需多型但無「是一種」關係時 | interface ProductInterface |
掌握 parent:: 的正確用法,是編寫健壯、可維護 PHP 物件導向程式碼的關鍵技能之一。