Klassen haben Vereinbarungen bezĂźglich ihrer Methoden:
<?php
class A {}
class B extends A {}
function foo(A $a) {}
function bar(B $b) {
foo($b);
}Dieser Code ist typsicher, da B der Vereinbarung von A folgt, und die Magie der Ko-/Kontra-Varianz sicherstellt, dass bis auf Exceptions alle an die Methoden gestellten Erwartungen erfĂźllt werden.
Enums haben Vereinbarungen ßber ihre Fälle, nicht ßber ihre Methoden:
<?php
enum ErrorCode {
case SOMETHING_BROKE;
}
function quux(ErrorCode $errorCode)
{
// Mit diesem Code werden offenbar alle Fälle abgedeckt
match ($errorCode) {
ErrorCode::SOMETHING_BROKE => true,
};
}
Die Anweisung match in der Funktion quux kann statisch
analysiert werden, um alle Fälle in ErrorCode abzudecken.
Aber angenommen, es wäre erlaubt, Enums zu erweitern:
<?php
// Ein gedankliches Code-Experiment, bei dem Enums nicht final sind.
// Es ist zu beachten, dass dies in PHP nicht funktioniert.
enum MoreErrorCode extends ErrorCode {
case PEBKAC;
}
function fot(MoreErrorCode $errorCode) {
quux($errorCode);
}
fot(MoreErrorCode::PEBKAC);Nach den normalen Vererbungsregeln besteht eine Klasse, die eine andere Klasse erweitert, die TypprĂźfung.
Das Problem besteht darin, dass die Anweisung match in
quux() nicht mehr alle Fälle abdeckt. Da sie
MoreErrorCode::PEBKAC nicht kennt, lĂśst der Abgleich eine
Exception aus.
Aus diesem Grund sind Enums final und kĂśnnen nicht erweitert werden.