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

PHP 進階 OOP 特性詳解:抽象類、介面、Final、類別常數與設計選型指南

     編輯:PHP 綜合知識

前言

PHP 5 建立完整物件模型,PHP 7/8 持續強化型別系統與介面能力。本文深度解析抽象類、介面、Final 關鍵字、類別常數四大進階特性,提供語法細節、設計模式應用與選型決策指南。

一、抽象類

定義與規則

  • abstract class ClassName { ... }
  • 不可實例化:new AbstractClass() 致命錯誤。
  • 可包含抽象方法(abstract public function name();)與具體方法。
  • 抽象方法不能有方法體(連大括號都不能有)。
  • 包含抽象方法的類別必須宣告為 abstract。
  • 子類別必須實作所有抽象方法,除非子類別也宣告為 abstract。

程式碼範例

<?php
abstract class Animal {
    public $name;
    public $age;
    abstract public function cry(); // 強制子類別實作
    public function getName() { return $this->name; } // 具體方法可直接繼承
}

class Cat extends Animal {
    public function cry() { echo 'Meow~'; }
}

$cat = new Cat();
$cat->name = 'Kitty';
$cat->cry(); // Meow~

適用場景

  • 提供基礎實作(共用屬性、工具方法)給子類別。
  • 定義演算法骨架(Template Method 模式),延遲關鍵步驟至子類別。
  • 狀態機、策略模式基類。

二、介面

定義與規則

  • interface InterfaceName { ... }
  • 完全抽象:PHP 8.0 前所有方法隱含 public abstract,不可有方法體;PHP 8.0+ 允許 private 方法與靜態方法體。
  • 可定義常數(const),不可定義屬性。
  • 類別用 implements 實作,必須實作所有方法。
  • 支援多重實作:class A implements I1, I2 {}。
  • 介面可繼承介面:interface C extends A, B {}。
  • 類別可同時繼承父類別並實作介面:class C extends Base implements I1, I2 {}。

程式碼範例

<?php
interface iUsb {
    public function start();
    public function stop();
    const VERSION = '2.0';
}

class Camera implements iUsb {
    public function start() { echo 'Camera Start'; }
    public function stop() { echo 'Camera Stop'; }
}

class Phone implements iUsb {
    public function start() { echo 'Phone Start'; }
    public function stop() { echo 'Phone Stop'; }
}

// 依賴介面程式設計
function connect(iUsb $device) {
    $device->start();
}
connect(new Camera());
connect(new Phone());

介面 vs 抽象類 選型決策表

需求選擇理由
需要共享程式碼/屬性/建構子抽象類介面無狀態、無建構子
定義「是什麼」能力契約介面多型核心、解耦
類別已有父類別介面單一繼承限制
需要預設方法實作(PHP 8.0+)介面可定義 private/static 方法體
標記/標識用途(Marker Interface)介面如 Serializable, JsonSerializable

三、Final 關鍵字

三大用途

  1. Final 類別:final class SecurityManager {} → 禁止繼承,常用於工具類、單例、不可變值物件。
  2. Final 方法:final public function calculateTax(): float {} → 禁止覆寫,但可繼承呼叫。保護核心演算法不被修改。
  3. 不可修飾屬性:屬性用 readonly(PHP 8.1+)實現不可變。

程式碼範例

<?php
class TaxCalculator {
    final public function getRate(float $salary): float {
        return $salary * 0.08; // 稅率邏輯鎖死
    }
}

class RegionalTaxCalculator extends TaxCalculator {
    // 錯誤:Cannot override final method
    // public function getRate(float $salary): float { return $salary * 0.01; }
}

四、類別常數

定義與存取

<?php
class Config {
    const TAX_RATE = 0.08;
    const MAX_RETRY = 3;
    public function calculateTax(float $income): float {
        return $income * self::TAX_RATE; // 內部存取
    }
}

echo Config::TAX_RATE;     // 外部存取:類別名::常數名
echo Config::MAX_RETRY;
$obj = new Config();
echo $obj::TAX_RATE;       // 物件也可存取(PHP 5.3+)

特性

  • 慣例全大寫、底線分隔,無 $ 符號。
  • 不可修改(定義時必須賦值)。
  • 不屬於物件,屬於類別(靜態綁定)。
  • 可被子類別繼承(子類別可覆蓋重新定義)。
  • 介面中只能定義常數,預設 public。

五、綜合實戰:支付策略模式

<?php
// 1. 介面定義契約
interface PaymentGateway {
    public function charge(float $amount, string $currency): PaymentResult;
    public function refund(string $transactionId): RefundResult;
}

// 2. 抽象基類提供共用邏輯
abstract class BaseGateway implements PaymentGateway {
    protected string $merchantId;
    protected string $apiKey;
    public function __construct(string $merchantId, string $apiKey) {
        $this->merchantId = $merchantId;
        $this->apiKey = $apiKey;
    }
    protected function sign(array $params): string { /* 簽名邏輯 */ }
    protected function request(string $endpoint, array $data): array { /* HTTP 客戶端 */ }
}

// 3. 具體實作
final class StripeGateway extends BaseGateway {
    public function charge(float $amount, string $currency): PaymentResult {
        $response = $this->request('/charges', [
            'amount' => $amount * 100,
            'currency' => $currency,
        ]);
        return new PaymentResult($response['id'], $response['status']);
    }
    public function refund(string $transactionId): RefundResult { /* ... */ }
}

final class PayPalGateway extends BaseGateway { /* ... */ }

// 4. 工廠根據配置建立實例
class GatewayFactory {
    public static function create(string $type): PaymentGateway {
        return match ($type) {
            'stripe' => new StripeGateway(config('stripe.id'), config('stripe.key')),
            'paypal' => new PayPalGateway(config('paypal.id'), config('paypal.key')),
            default => throw new InvalidArgumentException("Unknown gateway: $type"),
        };
    }
}

// 5. 使用
$gateway = GatewayFactory::create('stripe');
$result = $gateway->charge(99.00, 'USD');

六、最佳實踐總結

  1. 介面優先:定義服務契約用介面,實作細節用 final 類別。
  2. 抽象類承載共用邏輯:避免重複程式碼,提供 Template Method 骨架。
  3. Final 保護核心邏輯:演算法、安全檢查、第三方整合細節標記 final。
  4. 常數集中管理配置:業務規則常數(稅率、重試次數、分頁大小)定義為類別常數。
  5. 依賴倒置:高層模組依賴介面,具體實作由工廠/容器注入。
  6. PHP 8.0+ 新語法:readonly 屬性、match 表達式、介面預設方法、::class 常數,善用現代特性簡化程式碼。

靈活運用抽象類、介面、Final 與常數,能構建高內聚、低耦合、易測試、易擴充的 PHP 企業級架構。

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