Aufzählungen und Methoden
Enums (sowohl Pure Enums als auch Backed Enums) können Methoden enthalten
und Schnittstellen implementieren. Wenn eine Enum eine Schnittstelle
implementiert, dann akzeptiert eine Typüberprüfung für diese Schnittstelle
auch alle Fälle dieser Enum.
<?php
interface Colorful
{
public function color(): string;
}
enum Suit implements Colorful
{
case Hearts;
case Diamonds;
case Clubs;
case Spades;
// Erfüllt die Schnittstellenvereinbarung
public function color(): string
{
return match($this) {
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spades => 'Black',
};
}
// Nicht Teil der Schnittstelle; das ist OK
public function shape(): string
{
return "Rectangle";
}
}
function paint(Colorful $c)
{
/* ... */
}
paint(Suit::Clubs); // funktioniert
print Suit::Diamonds->shape(); // gibt "Rectangle" aus
?>
In diesem Beispiel haben alle vier Instanzen von Suit
zwei Methoden: color()
und shape()
.
In Bezug auf den aufrufenden Code und die Überprüfung des Typs verhalten
sie sich genau wie jede andere Objektinstanz.
Bei einer Backed Enum erfolgt die Deklaration der Schnittstelle nach der
Deklaration des zugehörigen Typs.
<?php
interface Colorful
{
public function color(): string;
}
enum Suit: string implements Colorful
{
case Hearts = 'H';
case Diamonds = 'D';
case Clubs = 'C';
case Spades = 'S';
// Erfüllt die Schnittstellenvereinbarung
public function color(): string
{
return match($this) {
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spades => 'Black',
};
}
}
?>
Innerhalb einer Methode wird die Variable $this
definiert, die sich auf die Case-Instanz bezieht.
Die Methoden können beliebig komplex sein, geben aber in der Praxis
normalerweise einen statischen Wert zurück oder ein match
(Übereinstimmung) auf $this
, um für verschiedene Fälle
verschiedene Ergebnisse zu liefern.
In diesem Fall wäre es für die Datenmodellierung besser, auch einen
Enum-Typ SuitColor
mit den Werten Red und Black zu
definieren und stattdessen diesen zurückzugeben, aber das würde dieses
Beispiel verkomplizieren.
Die obige Hierarchie ähnelt logisch der folgenden Klassenstruktur (obwohl
dies nicht der tatsächlich ausgeführte Code ist):
<?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
{
// Unzulässige Methode, weil bei einer Enum keine benutzerdefinierte case()-Methode erlaubt ist.
// Siehe auch Abschnitt "Werteliste".
}
}
?>
Methoden können public, private oder protected sein, wobei private und
protected praktisch gleichwertig sind, da Vererbung nicht erlaubt ist.