在子类中覆盖公共方法,以限制公共访问,同时仍允许从父类访问? [英] Override public method in subclass in a way that restricts public access while still allowing access from parent class?

查看:157
本文介绍了在子类中覆盖公共方法,以限制公共访问,同时仍允许从父类访问?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个通用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆