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.

add a note

User Contributed Notes 1 note

up
7
iloveyii at yahoo dot com
1 year ago
Just to complete the function shape in the above neat example:

<?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 match(
$this) {
Suit::Hearts => '❤️',
Suit::Diamonds => '💎',
Suit::Clubs => '♣️',
Suit::Spades => ' ♠️'
};

}
}

echo
Suit::Diamonds->shape();
echo
PHP_EOL;
echo
Suit::Clubs->shape();
To Top