最佳答案
更新 : PHP 7.4 now 确实支持反变解决了这个问题中提出的主要问题。
在 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");
预期产出为:
弗雷德 薇玛 巴尼 贝蒂
实际上我得到的是:
PHP 致命错误: Foo: : bar (int $baz)的声明: Foo 必须与第7行 test.PHP 中的 iFoo: : bar (int $baz)兼容
问题是 Foo 是 iFoo 的一个实现,因此就我所知,这个实现应该与给定的接口完全兼容。我可以通过改变接口或者实现类(或者两者都改变)来按名称返回提示接口,而不是使用 self
来解决这个问题,但我的理解是,从语义上讲,self
意味着“返回刚才调用方法的类的实例”。因此,将其更改为接口在理论上意味着,当我的意图是针对被调用的实例时,我可以返回实现接口的任何实例。
这是 PHP 中的一个疏忽,还是一个深思熟虑的设计决策?如果是前者,有没有可能在 PHP 7.1中修复它?如果没有,那么返回提示的正确方式是什么,提示您的接口期望您返回刚才为链接调用该方法的实例?