Menu
CoddyTech

实现多个接口

本课属于 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 Report

Report 类通过实现 Printable 和 Savable 中的所有方法,满足了这两个契约。你必须为每个接口中声明的所有方法提供实现。

这种方法很强大,因为它让你可以在不受单继承限制的情况下,创建满足多项要求的类。一个类可以同时具备可打印、可保存、可导出等功能。

要点:使用逗号来实现多个接口。你的类必须为它实现的每个接口中的所有方法提供具体实现。

challenge icon

挑战

简单

让我们构建一个媒体文件系统,展示单个类如何实现多个接口,从而获得不同的功能。

你将创建 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() 的结果

?>
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: PHP 在线编译器