枚舉(包括純粹枚舉、回退枚舉)還能包含方法, 也能實(shí)現(xiàn) interface。 如果 Enum 實(shí)現(xiàn)了 interface,則其中的條目也能接受 interface 的類型檢測(cè)。
<?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 的一部分;也沒(méi)問(wèn)題
public function shape(): string
{
return "Rectangle";
}
}
function paint(Colorful $c) { ... }
paint(Suit::Clubs); // 正常
print Suit::Diamonds->shape(); // 輸出 "Rectangle"
?>
在這例子中,Suit
所有的四個(gè)實(shí)例具有兩個(gè)方法:
color()
、shape()
。
目前的調(diào)用代碼和類型檢查,和其他對(duì)象實(shí)例的行為完全一致。
在回退枚舉中,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
變量,它引用到了條目實(shí)例。
方法中可以任意復(fù)雜,但一般的實(shí)踐中,往往會(huì)返回靜態(tài)的值,
或者為 $this
match
各種情況并返回不同的值。
注意,在本示例中,更好的數(shù)據(jù)模型實(shí)踐是再定一個(gè)包含 Red 和 Black
枚舉值的 SuitColor
枚舉,并且返回它作為代替。
然而這會(huì)讓本示例復(fù)雜化。
以上的層次在邏輯中類似于下面的 class 結(jié)構(gòu)(雖然這不是它實(shí)際運(yùn)行的代碼):
<?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 中不允許手動(dòng)定義 cases() 方法
// 參考 “枚舉值清單” 章節(jié)
}
}
?>
僅管 enum 可以包括 public、private、protected 的方法, 但由于它不支持繼承,因此在實(shí)踐中 private 和 protected 效果是相同的。