Сужение возвращаемого типа при наследовании для абстрактного метода через 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,

Тем не менее, я хочу как-то прояснить, что дочерние классы, которые расширяют RealEntitySerializer или же PseudoEntitySerializer не должен возвращать экземпляр произвольного Entity но сузить тип возвращаемого значения RealEntity или же PseudoEntity соответственно

Особенно, если я опускаю переопределение метода и соответствующего ему PHPdoc из промежуточных классов, чтобы сделать PHP счастливым, моя IDE правильно предполагает, что RealEntitySerializer::getEntity а также PseudoEntitySerializer::getEntity разрешено возвращать произвольный экземпляр Entity, В результате моя среда IDE жалуется, что я вызываю неопределенные методы, если вызываю методы, относящиеся к одному из промежуточных классов объекта, который был возвращен RealEntitySerializer::getEntity или же PseudoEntitySerializer::getEntity соответственно

Как мне достичь обеих целей? Код, который (а) интерпретируется PHP без ошибок и (б) должным образом документирован.

1

Решение

Вы хотите 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 {}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]