实现接口
本课属于 Coddy PHP 学习旅程的“面向对象编程”单元。第 28 课,共 91 课。
现在你已经了解接口是什么,接下来看看如何实际实现接口。类使用 implements 关键字实现接口,并且必须为该接口中声明的所有方法提供具体实现。
<?php
interface Printable {
public function print();
}
class Document implements Printable {
private $content;
public function __construct($content) {
$this->content = $content;
}
public function print() {
return "Printing: " . $this->content;
}
}
$doc = new Document("Hello World");
echo $doc->print();
输出:
Printing: Hello WorldDocument 类通过提供自己的 print() 方法来实现 Printable。如果你忘记实现必需的方法,PHP 会抛出致命错误。
不同的类可以用各自的方式实现同一个接口:
<?php
class Invoice implements Printable {
private $amount;
public function __construct($amount) {
$this->amount = $amount;
}
public function print() {
return "Invoice Total: $" . $this->amount;
}
}
$invoice = new Invoice(150);
echo $invoice->print();
输出:
Invoice Total: $150Document 和 Invoice 都实现了 Printable 契约,但它们会根据各自的用途采用不同的打印方式。
要点:使用 implements 将类与接口连接起来,然后定义所有必需的方法。每个实现类都提供自己的逻辑,同时确保存在相同的方法签名。
挑战
简单我们来构建一个消息系统,演示不同的类如何以各自独特的方式实现同一个接口。
你将创建 3 个文件,它们协同处理不同类型的消息:
Messageable.php:定义Messageable接口,其中包含两个方法签名:compose($content)和deliver()。这个接口规定了所有消息类型都必须遵循的契约。Email.php:创建一个实现Messageable的Email类。在文件顶部引入接口文件。这个类应有一个私有的$recipient属性和一个私有的$body属性。构造函数接收收件人地址。实现compose($content),将内容存储在$body中并返回"Email composed"。实现deliver(),使其返回"Email to [recipient]: [body]"。SMS.php:创建一个同样实现Messageable的SMS类。在文件顶部引入接口文件。这个类应有一个私有的$phoneNumber属性和一个私有的$text属性。构造函数接收电话号码。实现compose($content),将内容存储在$text中并返回"SMS composed"。实现deliver(),使其返回"SMS to [phoneNumber]: [text]"。
在 main.php 中,同时引入 Email 和 SMS 文件。你将收到 3 项输入:电子邮件地址、电话号码和消息内容。使用电子邮件地址创建一个 Email 对象,并使用电话号码创建一个 SMS 对象。在两个对象上调用 compose(),参数为消息内容,并将每个结果分别打印在一行上。然后在两个对象上调用 deliver(),并将每个结果分别打印在一行上。顺序应为:Email compose、SMS compose、Email deliver、SMS deliver。
这两个类都遵循同一个 Messageable 契约,但会根据各自的用途处理消息的撰写和发送:电子邮件会显示收件人地址,而 SMS 消息会显示电话号码。
亲手试试
<?php
require_once 'Email.php';
require_once 'SMS.php';
// 读取输入
$emailAddress = trim(fgets(STDIN));
$phoneNumber = trim(fgets(STDIN));
$messageContent = trim(fgets(STDIN));
// TODO:用电子邮件地址创建一个 Email 对象
// TODO:用电话号码创建一个 SMS 对象
// TODO:对两个对象调用 compose() 并打印结果
// 顺序:先调用 Email 的 compose(),再调用 SMS 的 compose()
// TODO:对两个对象调用 deliver() 并打印结果
// 顺序:先调用 Email 的 deliver(),再调用 SMS 的 deliver()
?>这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: PHP 在线编译器