переопределение возвращаемого типа в PHPDoc


У меня есть класс Abc с методом (тело не важно):

/**
 * @return SomeBaseClass
 */
function getAll() { ... }

В дочернем классе Abc под названием AbcChild я хотел бы переопределить только тип возвращаемого класса, чтобы увидеть его должным образом в Netbeans. Могу ли я сделать это без переопределения метода:

/**
 * @return SomeClass
 */
function getAll() { return parent::getAll(); }
3 4

3 ответа:

Попробуйте что-нибудь вроде этого:

/**
 * @method SomeClass getAll()
 */
class AbcChild
{
 // ....
}

Подробнее о компании @method

Нет, потому что вам нужен сам код дочернего метода, чтобы иметь дочерний docblock для связи с ним. Если у вас есть docblock, но нет кода метода, docblock не будет привязан ни к чему и, таким образом, не будет иметь никакого эффекта. Большинство людей не любят изменять свой код, чтобы приспособиться к поведению docblock,хотя это никогда не беспокоило меня.

Однако другой вариант для вас-настроить тег @return в Родительском методе, чтобы он перечислял все возможные типы возвращаемых данных, которые вы хотите указать, что дети могут вернуться. Но это заставляет меня задуматься... если вы фактически не переопределяете сам метод,то как дочерний класс фактически возвращает другой класс, чем родительский? Я могу видеть способы сделать это в моем уме, включая свойства класса, которые содержат различные объекты класса, но они будут чувствовать себя как запах кода для меня ; -)

Если в дочернем коде отсутствует сам код переопределения метода, то я бы предпочел поместить все возможные типы возвращаемых данных в возвращение родителя@.

На самом деле я думаю, что есть другой способ, чем полное переопределение метода. Вы можете изменить блок @return phpdoc в дочернем интерфейсе, который расширяет базовый интерфейс. Позвольте мне объяснить с помощью кода, что я имею в виду:

interface EntityRepository
{
   /**
    * @return object
    */
    public function get($id);
    public function add($entity, $sync = false);
    public function remove($entity, $sync = false);
    // other methods common for custom repositories
}

interface ProjectRepository extends EntityRepository
{
   /**
    * @return Project
    */
    public function get($id);
}

Это часть вашего домена. А теперь конкретная реализация, взятая из Symfony & Doctrine:

use Doctrine\ORM\EntityRepository;
use Model\Repository\EntityRepository as BaseEntityRepository;

abstract class DoctrineEntityRepository extends EntityRepository implements BaseEntityRepository
{
    public function get($id)
    {
        $entity = $this->find($id);
        if (!$entity) {
            throw new EntityNotFoundException();
        }

        return $entity;
    }

    public function add($entity, $sync = false)
    {
        // method implementation
    }
    public function remove($entity, $sync = false)
    {
        // method implementation
    }
}

use Model\Repository\ProjectRepository as BaseProjectRepository;

class ProjectRepository extends DoctrineEntityRepository implements BaseProjectRepository
{
    public function specificQueryForProjects()
    {
        // method implementation
    }
}

Таким образом, вам не придется переопределять методы в дочерних классах только из-за автозаполнения кода. Вам просто нужно расширить интерфейсы, чтобы пользователи вашего API знали, что возвращаемое значение изменилось.