PHP8 枚举方法

2023-08-19 16:06 更新

枚举(包括纯粹枚举、回退枚举)还能包含方法, 也能实现 interface。 如果 Enum 实现了 interface,则其中的条目也能接受 interface 的类型检测。

<?php
interface Colorful
{
public function color(): string;
}

enum Suit implements Colorful
{
case Hearts;
case Diamonds;
case Clubs;
case Spades;

// 满足 interface 契约。
public function color(): string
{
return match($this) {
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spades => 'Black',
};
}

// 不是 interface 的一部分;也没问题
public function shape(): string
{
return "Rectangle";
}
}

function paint(Colorful $c) { ... }

paint(Suit::Clubs); // 正常

print Suit::Diamonds->shape(); // 输出 "Rectangle"
?>

在这例子中,Suit 所有的四个实例具有两个方法: color()、shape()。 目前的调用代码和类型检查,和其他对象实例的行为完全一致。

在回退枚举中,interface 的声明紧跟回退类型的声明之后。

<?php
interface Colorful
{
public function color(): string;
}

enum Suit: string implements Colorful
{
case Hearts = 'H';
case Diamonds = 'D';
case Clubs = 'C';
case Spades = 'S';

// 满足 interface 的契约。
public function color(): string
{
return match($this) {
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spades => 'Black',
};
}
}
?>

在方法中,定义了 $this 变量,它引用到了条目实例。

方法中可以任意复杂,但一般的实践中,往往会返回静态的值, 或者为 $this match 各种情况并返回不同的值。

注意,在本示例中,更好的数据模型实践是再定一个包含 Red 和 Black 枚举值的 SuitColor 枚举,并且返回它作为代替。 然而这会让本示例复杂化。

以上的层次在逻辑中类似于下面的 class 结构(虽然这不是它实际运行的代码):

<?php
interface Colorful
{
public function color(): string;
}

final class Suit implements UnitEnum, Colorful
{
public const Hearts = new self('Hearts');
public const Diamonds = new self('Diamonds');
public const Clubs = new self('Clubs');
public const Spades = new self('Spades');

private function __construct(public readonly string $name) {}

public function color(): string
{
return match($this) {
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spades => 'Black',
};
}

public function shape(): string
{
return "Rectangle";
}

public static function cases(): array
{
// 不合法的方法,Enum 中不允许手动定义 cases() 方法
// 参考 “枚举值清单” 章节
}
}
?>

尽管 enum 可以包括 public、private、protected 的方法, 但由于它不支持继承,因此在实践中 private 和 protected 效果是相同的。


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号