PHP 接口关键字
最后修改于 2025 年 4 月 16 日
PHP interface 关键字定义了类要实现的契约。接口指定了类必须实现哪些方法,而没有定义如何实现。它们实现了多态性并有助于创建松散耦合的系统。
基本定义
接口是实现类必须定义的方法的蓝图。它只包含方法签名,没有任何实现。接口中的所有方法都隐式为 public 和 abstract。
类使用 implements 关键字实现接口。一个类可以实现多个接口。接口可以使用 extends 关键字扩展其他接口。
语法:interface InterfaceName { public function methodName(); }。接口不能包含属性(常量除外)或方法体。
基本接口实现
此示例演示了一个简单的接口和一个实现它的类。
<?php
declare(strict_types=1);
interface Logger {
public function log(string $message): void;
}
class FileLogger implements Logger {
public function log(string $message): void {
file_put_contents('app.log', $message, FILE_APPEND);
}
}
$logger = new FileLogger();
$logger->log("User logged in\n");
Logger 接口定义了一个必须实现的方法。FileLogger 通过提供方法体来实现此接口。这确保了所有记录器都具有相同的基础功能。代码将消息写入日志文件。
多接口实现
此示例显示了一个类实现多个接口。
<?php
declare(strict_types=1);
interface Renderable {
public function render(): string;
}
interface Cacheable {
public function cache(): void;
}
class Page implements Renderable, Cacheable {
public function render(): string {
return "<h1>Welcome</h1>";
}
public function cache(): void {
echo "Page cached\n";
}
}
$page = new Page();
echo $page->render();
$page->cache();
Page 类实现了 Renderable 和 Cacheable 两个接口。它必须为两个接口中的所有方法提供实现。这允许对象具有多个角色。可以在任何需要其中一个接口的地方使用该类。
接口继承
此示例演示了一个接口扩展另一个接口。
<?php
declare(strict_types=1);
interface Vehicle {
public function start(): void;
public function stop(): void;
}
interface Car extends Vehicle {
public function accelerate(float $speed): void;
}
class Sedan implements Car {
public function start(): void {
echo "Engine started\n";
}
public function stop(): void {
echo "Engine stopped\n";
}
public function accelerate(float $speed): void {
echo "Accelerating to {$speed} km/h\n";
}
}
$sedan = new Sedan();
$sedan->start();
$sedan->accelerate(60);
$sedan->stop();
Car 接口扩展了 Vehicle,继承了它的方法。Sedan 必须实现这两个接口中的所有方法。这创建了一个契约的层次结构。该类为所有必需的方法提供了具体的实现。
接口常量
此示例展示了如何在接口中定义和使用常量。
<?php
declare(strict_types=1);
interface MathOperations {
const PI = 3.14159;
public function calculateArea(float $radius): float;
}
class Circle implements MathOperations {
public function calculateArea(float $radius): float {
return self::PI * $radius * $radius;
}
}
$circle = new Circle();
echo "Area: " . $circle->calculateArea(5);
接口可以包含实现类可以访问的常量。常量隐式为 public、static 和 final。Circle 类在其面积计算中使用 PI 常量。接口常量提供跨实现的共享值。
使用接口进行类型提示
此示例演示了使用接口进行类型提示。
<?php
declare(strict_types=1);
interface Notifier {
public function send(string $message): void;
}
class EmailNotifier implements Notifier {
public function send(string $message): void {
echo "Email sent: {$message}\n";
}
}
class NotificationService {
public function __construct(private Notifier $notifier) {}
public function notify(string $message): void {
$this->notifier->send($message);
}
}
$service = new NotificationService(new EmailNotifier());
$service->notify("Hello World");
NotificationService 接受任何 Notifier 实现。这允许灵活的依赖注入。服务不需要知道具体的通知器类。这促进了松散耦合和更轻松的测试。
接口 vs 抽象类
此示例比较了接口与抽象类。
<?php
declare(strict_types=1);
// Interface
interface Drawable {
public function draw(): void;
}
// Abstract class
abstract class Shape {
protected string $color;
public function __construct(string $color) {
$this->color = $color;
}
abstract public function getArea(): float;
}
// Concrete class implementing both
class Circle extends Shape implements Drawable {
private float $radius;
public function __construct(string $color, float $radius) {
parent::__construct($color);
$this->radius = $radius;
}
public function draw(): void {
echo "Drawing a {$this->color} circle\n";
}
public function getArea(): float {
return pi() * $this->radius * $this->radius;
}
}
$circle = new Circle("red", 5);
$circle->draw();
echo "Area: " . $circle->getArea();
接口定义契约,而抽象类可以提供部分实现。一个类可以扩展一个抽象类,但实现多个接口。Circle 继承自 Shape 并实现了 Drawable。这展示了如何结合这两种方法。
现代 PHP:接口特性
此示例演示了现代 PHP 接口特性。
<?php
declare(strict_types=1);
// Interface with return type declaration
interface Calculator {
public function add(float $a, float $b): float;
// Default implementation (PHP 8.0+)
public function subtract(float $a, float $b): float {
return $a - $b;
}
}
class BasicCalculator implements Calculator {
public function add(float $a, float $b): float {
return $a + $b;
}
}
$calc = new BasicCalculator();
echo "5 + 3 = " . $calc->add(5, 3) . "\n";
echo "5 - 3 = " . $calc->subtract(5, 3) . "\n";
PHP 8.0 引入了接口中的默认方法实现。该示例显示了返回类型声明和一个默认方法。类可以覆盖默认方法。这在接口设计中提供了更大的灵活性。BasicCalculator 仅实现了 add 方法。
最佳实践
- 单一职责: 保持接口专注于一个角色。
- 命名: 使用以“able”或“er”结尾的描述性名称。
- 方法数量: 优先使用具有少量方法的小型接口。
- 文档: 清楚地记录接口的目的和用法。
- 分离: 遵循接口隔离原则。
来源
本教程通过实际示例介绍了 PHP 接口,展示了基本用法、多重实现、继承和现代特性。
作者
列出 所有 PHP 教程。