Enumeration methods
Оновлено: 09.05.2023
Зчислення (як чисті, так і підкріплені) можуть містити методи, а також можуть реалізовувати інтерфейси. Якщо зчислення реалізує інтерфейс, то будь-яка перевірка типу для цього інтерфейсу також прийме всі випадки цього зчислення.
<?php
interface Colorful
{
public function color(): string;
}
enum Suit implements Colorful
{
case Hearts;
case Diamonds;
case Clubs;
case Spades;
// Fulfills the interface contract.
public function color(): string
{
return match($this) {
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spades => 'Black',
};
}
// Not part of an interface; that's fine.
public function shape(): string
{
return "Rectangle";
}
}
function paint(Colorful $c) { ... }
paint(Suit::Clubs); // Works
print Suit::Diamonds->shape(); // prints "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';
// Fulfills the interface contract.
public function color(): string
{
return match($this) {
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spades => 'Black',
};
}
}
?>
Усередині методу визначається змінна $this, яка посилається на екземпляр Case.
Методи можуть бути як завгодно складними, але на практиці вони зазвичай повертають статичне значення або збіг з $this, щоб забезпечити різні результати для різних випадків.
Зауважте, що у цьому випадку краще було б також визначити тип перерахування SuitColor зі значеннями Red і Black і повернути його замість цього. Однак це ускладнило б цей приклад.
Наведена вище ієрархія логічно схожа на наступну структуру класів (хоча це не є фактичним кодом, який виконується):
<?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
{
// Illegal method, because manually defining a cases() method on an Enum is disallowed.
// See also "Value listing" section.
}
}
?>
Методи можуть бути публічними, приватними або захищеними, хоча на практиці поняття "приватний" і "захищений" є рівнозначними, оскільки успадкування не допускається.