变量的Phpdoc“;“铸造”吗;?
基类:变量的Phpdoc“;“铸造”吗;?,php,phpdoc,Php,Phpdoc,基类: abstract class A { public function methodA() { echo __FUNCTION__.'<br>'; } } class B extends A { public function methodB() { echo __FUNCTION__.'<br>'; } } phpdoc是正确的,因为它说“返回来自A”的内容。 现在棘手的部分来了: class OwnClass { /** *
abstract class A
{
public function methodA() { echo __FUNCTION__.'<br>'; }
}
class B extends A
{
public function methodB() { echo __FUNCTION__.'<br>'; }
}
phpdoc是正确的,因为它说“返回来自A
”的内容。
现在棘手的部分来了:
class OwnClass
{
/**
* @var A
*/
protected $var;
public function __construct()
{
$this->var = \Factory::createAorB();
}
}
class OwnClassB extends OwnClass
{
public function callMe()
{
$this->var->methodA();
$this->var->methodB(); // this will also run, but IDE wont autocomplete with this method
}
}
(new OwnClassB())->callMe();
这肯定会运行,但要检查
methodB()
调用。IDE不会使用此方法自动完成。如何使用phpDoc判断var现在是B
,而不是A
?您可以覆盖PHPStorm自动完成的继承属性:
/**
* @property B $var
*/
class OwnClassB extends OwnClass
{
//...
}
然而,我个人认为你试图解决错误的问题。如果您有一个返回a
或B
的工厂类,则不应向a
键入返回值。相反,您应该同时提供:
class Factory
{
/**
* @return A|B
*/
public static function createAorB()
{
return new B();
}
}
这两个选项都足以通知PHPStorm,让它以自动完成选项的形式向您显示这两种方法,但后者在代码实际执行的功能方面是准确的(好吧,在本例中不是这样,但给定函数名,我想这就是您的实际实现所做的)。不清楚
@return A
实际上是如何正确的,当您返回B
时?如果在受保护的$var
变量上有@var B
,则PHPStorm(至少)将正确地自动完成。。。(在PHPStorm.Lints中正确测试和验证,并通过这一更改正确自动完成)。@cale_b这是正确的,因为A
是b
继承链的一部分。phpdoc只说该方法将返回一个符合类a定义的类。B会这样做(因为它扩展了a)。这也是PHPStorm无法自动完成的原因-因为您不能假设当前提示中存在methodB
。同时提示A和B是错误的,因为它可能返回未来的C、D。。。。classesOk,在这种情况下,提示A | B | C | D
会适得其反,因为您可能最终会得到许多实际上并不适用的自动完成选项。那么第一种选择可能是更好的选择。
class Factory
{
/**
* @return A|B
*/
public static function createAorB()
{
return new B();
}
}