## Pourquoi les enums ne sont pas extensibles

Les classes ont des contrats sur leurs méthodes :

`<?php
class A {}
class B extends A {}
function foo(A $a) {}
function bar(B $b) {
foo($b);
}
?>`

Ce code est sûr du point de vue du type, car B suit le contrat de A, et par la magie de la co/contra-variance, toute attente que l'on peut avoir à l'égard des méthodes sera préservée, sauf exceptions.

Les enums ont des contrats sur leurs cas, pas sur les méthodes :

`<?php
enum ErrorCode {
case SOMETHING_BROKE;
}
function quux(ErrorCode $errorCode)
{
// Quand écrit, ce code semble couvrir tous les cas de figure
match ($errorCode) {
ErrorCode::SOMETHING_BROKE => true,
};
}
?>`

L'instruction match dans la fonction `quux` peut être analysée statiquement pour couvrir tous les cas d'ErrorCode.

Mais imaginons qu'il soit permis d'étendre les enums :

`<?php
// Code d'expérience de pensée où les enums ne sont pas finaux.
// Notez que cela ne fonctionnera pas en PHP.
enum MoreErrorCode extends ErrorCode {
case PEBKAC;
}
function fot(MoreErrorCode $errorCode) {
quux($errorCode);
}
fot(MoreErrorCode::PEBKAC);
?>`

En vertu des règles d'héritage normales, une classe qui en étend une autre passera le contrôle de type.

Le problème serait que l'instruction match dans `quux()` ne couvre plus tous les cas. Parce qu'elle ne connaît pas `MoreErrorCode::PEBKAC`, la correspondance lèvera une exception.

Pour cette raison, les enums sont finaux et ne peuvent pas être étendus.