Menu
CoddyTech

匿名类

本课属于 Coddy PHP 学习旅程的“面向对象编程”单元。第 58 课,共 91 课。

有时,你需要一个简单的临时对象,不想为此定义完整的类。匿名类可以让你在需要的地方即时创建对象。它们与依赖注入结合使用时尤其有用。

匿名类使用 new class 定义,后面跟着类体:

<?php
$logger = new class {
    public function log(string $message): void {
        echo "Log: $message";
    }
};

$logger->log("Hello!");

输出:

Log: Hello!

实现接口时,匿名类会变得非常强大。这非常适合测试,或者在你需要快速实现、又不想用只使用一次的类让代码库变得杂乱时使用:

<?php
interface Notifier {
    public function send(string $message): string;
}

function notify(Notifier $notifier, string $msg): string {
    return $notifier->send($msg);
}

$result = notify(new class implements Notifier {
    public function send(string $message): string {
        return "Sent: $message";
    }
}, "Test message");

echo $result;

输出:

Sent: Test message

匿名类也可以继承其他类、使用 trait,并接收构造函数参数。它们可以使用完整的面向对象编程功能,只是以内联方式定义,而不是定义在单独的文件中。当完整的类定义显得过于繁琐,但你仍然需要面向对象行为时,可以使用匿名类。

challenge icon

挑战

简单

让我们构建一个数据格式化系统,展示匿名类的强大之处。对于简单的一次性实现,你不必创建单独的类文件,而是可以在需要的地方使用匿名类快速实现。

你会将代码分成两个文件:

  • FormatterInterface.php:定义一个名为 FormatterInterface 的接口,其中包含一个方法 format(string $data): string。这规定了所有格式化器都必须遵循的契约。
  • main.php:引入接口文件,并创建一个 DataProcessor 类,通过依赖注入接受任意格式化器。这个类应该:
    • 在构造函数中接受一个 FormatterInterface
    • 包含一个方法 process(string $data),将处理委托给注入的格式化器,并返回其结果

    你会收到两个输入:格式类型("upper" 或 "reverse")以及要格式化的字符串。

    根据格式类型,创建一个实现 FormatterInterface 的匿名类:

    • 对于 "upper":format() 方法应返回转换为大写的内容
    • 对于 "reverse":format() 方法应返回反转后的内容

    将匿名类注入 DataProcessor,使用输入字符串调用 process(),并打印结果。

如果你需要快速实现,又不想让只使用一次的类文件使代码库变得杂乱,这种方法就很合适。匿名类会在代码中直接创建,实现所需的接口,并且可以传递到任何需要该接口的地方。

亲手试试

<?php
require_once 'FormatterInterface.php';

// TODO:创建一个 DataProcessor 类,要求:
// 接受一个 FormatterInterface 作为构造函数的参数
// 提供一个 process(string $data) 方法,将处理工作交给格式化器

// 读取输入
$formatType = trim(fgets(STDIN));
$inputString = trim(fgets(STDIN));

// TODO:根据 $formatType("upper" 或 "reverse")创建一个匿名类
// 该类实现 FormatterInterface
// 对于 "upper":format() 应返回 data 的大写形式
// 对于 "reverse":format() 应返回 data 的反转形式

// TODO:使用你创建的匿名类格式化器创建一个 DataProcessor
// 将输入字符串传给 process(),并打印结果

?>
quiz icon自我测试

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

面向对象编程中的所有课

自己练习: PHP 在线编译器