Перечисления (как чистые перечисления, так и поддерживаемые перечисления) могут содержать методы и могут реализовывать интерфейсы. Если Enum реализует интерфейс, то любая проверка типа для этого интерфейса также будет принимать все случаи этого Enum.
<?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()
. Что касается кода вызова и проверки типов, то они ведут себя точно так же, как и любой другой экземпляр объекта.
В Backed Enum объявление интерфейса следует за объявлением резервного типа.
<?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
Enum Type со значениями 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.
}
}
?>
Методы могут быть открытыми, закрытыми или защищенными, хотя на практике закрытые и защищенные эквивалентны, поскольку наследование не допускается.
0 комментариев