2024 年日本 PHP 研討會

列舉方法

列舉(純列舉和支援型列舉)可以包含方法,並且可以實作介面。如果列舉實作了介面,則任何針對該介面的類型檢查也會接受該列舉的所有情況。

<?php

介面 Colorful
{
public function
color(): string;
}

列舉
Suit 實作 Colorful
{
case
Hearts;
case
Diamonds;
case
Clubs;
case
Spades;

// 履行介面合約。
public function color(): string
{
return match(
$this) {
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spades => 'Black',
};
}

// 非介面的一部分;這沒問題。
public function shape(): string
{
return
"Rectangle";
}
}

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

paint(Suit::Clubs); // 可以正常運作

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

在此範例中,所有四個 Suit 的實例都有兩個方法,color()shape()。就呼叫程式碼和類型檢查而言,它們的行為與任何其他物件實例完全相同。

在有支援類型的列舉中,介面宣告放在支援類型宣告之後。

<?php

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

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

// 實現介面規範。
public function color(): string
{
return match(
$this) {
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spades => 'Black',
};
}
}
?>

在方法內,`$this` 變數已被定義,並指向枚舉案例的實例。

方法可以任意複雜,但在實務上通常會回傳一個靜態值,或使用 match 運算式搭配 `$this` 來針對不同的案例提供不同的結果。

請注意,在這種情況下,更好的資料建模做法是額外定義一個帶有紅色和黑色值的 `SuitColor` 枚舉類型,並回傳該類型。然而,這會使範例變得更複雜。

上述階層結構在邏輯上類似於以下的類別結構(雖然這並非實際執行的程式碼)

<?php

介面 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() 函式。
// 也請參考「值列表」章節。
}
}
?>

方法可以是 public、private 或 protected,但在實務上 private 和 protected 是相同的,因為不允許繼承。

新增註解

使用者貢獻的註解 1 則註解

iloveyii at yahoo dot com
1 年前
只是為了完成上面簡潔範例中的 shape 函式

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

列舉
Suit implements Colorful
{
case
Hearts;
case
Diamonds;
case
Clubs;
case
Spades;

// 履行介面合約。
public function color(): string
{
return match(
$this) {
Suit::Hearts, Suit::Diamonds => '紅色',
Suit::Clubs, Suit::Spades => '黑色',
};
}

// 非介面的一部分;沒關係。
public function shape(): string
{
return match(
$this) {
Suit::Hearts => '❤️',
Suit::Diamonds => '💎',
Suit::Clubs => '♣️',
Suit::Spades => ' ♠️'
};

}
}

echo
Suit::Diamonds->shape();
echo
PHP_EOL;
echo
Suit::Clubs->shape();
To Top