当 class2 扩展 class1 时,PhpStorm 警告“预期的 class1,得到 class2”

Posted

技术标签:

【中文标题】当 class2 扩展 class1 时,PhpStorm 警告“预期的 class1,得到 class2”【英文标题】:PhpStorm warns about "Expected class1, got class2" when class2 extends class1 【发布时间】:2017-01-09 12:12:25 【问题描述】:

我正在使用 Phalcon 框架,它具有模型类:Phalcon\Mvc\Model(从现在起仅作为 P\M\Model)。我已经定义了基域,它扩展了该类,然后所有其他域都扩展了我的基域,因此 Phalcons 模型类:

域名.php

class Domain extends \Phalcon\Mvc\Model

    ...

DomainA.php:

class DomainA extends Domain

    ...

然后我使用存储库管理器获取DomainA 模型的存储库。所有存储库都有相同的父级,类似于定义了方法 find() 的 Domain

Repository.php:

class Repository

    /**
    * Will always return object of classes 
    * which extends Phalcon\Mvc\Model
    *
    * @return Phalcon\Mvc\Model
    */
    public function find()
    
        ...
        $domain::find();
    

RepositoryA.php:

class RepositoryA extends Repository

    ...

所以,RepositoryA 现在有来自其父级的 find() 方法,因为父级并不确切知道他将返回什么,但知道所有返回的父级,所以它通过 @ 进行类型提示987654330@.

然后我有一些其他类,它的方法只需要 DomainA 对象,它也是 P\M\Model 的父对象,我尝试将这种类型的对象推送到那里它工作正常,因为从存储库返回的对象实际上是DomainA 对象,但 Repository 将其注释为 P\M\Model,因此 PhpStorm 用消息突出显示它 "Expected DomainA, got Phalcon\Mvc\Model..."

public function pleaseGiveDomainA(DomainA $obj)

    ...


// Works OK but is higlighted in IDE
$this->pleaseGiveDomainA($repositoryA->find());

我应该如何注释这种东西?在@return 中提示@return DomainA|DomainB|DomainC... 等所有域的情况都不好,因为我们有数百个域,而且在功能上期望父P\M\Model 也不好,因为我们想确定它是唯一的DomainA。

谢谢。

【问题讨论】:

***.com/a/39401647/934739的可能重复 @GerardRoche 这一个比它大一天,那么另一个不应该被认为可能重复吗? 【参考方案1】:

尝试使用接口而不是基本模型。根据我的经验,有时 PHPStorm 会与这种复杂的类层次结构混淆。在我的程序中,我定义了一个接口并针对它输入提示。这允许 PHPStorm 正确检测类

【讨论】:

但是当我需要基本模型有非抽象方法时呢?然后我应该添加接口但仍扩展基本模型吗? 你可以。您也可以使用接口来创建一种用于开发应用程序的最佳实践,这样不仅可以使 PHPStorm 快乐,还可以形式化类系统的结构。我应该注意我还看到其他开发人员创建空白接口来解决这个问题【参考方案2】:

如果您在 RepositoryA 类中重新定义 find(),则只需使用 @return DomainA 注释其实现即可。否则,在RepositoryA 类的文档块中将find() 声明为@method,并将DomainA 作为其返回类型。

两种方法都显示如下:

/**
 * @method DomainA find()          <-- use this when the method is inherited 
 *                                     but not redefined in this class
 */
class RepositoryA extends Repository

    /**
     * @return DomainA             <-- preferably use this
     */
    public function find()
    

    

类似的技巧可以用于继承属性,在子类中存储类的对象,这些类扩展了基类中注释中使用的类:

/**
 * @property DomainA $member       <-- it was declared as @var Domain $member
 *                                     in the base class
 */

【讨论】:

【参考方案3】:

PSR-5 定义了一个 @method 标签。

语法

@method [return type] [name]([type] [parameter], [...]) [description]

示例

/**
 * @method string getString()
 * @method void setInteger(int $integer)
 * @method setString(int $integer)
 */
class Child extends Parent

    <...>

abstract class EntitySerializer 
  /**
   * @return Entity
   */
  abstract public function getEntity();


/**
 * @method RealEntity getEntity()
 */
abstract class RealEntitySerializer extends EntitySerializer 

/**
 * @method PseudoEntity getEntity()
 */
abstract class PseudoEntitySerializer extends EntitySerializer 

回复:取自我的SO answer here。

【讨论】:

以上是关于当 class2 扩展 class1 时,PhpStorm 警告“预期的 class1,得到 class2”的主要内容,如果未能解决你的问题,请参考以下文章

markdown .class1.class2和.class1 .class2的区别

如果元素在 Jquery .hasClass() 函数中具有“class1”和/或“class2”

jquery中class选择器的用法,选择两个class

model: class1 或 class2 如何与 class3 有关系,但两者同时没有关系?

比例:工作地图

c ++指针转换过载