## Warum Enums nicht erweiterbar sind

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.

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open