PHP 面向對象程式設計(OOP)是構建可維護、可擴充大型應用的基石。本文系統梳理 PHP OOP 核心知識點,涵蓋類繼承、可見性控制、靜態綁定、魔術方法、建構子/解構子、final 關鍵字、介面契約、屬性重載、對象克隆等進階特性,並附帶可直接運行的代碼範例。
使用 extends 關鍵字實現繼承。子類自動擁有父類的 public 與 protected 成員,可新增或覆蓋(重載)同名方法。
<?php
class A {
public function foo() { echo "A::foo\n"; }
protected function bar() { echo "A::bar\n"; }
private function baz() { echo "A::baz\n"; } // 子類不可見
}
class B extends A {
public function foo() { echo "B::foo\n"; } // 重載
public function test() {
$this->foo(); // B::foo
$this->bar(); // A::bar (受保護可繼承)
// $this->baz(); // Fatal Error: 私有不可訪問
}
}
$b = new B();
$b->foo(); // B::foo
$b->test();
?>
| 修飾符 | 類內部 | 子類 | 外部代碼 |
|---|---|---|---|
| public | ✅ | ✅ | ✅ |
| protected | ✅ | ✅ | ❌ |
| private | ✅ | ❌ | ❌ |
最佳實踐:屬性預設 private,透過 getter/setter 或魔術方法 __get/__set 控制存取;需子類覆蓋的方法用 protected。
:: 作用域解析操作符用於存取靜態成員、類常量、覆蓋父類方法、延遲靜態綁定。
<?php
class MyClass {
const CONST_VALUE = '常量值';
public static $staticVar = '靜態屬性';
public static function staticMethod() { echo "靜態方法\n"; }
}
echo MyClass::CONST_VALUE; // 常量
echo MyClass::$staticVar; // 靜態屬性
MyClass::staticMethod(); // 靜態方法
// 子類覆蓋父類並調用父實現
class ParentClass {
protected function greet() { echo "Parent\n"; }
}
class ChildClass extends ParentClass {
public function greet() {
parent::greet(); // 調用父類實現
echo "Child\n";
}
}
(new ChildClass())->greet();
?>
$this、self、parent 三者區別| 關鍵字 | 指向 | 可存取 | 典型用途 |
|---|---|---|---|
| $this | 當前對象實例 | 實例屬性/方法 | 非靜態上下文 |
| self | 當前類(編譯期綁定) | 靜態成員、常量 | 類內部調用靜態成員 |
| parent | 父類 | 父類靜態/受保護成員 | 調用父類建構子、被覆蓋方法 |
<?php
class Counter {
private static $count = 0;
private $id;
public function __construct() {
$this->id = ++self::$count; // self:: 存取靜態屬性
}
public function getId() { return $this->id; }
}
class SubCounter extends Counter {
public function __construct() {
parent::__construct(); // 必須顯式調用父建構子
}
}
?>
__construct 與解構子 __destructparent::__construct()。exit()/die() 會觸發解構子,但在解構子中再次調用 exit() 會中止後續關閉操作。final 關鍵字final 修飾方法 → 禁止子類覆蓋final 修飾類 → 禁止被繼承<?php
final class SecurityUtils {
public static function hash($data) { return hash('sha256', $data); }
}
// class Hack extends SecurityUtils {} // Fatal Error
?>
interface:定義行為契約public abstractimplements 多個介面,方法名不可重複extends 多個父介面<?php
interface iTemplate {
public function setVariable($name, $var);
public function getHtml($template);
}
class Template implements iTemplate {
private $vars = [];
public function setVariable($name, $var) { $this->vars[$name] = $var; }
public function getHtml($template) {
foreach ($this->vars as $k => $v) {
$template = str_replace('{'.$k.'}', $v, $template);
}
return $template;
}
}
?>
__get、__set、__isset、__unset當存取 不可見(不存在、private、protected)屬性時自動觸發。注意:這些魔術方法必須聲明為 public,否則外部調用會報錯。
<?php
class Person {
private $data = [];
public function __set($name, $value) { $this->data[$name] = $value; }
public function __get($name) { return $this->data[$name] ?? null; }
public function __isset($name) { return isset($this->data[$name]); }
public function __unset($name) { unset($this->data[$name]); }
}
$p = new Person();
$p->name = '張三'; // 觸發 __set
echo $p->name; // 觸發 __get → 張三
var_dump(isset($p->name)); // 觸發 __isset → true
unset($p->name); // 觸發 __unset
echo $p->name; // null
?>
clone 與 __clone()__clone() 可在克隆後執行深拷貝邏輯<?php
class Address { public $city; }
class User {
public $name;
public $address;
public function __clone() {
$this->address = clone $this->address; // 深拷貝地址對象
}
}
$u1 = new User();
$u1->name = 'A';
$u1->address = new Address();
$u1->address->city = '北京';
$u2 = clone $u1;
$u2->address->city = '上海';
echo $u1->address->city; // 北京(深拷貝生效)
?>
| 模式 | PHP 關鍵實現 | 適用場景 |
|---|---|---|
| 單例 | private __construct + static getInstance() | 資料庫連線、配置管理 |
| 工廠 | static create() 返回介面實現 | 多驅動切換(快取、日志、支付) |
| 觀察者 | SplObserver / SplSubject | 事件系統、解耦業務邏輯 |
| 策略 | 介面 + 多實現 + 上下文注入 | 演算法熱插拔(排序、壓縮、加密) |
掌握 PHP OOP 核心機制,能寫出高內聚、低耦合、易測試的代碼。建議:
private 封裝狀態,暴露語意化介面