在子类中覆盖公共方法,以限制公共访问,同时仍允许从父类访问? [英] Override public method in subclass in a way that restricts public access while still allowing access from parent class?
问题描述
我有一个通用Collection类,有各种公共getter方法。
I have a generic Collection class, with a variety of public getter methods.
要从集合中获取一个项目,请调用get()。还有几种方法返回多个项目:getMany(),getRange(),getAll(),find(),findAll(),query(),queryAny()等。
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.
在内部,所有这些返回多个项目的方法都有一个循环,它重复调用get(),因为它们聚合各个项目返回。
Internally, all of these methods that return multiple items have a loop that calls get() repeatedly, as they aggregate the individual items to return.
一个简单的例子:
public function get($key){
return $this->collection[$key];
}
public function getMany($keys){
$many = array();
foreach ($keys as $key){
$many[] = $this->get($key);
}
return $many;
}
问题出现在我想扩展Collection时,不希望客户端能够从集合访问单个项目。基本上,我想禁止访问get()方法。
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.
我不能让get()一个私有或保护的函数,因为它在父类中是public 。
I can't make get() a private or protected function, because it's public in the parent class.
我也不能以这样的方式覆盖get(),使它无法正常工作(即用一个返回覆盖它,或抛出一个异常),因为所有其他方法依赖于get(),并且我希望它们保持功能。
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.
我知道我可以覆盖所有依赖get对一些新的protected方法(即getOne()),但这将违反DRY原则。
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.
我不想做什么:
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 ...?
推荐答案
你可以做一个受保护的方法说 _get
,这可以是所有方法内部调用。然后,您可以在所有需要访问的类上暴露一个 get
方法,只需调用 _get
。
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
.
这篇关于在子类中覆盖公共方法,以限制公共访问,同时仍允许从父类访问?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!