[TOC] #### 1. 多态的理解 --- PHP 中的多态是面向对象编程(OOP)的核心特性之一 简单来说,它指的是同一个方法调用,在不同的对象上可以表现出不同的行为,极大的提高了代码的灵活性和可扩展性 多态的字面意思就是 “多种形态”,在面向对象编程中,可以通过以下几种方式理解多态: + 同一个方法,不同的对象执行不同的行为 + 允许程序在运行时选择具体的方法实现 + 在父类中定义统一接口(方法),让子类提供具体的实现 #### 2. 多态的实现 --- 在 PHP 中,多态主要通过继承和接口两种方式实现: + 方法重写:子类重新定义父类的某个方法,此时子类的方法会覆盖父类的方法 + 接口和抽象类:通过实现接口或继承抽象类,子类可以定义具体的行为,保持统一的调用接口 ##### 通过继承实现 在这个例子中,`makeSound` 函数不关心传入的是 `Cat` 还是 `Dog`,它只知道传入的是一个 `Animal` 当调用 `$animal->speak();` 时,PHP 会在运行时根据对象的真实类型来决定执行哪个 `speak()` 方法 ```php // 父类 class Animal { public function speak() { echo '动物发出声音'; } } // 子类 Cat class Cat extends Animal { public function speak() { echo "猫:喵喵喵\n"; } } // 子类 Dog class Dog extends Animal { public function speak() { echo "狗:汪汪汪\n"; } } // 多态的体现 // 参数类型提示为父类 Animal function makeSound(Animal $animal) { $animal->speak(); // 调用哪个 speak() 方法,取决于传入的实际对象 } makeSound(new Cat()); // 猫:喵喵喵 makeSound(new Dog()); // 狗:汪汪汪 ``` ##### 通过接口实现 实现接口的类都必须提供接口方法的具体实现,这使得完全不相关的类也可以通过实现同一个类来表现出多态性 ```php // 1. 定义一个接口 interface Shape { public function calculateArea(); } // 2. 创建类实现接口 Shape class Circle implements Shape { private $radius; public function __construct($radius) { $this->radius = $radius; } public function calculateArea() { return pi() * $this->radius * $this->radius; } } // 3. 创建类实现接口 Shape class Rectangle implements Shape { private $width, $height; public function __construct($width, $height) { $this->width = $width; $this->height = $height; } public function calculateArea() { return $this->width * $this->height; } } // 4. 使用多态 function printArea(Shape $shape) { echo "面积是: " . $shape->calculateArea() . "\n"; } printArea(new Circle(5)); // 计算圆形的面积 printArea(new Rectangle(4, 6)); // 计算矩形的面积 ``` ##### 通过抽象类实现 抽象类也能实现多态,与接口的不同之处在于,抽象类可以提供部分方法的实现,或者只作为一种规范来约束子类 ```php // 定义一个抽象类 Animal abstract class Animal { abstract public function sound(); // 具体方法的实现(抽象类可以有,但是接口不行) public function say() {} } // 类 Dog 继承自 Animal class Dog extends Animal { public function sound() { return "Woof!"; } } // 类 Cat 继承自 Animal class Cat extends Animal { public function sound() { return "Meow!"; } } // 多态的体现 function makeSound(Animal $animal) { echo $animal->sound() . "\n"; } $dog = new Dog(); $cat = new Cat(); makeSound($dog); // 输出: Woof! makeSound($cat); // 输出: Meow! ``` #### 3. 多态的好处 --- PHP 中的多态通过方法的重写、接口和抽象类等机制,使程序在执行时能够根据实际的对象类型决定调用哪个方法,从而实现灵活和可扩展的代码结构 + 灵活性:可以通过父类或接口定义统一的接口,然后不同的子类提供不同的实现 + 扩展性:如果需要扩展新的子类,只需确保新类实现了接口或继承了父类 + 代码复用:可以编写通用的函数来处理同一父类或同一接口的所有对象,避免了代码重复 多态只对 `$this->method()` 这样的调用生效,因为它是运行时动态绑定的,而 `self::method()` 是编译期静态绑定的,它始终指向定义该代码的类,不会根据对象的实际类型改变 ```php class ParentClass { public function test() { $this->whoAmI(); // 动态绑定,调用子类的方法 self::whoAmI(); // 静态绑定,调用 ParentClass 的方法 } public function whoAmI() { echo "我是父类\n"; } } class ChildClass extends ParentClass { public function whoAmI() { echo "我是子类\n"; } } $obj = new ChildClass(); $obj->test(); // 输出: // 我是子类 // 我是父类 ```