PHP abstract 关键字
最后修改于 2025 年 4 月 16 日
PHP 的 abstract 关键字用于在面向对象编程中创建抽象类和抽象方法。抽象类不能被直接实例化。它们充当基类,其他类可以继承它们。
基本定义
抽象类 是至少包含一个抽象方法的类。抽象类为其子类提供了一个通用的接口。
抽象方法 是一个未实现的方法声明。它只定义了方法的签名。具体的子类必须实现所有抽象方法。
abstract 关键字强制执行派生类必须遵循的契约。这是 PHP OOP 中多态和继承的关键概念。
基本抽象类
此示例演示了 PHP 中抽象类的最简单形式。
<?php
abstract class Animal {
abstract public function makeSound();
}
class Dog extends Animal {
public function makeSound() {
echo "Bark";
}
}
$dog = new Dog();
$dog->makeSound();
Animal 类被声明为抽象类,并包含一个抽象方法。Dog 继承 Animal 并实现了 makeSound。尝试直接实例化 Animal 会导致错误。
带具体方法的抽象类
此示例展示了一个同时包含抽象方法和具体方法的抽象类。
<?php
abstract class Shape {
abstract public function area();
public function description() {
return "This is a shape.";
}
}
class Square extends Shape {
private $side;
public function __construct($side) {
$this->side = $side;
}
public function area() {
return $this->side * $this->side;
}
}
$square = new Square(5);
echo $square->area();
echo $square->description();
Shape 有一个抽象的 area 方法和一个具体的 description 方法。Square 实现 area 但继承 description。抽象类可以混合使用方法类型。
多个抽象方法
此示例演示了一个具有多个抽象方法的抽象类。
<?php
abstract class Database {
abstract public function connect();
abstract public function query($sql);
abstract public function disconnect();
}
class MySQL extends Database {
public function connect() {
echo "Connecting to MySQL...";
}
public function query($sql) {
echo "Executing: $sql";
}
public function disconnect() {
echo "Disconnecting from MySQL...";
}
}
$db = new MySQL();
$db->connect();
$db->query("SELECT * FROM users");
$db->disconnect();
Database 抽象类定义了三个抽象方法。MySQL 必须实现所有这些方法。这确保了不同数据库实现之间接口的一致性。
带属性的抽象类
此示例展示了一个带有属性和抽象方法的抽象类。
<?php
abstract class Vehicle {
protected $speed;
abstract public function accelerate();
public function getSpeed() {
return $this->speed;
}
}
class Car extends Vehicle {
public function accelerate() {
$this->speed += 10;
}
}
$car = new Car();
$car->accelerate();
echo $car->getSpeed();
Vehicle 有一个受保护的属性 $speed 和一个抽象方法。Car 实现 accelerate 并可以访问继承的属性。抽象类可以包含属性和具体方法。
抽象类继承
此示例演示了一个继承另一个抽象类的抽象类。
<?php
abstract class A {
abstract public function methodA();
}
abstract class B extends A {
abstract public function methodB();
}
class C extends B {
public function methodA() {
echo "Method A implementation";
}
public function methodB() {
echo "Method B implementation";
}
}
$obj = new C();
$obj->methodA();
$obj->methodB();
B 继承 A 并添加了另一个抽象方法。C 必须实现来自两个类的所有抽象方法。抽象类可以像具体类一样形成继承层次结构。
带构造函数的抽象类
此示例显示了一个带有构造函数方法的抽象类。
<?php
abstract class Person {
protected $name;
public function __construct($name) {
$this->name = $name;
}
abstract public function greet();
}
class Student extends Person {
public function greet() {
return "Hello, I'm student {$this->name}";
}
}
$student = new Student("Alice");
echo $student->greet();
Person 有一个具体的构造函数,用于设置 $name 属性。Student 调用父构造函数并实现 greet。抽象类可以像普通类一样拥有构造函数。
最终抽象方法
此示例演示了在方法中组合 abstract 和 final 关键字。
<?php
abstract class Template {
final public function templateMethod() {
$this->stepOne();
$this->stepTwo();
}
abstract protected function stepOne();
abstract protected function stepTwo();
}
class Implementation extends Template {
protected function stepOne() {
echo "Step 1 completed";
}
protected function stepTwo() {
echo "Step 2 completed";
}
}
$impl = new Implementation();
$impl->templateMethod();
templateMethod 是最终的,并定义了一个算法结构。抽象方法 stepOne 和 stepTwo 必须由子类实现。这就是模板方法设计模式。
最佳实践
- 目的:使用抽象类来定义通用接口。
- 实现:所有抽象方法都必须被实现。
- 设计:当需要共享代码时,优先使用抽象类。
- 命名:使用清晰的名称来指示抽象性质。
- 文档:记录抽象方法预期的行为。
来源
本教程通过各种场景下 abstract 关键字使用的实际示例,涵盖了 PHP 抽象类和抽象方法。
作者
列出 所有 PHP 教程。