UPDATE:PHP7.4现在是does support covariance and contravariance,它解决了这个问题中提出的主要问题.
我在PHP7中使用返回类型暗示时遇到了一些问题.我的理解是,暗示: 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");
预期yields 为:
弗莱德
我实际得到的是:
PHP致命错误:声明Foo::bar(int$baz):Foo必须与测试中的iFoo::bar(int$baz):iFoo兼容.php第7行
问题是Foo是iFoo的一个实现,所以据我所知,这个实现应该与给定的接口完全兼容.我可以通过更改接口或实现类(或两者)来修复这个问题,以按名称返回接口,而不是使用self
,但我的理解是,从语义上讲,self
意味着"返回您刚才调用方法的类的实例".因此,将其更改为接口在理论上意味着我可以返回实现接口的任何对象的实例,而我的意图是调用的实例将被返回.
这是PHP中的疏忽还是故意的设计决定?如果是前者,有没有可能在PHP7.1中修复它?如果不是,那么什么是正确的返回方式,暗示您的接口希望您返回刚刚调用链接方法的实例?