更新:PHP 7.4现在确实支持协方差和逆方差,这解决了此问题中提出的主要问题。
我在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):第7行的test.php中的iFoo兼容
事情是Foo是iFoo的实现,据我所知,该实现应该与给定的接口完全兼容。我大概可以通过更改接口或实现类(或两者)以按名称而不是使用来返回提示接口来解决此问题self
,但我的理解是从语义上讲self
意味着“返回您刚刚在其上调用方法的类的实例” ”。因此,从理论上讲,将其更改为接口意味着我可以返回任何实现接口的东西的实例,而当我的意图是要调用的实例是要返回的对象时。
这是PHP的疏忽,还是故意的设计决策?如果是前者,有没有机会看到它在PHP 7.1中修复?如果不是,那么正确的返回方式暗示您的接口希望您返回刚刚调用该方法进行链接的实例?