PHP 8.0 позволяет использовать static в качестве типа возвращаемого значения для методов класса.
class Foo {
public static function getInstance(): static {
return new static();
}
} В предыдущих версиях методы классов PHP могли возвращать self и parent , но static не допускался до PHP 8.0. Новый разрешённый тип возвращаемого значения static позволяет сузить возвращаемый тип до вызываемого класса.
Тип возвращаемого значения static полезен для классов с «текучим» интерфейсом (т. е. с return $this ), неизменяемых классов (т. е. return clone $this ) или статических методов, которые возвращают экземпляр самого класса.
Без разрешения типа static в качестве возвращаемого значения приходилось использовать self , что не всегда идеально. В PHP DocBlock тип @return static уже поддерживался, указывая на то, что методы возвращают сам объект или экземпляр того же класса.
Благодаря поддержке типа возвращаемого значения static в PHP 8.0 теперь можно заменить аннотации @return static в DocBlock объявлением типа возвращаемого значения.
class Foo {
- /**
- * @return static
- */
- public static getInstance() {
+ public static getInstance(): static {
return new static();
}
} Вариантность
Тип возвращаемого значения static соответствует принципу подстановки Барбары Лисков. Метод дочернего класса может возвращать объект более узкого класса, чем тип возвращаемого значения родительского метода.
Поскольку static всегда ссылается на имя класса вызываемого объекта (т. е. так же, как get_class($object) ), static является подмножеством self , которое, в свою очередь, является подмножеством parent .
Дочерний класс может возвращать static , даже если тип возвращаемого значения родительского метода — self или parent .
Например, вся следующая цепочка наследования является корректной:
Слишком длинные цепочки наследования почти всегда являются плохой идеей и приводят к трудноподдерживаемому коду. Приведённый ниже фрагмент кода используется только для демонстрации.
class Foo {
public function getInstance(): mixed {}
}
class Bar extends Foo {
public function getInstance(): object|null {}
}
class Baz extends Bar {
public function getInstance(): object {}
}
class Qux extends Baz {
public function getInstance(): parent {}
}
class Quux extends Qux {
public function getInstance(): self {}
}
class Corge extends Quux {
public function getInstance(): static {}
} В фрагменте кода выше используются и другие возможности PHP 8.0:
Попытка «расширить» область типа возвращаемого значения с помощью self , parent или любого другого типа приведет к ошибке:
class Corge {
public function getInstance(): static {}
}
class Grault extends Corge {
public function getInstance(): parent {}
} Fatal error: Declaration of Grault::getInstance(): Corge must be compatible with Corge::getInstance(): static in ... on line ... На самом деле, также не допускается заменять тип возвращаемого значения static именем дочернего или родительского класса.
Только как тип возвращаемого значения
Тип возвращаемого значения static допускается использовать только в качестве возвращаемого типа. Его нельзя использовать как тип свойства или тип параметра.
Это связано с тем, что тип возвращаемого значения static всегда сужает область применения, что недопустимо для типизированных свойств и типов параметров.
Запрещено вне контекста класса
Только методы классов могут объявлять тип возвращаемого значения static . Обычные функции или замыкания не могут объявлять тип возвращаемого значения static .
function get_instance(): static {} Fatal error: Cannot use "static" when no class scope is active in ... on line ... Влияние на обратную совместимость
Код с типом возвращаемого значения static не будет обратно совместим со старыми версиями PHP до 8.0. Запуск такого кода приведет к ошибке синтаксического анализа (parse error):
Parse error: syntax error, unexpected 'static' (T_STATIC) in ... on line ...
Бэкпортировать эту возможность в более старые версии PHP также невозможно.
Комментарии (0)
Пока нет комментариев — будьте первым.