PHP 8.4.1 Released!

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.

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