Métodos de enumerações
Enums (tanto Puras quanto Backed) podem conter métodos, e podem implementar interfaces. Se uma Enum implementa uma interface, então qualquer verificação de tipo para aquela interface também aceitará todos os casos daquela Enum.
<?php
interface Colorido
{
public function cor(): string;
}
enum Naipe implements Colorido
{
case Copas;
case Ouros;
case Paus;
case Espadas;
// Cumpre o contrato da interface.
public function cor(): string
{
return match($this) {
Naipe::Copas, Naipe::Ouros => 'Vermelho',
Naipe::Paus, Naipe::Espadas => 'Preto',
};
}
// Não faz parte de uma interface; tudo bem.
public function forma(): string
{
return "Retângulo";
}
}
function pintar(Colorido $c)
{
/* ... */
}
pintar(Naipe::Paus); // Funciona
print Naipe::Ouros->shape(); // imprime "Retângulo"
?>
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 Backed Enum, 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 Enum 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 são equivalentes na prática, pois herança não é permitida.