## Why enums aren't extendable

Classes have contracts on their methods:

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

This code is type-safe, as B follows the contract of A, and through the magic of co/contra-variance, any expectation one may have of the methods will be preserved, exceptions excepted.

Enums have contracts on their cases, not methods:

`<?php
enum ErrorCode {
case SOMETHING_BROKE;
}
function quux(ErrorCode $errorCode)
{
// When written, this code appears to cover all cases
match ($errorCode) {
ErrorCode::SOMETHING_BROKE => true,
};
}
?>`

The match statement in the function `quux` can be static analyzed to cover all of the cases in ErrorCode.

But imagine it was allowed to extend enums:

`<?php
// Thought experiment code where enums are not final.
// Note, this won't actually work in PHP.
enum MoreErrorCode extends ErrorCode {
case PEBKAC;
}
function fot(MoreErrorCode $errorCode) {
quux($errorCode);
}
fot(MoreErrorCode::PEBKAC);
?>`

Under normal inheritance rules, a class that extends another will pass the type check.

The problem would be that the match statement in `quux()` no longer covers all the cases. Because it doesn't know about `MoreErrorCode::PEBKAC` the match will throw an exception.

Because of this enums are final and can't be extended.

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