实现多个接口
本课属于 Coddy PHP 学习旅程的“面向对象编程”单元。第 29 课,共 91 课。
与一个类只能继承一个父类的继承方式不同,PHP 允许一个类实现多个接口。这样你就可以灵活地组合不同的契约,让类的用途更加广泛。
要实现多个接口,请在 implements 关键字后用逗号分隔它们:
<?php
interface Printable {
public function print();
}
interface Savable {
public function save();
}
class Report implements Printable, Savable {
private $title;
public function __construct($title) {
$this->title = $title;
}
public function print() {
return "Printing: " . $this->title;
}
public function save() {
return "Saving: " . $this->title;
}
}
$report = new Report("Sales Report");
echo $report->print() . "\n";
echo $report->save();
输出:
Printing: Sales Report
Saving: Sales ReportReport 类通过实现 Printable 和 Savable 中的所有方法,满足了这两个契约。你必须为每个接口中声明的所有方法提供实现。
这种方法很强大,因为它让你可以在不受单继承限制的情况下,创建满足多项要求的类。一个类可以同时具备可打印、可保存、可导出等功能。
要点:使用逗号来实现多个接口。你的类必须为它实现的每个接口中的所有方法提供具体实现。
挑战
简单让我们构建一个媒体文件系统,展示单个类如何实现多个接口,从而获得不同的功能。
你将创建 4 个协同工作的文件,用于处理既可以播放又可以分享的媒体文件:
Playable.php:定义一个Playable接口,其中只有一个方法签名:play()。这个契约可确保任何可播放的媒体都能启动。Shareable.php:定义一个Shareable接口,其中只有一个方法签名:share($platform)。这个契约可确保任何可分享的内容都能分发到不同的平台。Video.php:创建一个同时实现Playable和Shareable的Video类。在文件顶部引入这两个接口文件。这个类应包含一个私有的$title属性和一个私有的$duration属性(以分钟为单位)。构造函数接收标题和时长。实现play(),使其返回"Playing video: [title] ([duration] min)"。实现share($platform),使其返回"Sharing [title] on [platform]"。main.php:引入 Video 文件。你将收到 3 个输入:视频标题、时长(以字符串形式接收,需要转换为整数)和平台名称。使用标题和时长创建一个Video对象。第一行输出调用play()的结果,然后在第二行输出使用该平台调用share()的结果。
你的 Video 类同时满足两个独立的契约。它既可以像任何媒体一样播放,也可以分享到社交平台。这就是实现多个接口的优势:单个类可以从不同来源获得功能,而不受单一继承链的限制。
亲手试试
<?php
// 引入 Video 文件
require_once 'Video.php';
// 读取输入
$title = trim(fgets(STDIN));
$duration = intval(trim(fgets(STDIN)));
$platform = trim(fgets(STDIN));
// TODO: 用标题和时长创建一个 Video 对象
// TODO: 在第一行打印调用 play() 的结果
// TODO: 在第二行打印传入平台参数调用 share() 的结果
?>这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: PHP 在线编译器