标签:php inheritance phpdoc type-narrowing
假设我们在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中父方法的签名相同.
但是,我想以某种方式弄清楚扩展RealEntitySerializer或PseudoEntitySerializer的子类不得返回任意Entity的实例,而应将返回类型缩小为RealEntity或PseudoEntity resp.
特别是,如果我省略了中间类的方法及其对应的PHPdoc的重新定义以使PHP满意,则我的IDE会正确地假定RealEntitySerializer :: getEntity和PseudoEntitySerializer :: getEntity被允许返回Entity的任意实例.结果,我的IDE抱怨说,如果我调用RealEntitySerializer :: getEntity或PseudoEntitySerializer :: getEntity resp返回的对象中的某个中间类特定的方法,则会调用未定义的方法.
如何实现两个目标? (a)由PHP解释且无错误且(b)正确记录的代码.
解决方法:
您需要PSR-5: PHPDoc @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 {}
标签:php,inheritance,phpdoc,type-narrowing 来源: https://codeday.me/bug/20191013/1909694.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。