Métodos de enumeración
Las enumeraciones (tanto Enumeraciones Puras como Enumeraciones Respaldadas) pueden contener métodos y pueden implementar interfaces.
Si una enumeración implementa una interfaz, entonces cualquier comprobación de tipo para esa interfaz también aceptará
todos los casos de esa enumeración.
<?php
interface Colorful
{
public function color(): string;
}
enum Suit implements Colorful
{
case Hearts;
case Diamonds;
case Clubs;
case Spades;
// Cumple con el contrato de la interfaz.
public function color(): string
{
return match($this) {
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spades => 'Black',
};
}
// No forma 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 cuanto al código de llamada
y las comprobaciones de tipo, se comportan exactamente igual que cualquier otra instancia de objeto.
En una Enumeración Respaldada, 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';
// Cumple con el contrato de la interfaz.
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 del Caso.
Los métodos pueden ser arbitrariamente complejos, pero en la práctica suelen devolver 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 también definir un
tipo de enumeración SuitColor
con valores Red y Black 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 ilegal, porque definir manualmente un método cases() en una Enumeración no está permitido.
// Ver también la sección "Listado de valores".
}
}
?>
Los métodos pueden ser públicos, privados o protegidos, aunque en la práctica privado y
protegido son equivalentes ya que la herencia no está permitida.