override return type in PHPDoc

2019-04-30 19:01发布

问题:

I have a class Abc with method (body is not important):

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

In child class of Abc called AbcChild I'd like to redefine only type of returning class to see it properly in Netbeans. Can I do it without redefining method:

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

回答1:

Try something like this:

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

More info about @method



回答2:

No, because you need the child method code itself in order to have a child docblock to associate with it. If you have the docblock but not the method code, the docblock won't be tied to anything, and thus will have no effect. Most people dislike altering their code to accommodate docblock behavior, though it's never really bothered me to do so.

However, another option for you is to adjust the @return tag on the parent method, so that it lists all possible return types that you want to indicate the children could return. That makes me wonder, though... if you are not actually overriding the method itself, then how is the child class actually returning a different class than the parent? I can see ways to do this in my mind, involving class properties that contain the differing class objects, but they'd feel like code smells to me ;-)

If there is no method override code itself in the child, then I would choose to put all possible return types in the parent's @return.



回答3:

Actually I think there is other way than full method override. You can change @return phpdoc block in the child interface which extends base interface. Let me explain with code what I mean:

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);
}

This is part of your domain. And now the concrete implementation taken from 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
    }
}

This way you dont have to override methods in child classes only because of code autocomplete. You just have to extend interfaces to let users of your API know that the return value changed.



标签: phpdoc