Override public method in subclass in a way that restricts public access while still allowing access from parent class?

蓝咒 提交于 2019-12-04 06:19:36

问题


I have a generic Collection class, with a variety of public getter methods.

To get one item from the Collection, you call get(). There are also several methods that return multiple items: getMany(), getRange(), getAll(), find(), findAll(), query(), queryAny(), etc.

Internally, all of these methods that return multiple items have a loop that calls get() repeatedly, as they aggregate the individual items to return.

A simplified example:

public function get($key){
    return $this->collection[$key];
}

public function getMany($keys){

    $many = array();

    foreach ($keys as $key){
        $many[] = $this->get($key);
    }

    return $many;
}

The problem arises when I want to extend Collection in such a way that I don't want the client to be able to access a single item from the Collection. Basically, I want to disallow access to the get() method.

I can't make get() a private or protected function, because it's public in the parent class.

I also can't override get() in such a way that makes it non-functional (i.e. override it with just a return, or throw an Exception), because all the other methods rely on get(), and I want them to remain functional.

I know I could just override all the methods that rely on get() to rely on some new protected method (i.e. getOne()), but that would violate DRY principles.

WHAT I DON'T WANT TO DO:

class DataSet extends Collection{

    public function get(){
        throw new Exception('get() not implemented in DataSet');
    }

    protected function getOne($key){
        return parent::get($key);
    }    

    public function getMany($keys){

        $many = array();

        foreach ($keys as $key){
            $many[] = $this->getOne($key);
        }

        return $many;
     }
}

If I did the above, I'd have to override a half-dozen methods (some of which are quite complex), and they'd only differ from the parent class' method by a few characters.

So ... what other options do I have? Are there different means to the same end ...?


回答1:


What you could do is make a protected method say _get and this can be what all the methods call internally. You can then expose a get method on all the classes that need access and just have it call _get.



来源:https://stackoverflow.com/questions/1977027/override-public-method-in-subclass-in-a-way-that-restricts-public-access-while-s

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!