Изначально я садился писать этот пост, но решил вас предварительно разогреть... 😉
Представьте себе такую ситуацию:
interface A
{
public static function new(): static;
}
final class B implements A
{
public static function new(): self
{
return new self();
}
}
Есть ли тут ошибка? Поначалу кажется, что есть. В интерфейсе сказано: нужно вернуть инстанс класса позднего статического связывания, а реализация использует более широкий тип
self и поэтому нарушает LSP. PHP тоже так считает: https://3v4l.org/qWDQY.А теперь обратим внимание, что класс
B финальный! В цепочке наследования после B уже никого не может быть, это самый "поздний" возможный класс. В финальном классе всегда self =:= static. Так что ошибки на самом деле нет!Недавно подписчик Пыха @m1chael19 закинул PR с исправлением этого недоразумения. Фикс посчитали очень логичным и смерджили в 8.5 без RFC. Поздравим Михаила с первым контрибьютом в PHP!
https://github.com/php/php-src/pull/17724
https://3v4l.org/qWDQY/rfc#vgit.master