通过PHPdoc继承抽象方法的返回类型变窄导致PHP错误 [英] Narrowing return type on inheritance for abstract method through PHPdoc causes PHP error

查看:74
本文介绍了通过PHPdoc继承抽象方法的返回类型变窄导致PHP错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们在PHP中具有以下继承链

 abstract class Entity {}
abstract class RealEntity extends Entity {}
abstract class PseudoEntity extends Entity {}
 

和一堆反映相同继承链的其他类

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

abstract class RealEntitySerializer extends EntitySerializer {
  /**
   * @return RealEntity
   */
  abstract public function getEntity();
}


abstract class PseudoEntitySerializer extends EntitySerializer {
  /**
   * @return PseudoEntity
   */
  abstract public function getEntity();
}
 

PHP抱怨抽象方法getEntity必须正确实现(并松开abstract关键字),或者不能重新声明.我能理解为什么PHP会抱怨,因为尽管有PHPdoc注释,但方法签名与EntitySerializer中父方法的签名相同.

但是,我想以某种方式弄清楚扩展RealEntitySerializerPseudoEntitySerializer的子类一定不能返回任意Entity的实例,而只能将返回类型缩小为RealEntityPseudoEntity. /p>

尤其是,如果为了使PHP满意而省略了中间类中方法的重新定义及其对应的PHPdoc,则我的IDE会正确地假定允许RealEntitySerializer::getEntityPseudoEntitySerializer::getEntity返回<的任意实例. c7>.结果,我的IDE抱怨如果我调用RealEntitySerializer::getEntityPseudoEntitySerializer::getEntity resp.

返回的对象中某个中间类之一所特有的方法,则会调用未定义的方法.

如何实现两个目标?代码(a)由PHP正确解释,并且(b)正确记录了代码.

解决方案

您想要abstract class Entity {} abstract class RealEntity extends Entity {} abstract class PseudoEntity extends Entity {}

and a bunch of other classes that mirror the same inheritance chain

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

abstract class RealEntitySerializer extends EntitySerializer {
  /**
   * @return RealEntity
   */
  abstract public function getEntity();
}


abstract class PseudoEntitySerializer extends EntitySerializer {
  /**
   * @return PseudoEntity
   */
  abstract public function getEntity();
}

PHP complains that the abstract method getEntity must either be properly implemented (and loose the abstract keyword) or must not be re-declared. I can understand why PHP complains, because despite the PHPdoc comments the method signature is identical to the signature of the parent method in EntitySerializer.

However, I want somehow to make clear that child classes that extend RealEntitySerializer or PseudoEntitySerializer must not return an instance of an arbitrary Entity but narrow the return type to RealEntity or PseudoEntity resp.

Especially, If I omit re-definition of the method and its corresponding PHPdoc from the intermediate classes in order to make PHP happy, my IDE correctly assumes that RealEntitySerializer::getEntity and PseudoEntitySerializer::getEntity is allowed to return an arbitrary instance of Entity. In consequence, my IDE complains that I call undefined methods if I call methods that are particular to one of the intermediate classes on an object that was returned by RealEntitySerializer::getEntity or PseudoEntitySerializer::getEntity resp.

How, do I achieve both goals? Code that is (a) interpreted by PHP without an error and and that is (b) properly documented.

解决方案

You want the PSR-5: PHPDoc @method tag.

Syntax

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

Examples

/**
 * @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 {}

这篇关于通过PHPdoc继承抽象方法的返回类型变窄导致PHP错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆