Métodos de enumerações
Enumerações (tanto Puras quanto Apoiadas) podem conter métodos e podem implementar interfaces.
Se uma enumeração implementa uma interface, qualquer verificação de tipo para aquela interface também aceitará
todos os casos daquela enumeração.
Nesse exemplo, todas as quatro instâncias de Naipe possuem dois métodos,
cor() e forma(). Até onde o código chamador
e as checagens de tipo sabem, elas se comportam exatamente da mesma forma que qualquer outra instância de objeto.
Em uma Enumeração Apoiada, a declaração de interface vai após a declaração do tipo de lastro.
<?php
interface Colorido
{
public function cor(): string;
}
enum Naipe: string implements Colorido
{
case Copas = 'C';
case Ouros = 'O';
case Paus = 'P';
case Espadas = 'E';
// Cumpre o contrato da interface.
public function cor(): string
{
return match($this) {
Naipe::Copas, Naipe::Ouros => 'Vermelho',
Naipe::Paus, Naipe::Espadas => 'Preto',
};
}
}
Dentro de um método, a variável $this é definida e se refere à instância do Caso.
Métodos podem ser arbitrariamente complexos, mas na prática geralmente retornam um valor estático ou
match no $this para fornecer
resultados diferentes para casos diferentes.
Note que nesse caso, uma prática melhor de modelagem de dados seria definir também um
Tipo 'enum' CorDeNaipe com valores Preto e Vermelho e retornar isso no seu lugar.
No entanto, isso complicaria esse exemplo.
A hierarquia acima é logicamente similar a seguinte estrutura de classes
(embora esse não seja o código real que é executado):
<?php
interface Colorido
{
public function cor(): string;
}
final class Naipe implements UnitEnum, Colorido
{
public const Copas = new self('Copas');
public const Ouros = new self('Ouros');
public const Paus = new self('Paus');
public const Espadas = new self('Espadas');
private function __construct(public readonly string $nome) {}
public function cor(): string
{
return match($this) {
Naipe::Copas, Naipe::Ouros => 'Vermelho',
Naipe::Paus, Naipe::Espadas => 'Preto',
};
}
public function forma(): string
{
return "Retângulo";
}
public static function cases(): array
{
// Método ilegal, porque definir manualmente um método cases() em uma enumeração não é permitido.
// Veja também a seção "Listagem de valores".
}
}
Métodos podem ser públicos, privados ou protegidos, apesar dos privados e
protegidos serem equivalentes na prática, pois herança não é permitida.