PHP implements 关键字
最后修改于 2025 年 4 月 16 日
PHP implements
关键字用于在面向对象编程中实现接口。 它创建一个类必须遵循的契约。 接口定义方法签名,但不提供实现。 使用 implements
的类必须提供具体的方法实现。
基本定义
接口是实现类必须定义的方法的蓝图。 implements
关键字表明一个类将履行接口的契约。 接口可以包含方法签名和常量。
与类不同,接口不能包含属性定义或方法体。 接口中的所有方法都隐式为 public。 一个类可以实现多个接口,用逗号分隔。
语法:class ClassName implements InterfaceName { ... }
。 实现类必须定义接口中声明的所有方法。 否则会导致致命错误。
基本接口实现
此示例演示了一个带有一个方法的基本接口实现。
<?php 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("Error: File not found\n");
Logger
接口声明一个 log
方法。 FileLogger
类实现此接口并提供具体的方法。 该类必须与接口的方法签名完全匹配。
实现多个接口
此示例展示了一个类同时实现多个接口。
<?php interface Serializable { public function serialize(): string; } interface Renderable { public function render(): string; } class Widget implements Serializable, Renderable { private $data; public function __construct(array $data) { $this->data = $data; } public function serialize(): string { return json_encode($this->data); } public function render(): string { return implode(', ', $this->data); } } $widget = new Widget(['a', 'b', 'c']); echo $widget->serialize(); echo $widget->render();
Widget
Serializable 和 Renderable
接口。 它必须为两个接口中的所有方法提供实现。 多个接口用逗号分隔。
接口继承
此示例演示一个接口扩展另一个接口。
<?php interface Animal { public function eat(): void; } interface Mammal extends Animal { public function breathe(): void; } class Dog implements Mammal { public function eat(): void { echo "Dog is eating\n"; } public function breathe(): void { echo "Dog is breathing\n"; } } $dog = new Dog(); $dog->eat(); $dog->breathe();
Mammal
接口扩展 Animal
,继承其方法。 Dog
实现 Mammal
并且必须提供 eat
和 breathe
方法。 接口继承创建了契约的层次结构。
带有常量的接口
此示例展示了一个接口定义常量,实现类可以使用这些常量。
<?php interface HttpStatus { const OK = 200; const NOT_FOUND = 404; const SERVER_ERROR = 500; } class Response implements HttpStatus { public function send(int $code): void { if ($code === self::OK) { echo "Request successful"; } elseif ($code === self::NOT_FOUND) { echo "Resource not found"; } else { echo "Server error"; } } } $response = new Response(); $response->send(HttpStatus::OK);
HttpStatus
接口定义状态码常量。 Response
类实现该接口并使用 self::
访问常量。 接口常量始终是 public 并且不能被覆盖。
使用接口进行类型提示
此示例演示了在函数参数中使用接口进行类型提示。
<?php interface Cache { public function get(string $key): ?string; public function set(string $key, string $value): void; } class RedisCache implements Cache { public function get(string $key): ?string { // Simulate Redis get return "value_for_$key"; } public function set(string $key, string $value): void { // Simulate Redis set echo "Setting $key to $value\n"; } } function storeData(Cache $cache, string $key, string $value): void { $cache->set($key, $value); } $cache = new RedisCache(); storeData($cache, 'user1', 'John Doe');
storeData
函数接受任何实现 Cache
接口的对象。 这允许不同的缓存实现可以互换使用。 使用接口进行类型提示可以实现多态。
实现接口的抽象类
此示例展示了一个抽象类部分实现一个接口。
<?php interface Database { public function connect(): void; public function query(string $sql): array; public function disconnect(): void; } abstract class BaseDatabase implements Database { protected $connection; public function connect(): void { $this->connection = true; echo "Connected\n"; } abstract public function query(string $sql): array; public function disconnect(): void { $this->connection = false; echo "Disconnected\n"; } } class MySQLDatabase extends BaseDatabase { public function query(string $sql): array { echo "Executing: $sql\n"; return ['result1', 'result2']; } } $db = new MySQLDatabase(); $db->connect(); $db->query("SELECT * FROM users"); $db->disconnect();
BaseDatabase
抽象类实现了 Database
,但将 query
留为抽象。 具体类 MySQLDatabase
完成实现。 抽象类可以提供部分接口实现。
用于依赖注入的接口
此示例演示了使用接口进行依赖注入。
<?php interface PaymentGateway { public function charge(float $amount): bool; } class StripeGateway implements PaymentGateway { public function charge(float $amount): bool { echo "Charging \$$amount with Stripe\n"; return true; } } class PayPalGateway implements PaymentGateway { public function charge(float $amount): bool { echo "Charging \$$amount with PayPal\n"; return true; } } class OrderProcessor { private $gateway; public function __construct(PaymentGateway $gateway) { $this->gateway = $gateway; } public function process(float $amount): bool { return $this->gateway->charge($amount); } } $processor = new OrderProcessor(new StripeGateway()); $processor->process(100.50);
OrderProcessor
依赖于 PaymentGateway
接口,而不是具体的实现。 这使得可以轻松交换支付提供商。 接口可以在组件之间实现松耦合。
最佳实践
- 命名: 使用以 "able" 结尾的描述性名称(例如,Loggable)。
- 单一责任: 保持接口专注于一种能力。
- 文档: 清楚地记录接口的目的和用法。
- 分离: 遵循接口分离原则 (ISP)。
- 测试: 模拟接口以简化单元测试。
来源
本教程通过实际示例介绍了 PHP 接口实现,展示了 implements
关键字在各种情况下的用法。
作者
列出 所有 PHP 教程。