抽象類別是物件導向設計中「定義契約、延遲實作」的關鍵工具。它無法被實例化,僅能被繼承,強制子類別實作特定方法,確保介面一致性。本文詳細說明語法規則、可見性限制、建構子傳遞與實戰範例。
<?php
abstract class Shape {
// 抽象方法:只有宣告,沒有大括號與實作
abstract protected function getArea();
// 一般方法:可提供預設實作,子類別可選擇覆寫
public function getDescription() {
return "這是一個幾何形狀";
}
}
// 錯誤示範:無法實例化抽象類別
// $shape = new Shape(); // Fatal error: Cannot instantiate abstract class
?>
abstract 方法,整個類別就必須標記為 abstract。{ }。protected → 子類別可為 protected 或 public,不可為 private。<?php
abstract class Shape {
abstract protected function getArea(); // 強制子類實作
// 範本方法:定義演算法骨架
public function printInfo() {
echo "面積:" . $this->getArea() . " | 描述:" . $this->getDescription() . "\n";
}
// 提供預設實作,子類可選擇覆寫
protected function getDescription() {
return "未知形狀";
}
}
class Rectangle extends Shape {
private $width;
private $height;
public function __construct($width, $height) {
$this->width = $width;
$this->height = $height;
}
// 實作抽象方法,可見性提升為 public
public function getArea() {
return $this->width * $this->height; // 修正原文錯誤:周長公式 → 面積公式
}
// 覆寫預設方法
protected function getDescription() {
return "矩形 (寬:{$this->width}, 高:{$this->height})";
}
}
class Circle extends Shape {
private $radius;
public function __construct($radius) {
$this->radius = $radius;
}
public function getArea() {
return pi() * $this->radius ** 2;
}
protected function getDescription() {
return "圓形 (半徑:{$this->radius})";
}
}
// 使用
$shapes = [new Rectangle(10, 5), new Circle(3)];
foreach ($shapes as $shape) {
$shape->printInfo(); // 多型呼叫
}
// 輸出:
// 面積:50 | 描述:矩形 (寬:10, 高:5)
// 面積:28.274... | 描述:圓形 (半徑:3)
?>
| 特性 | 抽象類別 | 介面 |
|---|---|---|
| 關鍵字 | abstract class | interface |
| 方法實作 | 可包含具體方法 | 全為抽象方法 (PHP 8.0 前) |
| 屬性 | 可定義屬性、常數 | 僅常數 |
| 建構子 | 可定義 __construct | 不可 |
| 繼承關係 | 單一繼承 extends | 多重實作 implements |
| 適用場景 | 「是一種」關係,共享程式碼 | 「能做什麼」契約,跨類別復用 |
final public function template()),子類別實作抽象步驟。abstract protected function createProduct(),子類別決定具體產品類別。abstract。parent::__construct(...) 以完成父類別初始化。interface;需要共享程式碼、狀態時才用抽象類別。extends 一個父類別,但可 implements 多個介面 → 「單一繼承、多重介面」。