php 多态实现
多态的基本概念
多态是面向对象编程的三大特性之一(封装、继承、多态),指同一操作作用于不同类的实例时,会产生不同的行为。PHP 中多态主要通过接口(interface)和抽象类(abstract class)实现,结合方法重写(override)或方法重载(overload,PHP 不支持)来体现。
通过接口实现多态
接口定义一组方法规范,不同类实现同一接口时需实现这些方法,从而通过接口类型调用不同类的具体实现。
interface Animal {
public function makeSound();
}
class Dog implements Animal {
public function makeSound() {
echo "Bark!";
}
}
class Cat implements Animal {
public function makeSound() {
echo "Meow!";
}
}
// 多态调用
function animalSound(Animal $animal) {
$animal->makeSound();
}
$dog = new Dog();
$cat = new Cat();
animalSound($dog); // 输出: Bark!
animalSound($cat); // 输出: Meow!
通过抽象类实现多态
抽象类可以包含抽象方法(未实现的方法)和具体方法,子类继承抽象类后必须实现抽象方法,从而实现多态。
abstract class Shape {
abstract public function area();
}
class Circle extends Shape {
private $radius;
public function __construct($radius) {
$this->radius = $radius;
}
public function area() {
return pi() * $this->radius * $this->radius;
}
}
class Square extends Shape {
private $side;
public function __construct($side) {
$this->side = $side;
}
public function area() {
return $this->side * $this->side;
}
}
// 多态调用
function printArea(Shape $shape) {
echo $shape->area();
}
$circle = new Circle(3);
$square = new Square(4);
printArea($circle); // 输出: 28.274...
printArea($square); // 输出: 16
通过 trait 实现多态(辅助方式)
Trait 是 PHP 5.4 引入的代码复用机制,可以用于横向扩展类的功能,但需结合接口或抽象类实现多态。
trait Loggable {
public function log($message) {
echo "Log: $message";
}
}
interface Logger {
public function log($message);
}
class FileLogger implements Logger {
use Loggable;
}
class DatabaseLogger implements Logger {
use Loggable;
}
// 多态调用
function logMessage(Logger $logger, $message) {
$logger->log($message);
}
$fileLogger = new FileLogger();
$dbLogger = new DatabaseLogger();
logMessage($fileLogger, "File log"); // 输出: Log: File log
logMessage($dbLogger, "DB log"); // 输出: Log: DB log
动态方法调用
PHP 的动态特性允许通过变量或字符串调用不同类的方法,间接实现多态。
class Calculator {
public function add($a, $b) {
return $a + $b;
}
public function subtract($a, $b) {
return $a - $b;
}
}
$calc = new Calculator();
$method = 'add';
echo $calc->$method(5, 3); // 输出: 8
$method = 'subtract';
echo $calc->$method(5, 3); // 输出: 2
注意事项
- 接口 vs 抽象类:接口用于定义行为规范,抽象类可包含部分实现。
- 类型提示:多态常依赖类型提示(如
Animal $animal)确保参数符合规范。 - 方法覆盖:子类必须实现接口或抽象类中定义的所有方法。
- 性能影响:多态会引入少量运行时开销,但通常可忽略。
通过合理使用接口、抽象类和继承,可以高效实现 PHP 的多态特性。







