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 ...?
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