ATUALIZAÇÃO : o PHP 7.4 agora oferece suporte a covariância e contravariância que aborda a principal questão levantada nesta questão.
Eu tive um problema com o uso de dicas de tipo de retorno no PHP 7. Meu entendimento é que a sugestão : self
significa que você pretende que uma classe de implementação retorne a si mesma. Portanto, usei : self
em minhas interfaces para indicar isso, mas quando tentei realmente implementar a interface, obtive erros de compatibilidade.
A seguir está uma demonstração simples do problema que encontrei:
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");
A saída esperada era:
Fred Wilma Barney Betty
O que eu realmente consigo é:
Erro fatal do PHP: Declaração de Foo :: bar (int $ baz): Foo deve ser compatível com iFoo :: bar (int $ baz): iFoo em test.php na linha 7
O fato é que Foo é uma implementação do iFoo, então pelo que eu posso dizer, a implementação deve ser perfeitamente compatível com a interface fornecida. Eu poderia provavelmente corrigir esse problema alterando a interface ou a classe de implementação (ou ambas) para retornar a dica da interface pelo nome em vez de usar self
, mas meu entendimento é que semanticamente self
significa "retornar a instância da classe na qual você acabou de chamar o método " Portanto, alterá-lo para a interface significaria, em teoria, que eu poderia retornar qualquer instância de algo que implementa a interface quando minha intenção é que a instância invocada seja o que será retornado.
Isso é um descuido no PHP ou é uma decisão de design deliberada? Se for o primeiro, há alguma chance de vê-lo corrigido no PHP 7.1? Se não, qual é a maneira correta de retornar a dica de que sua interface espera que você retorne a instância na qual acabou de chamar o método para encadeamento?