为了使抽象类部分实现其子类的功能,并在实现所需的子类上强制一个契约,我使用了以下构造:
abstract class Parent {
public static function fromDB(string $name = '') {
$instance = new static();
if (!empty($name)) {
$instance->setName($name)->read();
}
return $instance;
}
public abstract function read();
public abstract function setName(string $name): self;
}
这里PHP似乎理解setName($name)
返回一个Parent
类型的Object,但是PhpStorm指出不能在结果上调用read()
,而这本来是预期的结果。
错误信息:在主题类中未找到引用的方法。
我不明白为什么会发生这种情况,甚至怀疑PHP或PhpStorm中有bug。
我已经阅读了后期静态绑定和以下部分讨论这个问题的问题,但我不知道如何解决它:
感谢您的时间和帮助。
我尝试在子类中实现setName,这样可以清楚地看到返回的Object的类型是子类的类型:
public function setName(string $name = null): user {...}
它不适用于self
返回类型,并且static
是禁用的。
4条答案
按热度按时间8dtrkrch1#
self
将总是引用它所在的类,从不引用子类。因此,当Parent
要求返回:self
时,它希望你创建一个返回Parent
示例的函数。你需要做的是让你的子类声明它直接这样做。ssetName
将返回:self
(Child
的示例),我们声明将直接返回Parent
类。PHP认为这是完全有效的(毕竟Child
是Parent
的示例)这里不能使用
:static
,因为static
是类定义中的保留字以上代码runs without error
igetnqfo2#
您的代码示例在PhpStorm 2017.2(目前处于EAP阶段)中看起来很好,但在2017.1.4中显示警告。
很可能是WI-33991或相关票证之一修复的。
您可以随时从此处获取并试用2017.2 EAP版本:http://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Early+Access+Program
它有自己的30天许可证,可以并行运行您的当前版本(IDE范围的设置存储在单独的文件夹)。
pwuypxnk3#
恕我直言,有一个智能和坚实的方法来使用接口。它甚至是需要的库应该使用的第三方。
因此,我们只是在所有父类中将接口名称设置为一个类型,而不是“self”,并继续对子类使用“self”。
vlju58qv4#
尝试更改以返回static,static should,这表明您正在返回扩展类,这可能会删 debugging 误。
这是猜测的工作,但值得一试。
编辑:好吧,我想这是不行的,你能提供更多的信息吗?什么是阅读的目的?从Db?等?