Я столкнулся с чем-то вроде проблемы с использованием типа возвращаемого типа в PHP 7. Я понимаю, что намек : self
означает, что вы намерены реализовать сам класс реализации. Поэтому я использовал : self
в своих интерфейсах, чтобы указать это, но когда я попытался реализовать интерфейс, у меня появились ошибки совместимости.
Ниже приведена простая демонстрация проблемы, с которой я столкнулся:
interface iFoo
{
public function bar (string $baz) : self;
}
class Foo implements iFoo
{
public function bar (string $baz) : self
{
echo $baz . PHP_EOL;
return $this;
}
}
(new Foo ()) -> bar ("Fred")
-> bar ("Wilma")
-> bar ("Barney")
-> bar ("Betty");
Ожидаемый результат:
Фред Вильма гулянка Бетти
Я действительно получаю:
PHP Неустранимая ошибка: декларация Foo:: bar (int $baz): Foo должен быть совместим с iFoo:: bar (int $baz): iFoo в test.php в строке 7
Дело в том, что Foo - это реализация iFoo, так как я могу сказать, что реализация должна быть полностью совместима с данным интерфейсом. Я мог бы, вероятно, исправить эту проблему, изменив либо интерфейс, либо реализующий класс (или оба), чтобы вернуть намек на интерфейс по имени вместо использования self
, но я понимаю, что семантически self
означает "вернуть экземпляр класса вы просто вызвали метод на". Поэтому изменение его в интерфейсе в теории означало бы, что я мог бы вернуть любой экземпляр того, что реализует интерфейс, когда мое намерение для вызванного экземпляра - это то, что будет возвращено.
Является ли это надзором в PHP или это преднамеренное дизайнерское решение? Если это первый, есть шанс увидеть его исправленным в PHP 7.1? Если нет, то каков правильный способ возврата, намекая, что ваш интерфейс ожидает, что вы вернете экземпляр, который вы только что назвали методом для цепочки?