PHP方法重写
外观
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";
}
}
实际应用案例[编辑 | 编辑源代码]
支付系统示例[编辑 | 编辑源代码]
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(但这不是真正的多态)
最佳实践[编辑 | 编辑源代码]
- 使用`@override`注解(IDE支持)提高可读性
- 重写方法时保持里氏替换原则(LSP)
- 复杂逻辑重写时调用`parent::method()`保留父类行为
- 对不应被重写的方法使用`final`修饰符
页面模块:Message box/ambox.css没有内容。
过度使用方法重写会导致代码难以维护,建议优先使用组合模式 |
性能考量[编辑 | 编辑源代码]
方法重写会引入轻微的性能开销(约5-10%),因为:
- 需要在运行时解析方法调用
- 涉及虚方法表(vtable)查找
- 但现代PHP版本(7.4+)已优化此过程
扩展阅读[编辑 | 编辑源代码]
- PHP类型声明(协变/逆变)
- PHP抽象类与接口
- 设计模式中的模板方法模式