跳转到内容

PHP方法重写

来自代码酷

模板:Note

PHP方法重写[编辑 | 编辑源代码]

方法重写(Method Overriding)是PHP面向对象编程中实现多态性的核心技术之一,允许子类重新定义从父类继承的方法。当子类对象调用被重写的方法时,将执行子类中的版本而非父类版本。

基础概念[编辑 | 编辑源代码]

定义[编辑 | 编辑源代码]

方法重写发生在继承体系中,需满足以下条件:

  • 子类方法与父类方法名称完全相同
  • 子类方法的参数数量必须与父类一致(PHP 7.4+ 支持协变参数)
  • 访问修饰符的可见性不能降低(如父类为`protected`则子类不能改为`private`)

与重载的区别[编辑 | 编辑源代码]

方法重写 (Overriding) 方法重载 (Overloading)
发生在继承关系中 发生在同一类内
方法签名必须相同 方法名相同但参数不同
运行时多态 编译时多态(PHP通过魔术方法模拟)

基本语法[编辑 | 编辑源代码]

class ParentClass {
    public function showMessage() {
        echo "Parent message\n";
    }
}

class ChildClass extends ParentClass {
    // 重写父类方法
    public function showMessage() {
        echo "Child message\n";
        parent::showMessage(); // 可选:调用父类原始方法
    }
}

$obj = new ChildClass();
$obj->showMessage();

输出:

Child message
Parent message

高级特性[编辑 | 编辑源代码]

访问修饰符规则[编辑 | 编辑源代码]

  • 子类方法可以放宽但不能收紧访问限制:
    • 父类`protected` → 子类可改为`public`
    • 父类`public` → 子类不可改为`protected/private`

final 关键字[编辑 | 编辑源代码]

父类可禁止方法被重写:

class SecureClass {
    final public function criticalMethod() {
        // 此方法不能被子类重写
    }
}

构造方法重写[编辑 | 编辑源代码]

特殊场景下的注意事项:

class Parent {
    public function __construct($param) {
        echo "Parent constructor with $param\n";
    }
}

class Child extends Parent {
    public function __construct($param, $extra) {
        parent::__construct($param); // 必须显式调用父类构造方法
        echo "Child constructor with $extra\n";
    }
}

实际应用案例[编辑 | 编辑源代码]

支付系统示例[编辑 | 编辑源代码]

classDiagram class PaymentGateway { +processPayment() void } class CreditCardPayment { +processPayment() void } class PayPalPayment { +processPayment() void } PaymentGateway <|-- CreditCardPayment PaymentGateway <|-- PayPalPayment

abstract class PaymentGateway {
    abstract public function processPayment($amount);
}

class CreditCardPayment extends PaymentGateway {
    public function processPayment($amount) {
        // 信用卡特定处理逻辑
        return "Processing $$amount via Credit Card";
    }
}

class PayPalPayment extends PaymentGateway {
    public function processPayment($amount) {
        // PayPal特定处理逻辑
        return "Processing $$amount via PayPal";
    }
}

function checkout(PaymentGateway $gateway, $amount) {
    echo $gateway->processPayment($amount);
}

checkout(new CreditCardPayment(), 100);  // 输出信用卡处理
checkout(new PayPalPayment(), 50);       // 输出PayPal处理

常见问题[编辑 | 编辑源代码]

方法签名变更[编辑 | 编辑源代码]

PHP 7.4+ 支持协变返回类型逆变参数

interface Factory {
    public function make(): object;
}

class UserFactory implements Factory {
    public function make(): User; // 协变:返回更具体类型
}

静态方法重写[编辑 | 编辑源代码]

静态方法在PHP中不具有多态性

class A {
    public static function test() { echo "A"; }
}

class B extends A {
    public static function test() { echo "B"; }
}

A::test(); // 输出 A
B::test(); // 输出 B
$obj = new B();
$obj::test(); // 输出 B(但这不是真正的多态)

最佳实践[编辑 | 编辑源代码]

  1. 使用`@override`注解(IDE支持)提高可读性
  2. 重写方法时保持里氏替换原则(LSP)
  3. 复杂逻辑重写时调用`parent::method()`保留父类行为
  4. 对不应被重写的方法使用`final`修饰符

页面模块:Message box/ambox.css没有内容。

性能考量[编辑 | 编辑源代码]

方法重写会引入轻微的性能开销(约5-10%),因为:

  • 需要在运行时解析方法调用
  • 涉及虚方法表(vtable)查找
  • 但现代PHP版本(7.4+)已优化此过程

扩展阅读[编辑 | 编辑源代码]