Я задал себе тот же вопрос сегодня, и я хотел бы добавить свои два цента.
Причина, по которой мы хотели бы abstract
свойства, состоит в том, чтобы убедиться, что подклассы определяют их и генерируют исключениякогда они этого не делают.В моем конкретном случае мне нужно было что-то, что могло бы работать с static
союзником.
В идеале мне хотелось бы что-то вроде этого:
abstract class A {
abstract protected static $prop;
}
class B extends A {
protected static $prop = 'B prop'; // $prop defined, B loads successfully
}
class C extends A {
// throws an exception when loading C for the first time because $prop
// is not defined.
}
В итоге я получил эту реализацию
abstract class A
{
// no $prop definition in A!
public static final function getProp()
{
return static::$prop;
}
}
class B extends A
{
protected static $prop = 'B prop';
}
class C extends A
{
}
Как видите, в A
я не определяю $prop
, но использую его в static
геттере.Поэтому следующий код работает
B::getProp();
// => 'B prop'
$b = new B();
$b->getProp();
// => 'B prop'
В C
, с другой стороны, я не определяю $prop
, поэтому я получаю исключения:
C::getProp();
// => Exception!
$c = new C();
$c->getProp();
// => Exception!
Я долженвызовите метод getProp()
, чтобы получить исключение, и я не могу получить его при загрузке класса, но это довольно близко к желаемому поведению, по крайней мере, в моем случае.
Я определяю getProp()
как final
чтобы избежать того, что какой-нибудь умный парень (он же через 6 месяцев) испытывает соблазн сделать
class D extends A {
public static function getProp() {
// really smart
}
}
D::getProp();
// => no exception...