PHP 8.5.0 Beta 2 available for testing

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.

add a note

User Contributed Notes 1 note

up
17
iloveyii at yahoo dot com
2 years 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