Métodos de enumeraciónes
Enums (tanto Enums Puros como Enums Respaldados) pueden contener métodos, y pueden implementar interfaces.
Si un Enum implementa una interfaz, entonces cualquier comprobación de tipo para esa interfaz también aceptará
todos los casos de ese Enum.
<?php
interface Colorful
{
public function color(): string;
}
enum Suit implements Colorful
{
case Hearts;
case Diamonds;
case Clubs;
case Spades;
// Rellenando el contrato de la interface.
public function color(): string
{
return match($this) {
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spades => 'Black',
};
}
// No es parte de una interfaz; eso está bien.
public function shape(): string
{
return "Rectangle";
}
}
function paint(Colorful $c)
{
/* ... */
}
paint(Suit::Clubs); // Funciona
print Suit::Diamonds->shape(); // Imprime "Rectangle"
?>
En este ejemplo, las cuatro instancias de Suit
tienen dos métodos,
color()
y shape()
. En lo que respecta al código de llamada
y a las comprobaciones de tipo, se comportan exactamente igual que cualquier otra instancia de objeto.
En un Enum Respaldado, la declaración de interfaz va después de la declaración del tipo de respaldo.
<?php
interface Colorful
{
public function color(): string;
}
enum Suit: string implements Colorful
{
case Hearts = 'H';
case Diamonds = 'D';
case Clubs = 'C';
case Spades = 'S';
// Rellenando el contrato de la interface.
public function color(): string
{
return match($this) {
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spades => 'Black',
};
}
}
?>
Dentro de un método, la variable $this
está definida y se refiere a la instancia de Caso.
Los métodos pueden ser arbitrariamente complejos, pero en la práctica generalmente devolverán un valor estático o
match en $this
para proporcionar
diferentes resultados para diferentes casos.
Tenga en cuenta que en este caso sería una mejor práctica de modelado de datos definir también un
Tipo Enum SuitColor
con valores Rojo y Negro y devolver eso en su lugar.
Sin embargo, eso complicaría este ejemplo.
La jerarquía anterior es lógicamente similar a la siguiente estructura de clase
(aunque este no es el código real que se ejecuta):
<?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
{
// Método no válido, porque definir manualmente un método cases() en un Enum está prohibido.
// Vea también la sección "Listado de valores".
}
}
?>
Los métodos pueden ser public, privados o protegidos, aunque en la práctica privado y
protegido son equivalentes ya que no se permite la herencia.