Table of Contents
PHP Abstract Class 是物件導向的重要概念,目的是抽象化設計,讓程式更靈活,也是應用設計模式很重要的實作方式。
什麼是 PHP Class
在 PHP 中,Class 是一種用來封裝相關函數和變數的藍圖或模板。當你需要創建多個具有相同特性和行為的對象時,使用 Class 非常有用。
Class 實現了物件導向三要素~
封裝(Encapsulation):
Class 可以將數據(變數)和行為(函數)封裝在一起。
繼承(Inheritance):
一個 Class 可以繼承另一個 Class。
多型(Polymorphism):
通過繼承 (Inheritance) 和介面 (Interface),不同的 Class 可以定義相同的方法。
程式範例
<?php
// 定義一個名為 "Animal" 的 Class
class Animal {
// 定義一個變數
public $name;
// 定義一個函數
public function makeSound() {
echo "Some generic animal sound";
}
}
// 創建一個 Animal 對象
$animal = new Animal();
$animal->name = "Dog";
$animal->makeSound(); // 輸出 "Some generic animal sound"
?>在這個範例中,我們定義了一個名為 Animal 的 Class,並在其中加入了一個變數 $name 和一個函數 makeSound()。然後,我們創建了一個 Animal 的實例(或對象)並設定其名稱和行為。
這是一個非常精簡的 Class 範例,更多 Class 說明介紹,請參考:PHP 物件導向的基礎,從類別 (Class) 與物件 (Object) 開始
什麼是 PHP Abstract Class
Abstract Class 是一種不能被實例化(不能創建對象)的 Class。它通常包含一個或多個抽象方法,這些方法僅有聲明而無實現。
當你有一些通用的方法,但不希望該 Class 被直接實例化時,應使用 Abstract Class。
程式範例
<?php
// 定義一個名為 "Animal" 的 Abstract Class
abstract class Animal {
// 定義一個抽象方法
abstract public function makeSound();
// 定義一個普通方法
public function run() {
echo "Running";
}
}
// 定義一個繼承自 Animal 的 Class
class Dog extends Animal {
public function makeSound() {
echo "Woof";
}
}
// 創建一個 Dog 對象
$dog = new Dog();
$dog->makeSound(); // 輸出 "Woof"
$dog->run(); // 輸出 "Running"
?>在這個範例中,我們定義了一個名為 Animal 的 Abstract Class,並在其中定義了一個抽象方法 makeSound() 和一個普通方法 run()。然後,我們創建了一個繼承自 Animal 的 Dog Class,並實現了 makeSound() 方法。
Class 與 Abstract Class 的差異
不同之處
- Class 可以被實例化,而 Abstract Class 不可以。
- Abstract Class 可以包含抽象方法,但 Class 不可以。
如何互動合作
通常,Abstract Class 作為基礎 Class,其他 Class 可以繼承它並實現其抽象方法。
程式範例
<?php
// 定義一個名為 "Animal" 的 Abstract Class
abstract class Animal {
abstract public function makeSound();
}
// 定義一個繼承自 Animal 的 Class
class Dog extends Animal {
public function makeSound() {
echo "Woof";
}
}
// 定義另一個繼承自 Animal 的 Class
class Cat extends Animal {
public function makeSound() {
echo "Meow";
}
}
// 創建對象
$dog = new Dog();
$cat = new Cat();
// 輸出
$dog->makeSound(); // Woof
$cat->makeSound(); // Meow
?>
為什麼這樣設計?
抽象基類(Abstract Base Class): Animal 作為一個抽象基類,定義了所有動物都應該有的基本行為,例如 makeSound()。
具體子類(Concrete Subclasses): Dog 和 Cat 是 Animal 的具體子類,它們繼承了 Animal 的特性並提供了 makeSound() 方法的具體實現。
方法覆寫(Method Overriding): 在 Dog 和 Cat 類中,我們覆寫了 makeSound() 方法,以提供各自特有的行為。
好處是什麼?
代碼重用(Code Reusability): 通過使用繼承,Dog 和 Cat 類可以重用 Animal 類中的代碼。這減少了重複代碼,使得代碼更為簡潔。
可維護性(Maintainability): 如果未來需要更改動物的共同行為,只需要在 Animal 類中進行更改,而不需要在每一個子類中單獨修改。
可擴展性(Extensibility): 如果未來需要添加更多種動物,只需要繼承 Animal 類並提供新的 makeSound() 實現。這樣可以輕鬆地擴展程式。
多型(Polymorphism): 由於 Dog 和 Cat 都是 Animal 類型,我們可以使用多型來處理各種不同的動物,而不需要知道它們的具體類型。
高度抽象(High Abstraction): 使用 Abstract Class,我們可以定義一個高度抽象的框架,這有助於理解各個類之間的關係,並強制子類實現某些方法。
進階 Abstract Class 範例
<?php
// 定義一個名為 "Vehicle" 的 Abstract Class
abstract class Vehicle {
public $speed;
// 定義一個抽象方法
abstract public function move();
// 定義一個普通方法
public function setSpeed($speed) {
$this->speed = $speed;
}
}
// 定義一個繼承自 Vehicle 的 Abstract Class
abstract class LandVehicle extends Vehicle {
public $wheels;
// 覆寫 move 方法
public function move() {
echo "Moving on land at speed " . $this->speed;
}
// 定義一個新的抽象方法
abstract public function honk();
}
// 定義一個繼承自 LandVehicle 的 Class
class Car extends LandVehicle {
public $brand;
// 實現 honk 方法
public function honk() {
echo "Honking";
}
}
// 創建一個 Car 對象
$car = new Car();
$car->setSpeed(100); // 設定速度
$car->move(); // 輸出 "Moving on land at speed 100"
$car->honk(); // 輸出 "Honking"
?>在這個範例中,我們首先定義了一個名為 Vehicle 的 Abstract Class,其中包含一個抽象方法 move() 和一個普通方法 setSpeed()。
然後,我們定義了一個繼承自 Vehicle 的 Abstract Class LandVehicle。在這個 Class 中,我們覆寫了 move() 方法並添加了一個新的抽象方法 honk()。
最後,我們定義了一個繼承自 LandVehicle 的 Class Car,並實現了 honk() 方法。
這個範例展示了如何在多層繼承中使用 Abstract Class,以及如何覆寫和實現抽象方法。

為什麼這樣設計?
多層繼承(Multi-level Inheritance): 在這個範例中,我們有一個 Vehicle Abstract Class,以及一個繼承自 Vehicle 的 LandVehicle Abstract Class。這種多層繼承允許我們更細緻地組織代碼。
方法覆寫(Method Overriding): LandVehicle Class 覆寫了 Vehicle Class 中的 move() 方法。這樣做是為了提供更具體的實現。
抽象與具體方法(Abstract and Concrete Methods): Vehicle 和 LandVehicle 都有抽象方法(需要子類實現的方法),但也有具體方法(已經實現的方法)。這提供了一個平衡,使得 Class 既靈活又具有一定的結構。
有什麼好處?
代碼重用(Code Reusability): 通過繼承,我們可以重用 Vehicle 和 LandVehicle 中的代碼,這減少了重複代碼。
可維護性(Maintainability): 使用 Abstract Class 和多層繼承使得代碼更容易維護。如果需要更改移動的方式,我們只需要在一個地方(如 Vehicle 或 LandVehicle)進行更改。
可擴展性(Extensibility): 如果未來需要添加更多種交通工具(如 AirVehicle、WaterVehicle 等),這種設計使得擴展變得非常容易。
結構清晰(Clear Structure): 這種多層繼承和方法覆寫的結構使得代碼更加組織化,更容易理解。
高度抽象(High Abstraction): 通過使用 Abstract Class,我們定義了一個高度抽象的框架,這有助於理解各個 Class 之間的關係。
實現細節隱藏(Implementation Hiding): Abstract Class 提供了一個界面,但隱藏了實現的細節。這有助於封裝和資訊隱藏。
參考文章:
- Class Abstraction
- Abstract Class – guide you on abstract classes and how to use them effectively.






