What I want to achieve:
abstract final class NoticeTypes {
const ERROR = "error";
const WARNING = "warning";
const INFO = "info";
const SUCCESS = "success";
static function getAll() {
$oClass = new ReflectionClass(__CLASS__);
return $oClass->getConstants();
}
}
The interpreter does not allow this:
Fatal error: Cannot use the final modifier on an abstract class in ...
However I want to use this as kind of a "constant never-modifiable enum". It should:
Why does the Interpreter dissallow this and how shall I implement it?
You could make it final and give it a private constructor:
final class NoticeTypes {
const ERROR = "error";
const WARNING = "warning";
const INFO = "info";
const SUCCESS = "success";
static function getAll() {
$oClass = new ReflectionClass(__CLASS__);
return $oClass->getConstants();
}
private function __construct() {}
}
Here, "final" takes care for the "cannot be extended" requirement, while the private constructor takes care of "cannot be instantiated".
As for the "why" you cannot do it, it is just because such is the language specification; also, as @CD001 points out in his comment:
The whole point of abstract classes is that they are to be extended so abstract final is sort of a contradiction
There was actually an RFC to change that, but it seems it didn't make it.
With the release of PHP 8.1 we now have enumerations available, which seems to be the best way to implement what OP wanted to achieve, in fact enums cannot be extended nor instantiated:
enum NoticeTypes: string {
case ERROR = "error";
case WARNING = "warning";
case INFO = "info";
case SUCCESS = "success";
}
In this implementation, instead of a custom getAll()
method, you'd just use the cases()
method.