Перечисления (как чистые перечисления, так и поддерживаемые перечисления) могут содержать методы и могут реализовывать интерфейсы. Если 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чтобы обеспечить разные результаты для разных случаев.

Обратите внимание, что в этом случае было бы лучше определить SuitColorEnum 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.
    }
}
?>

Методы могут быть открытыми, закрытыми или защищенными, хотя на практике закрытые и защищенные эквивалентны, поскольку наследование не допускается.