【问题标题】:Override public method in subclass in a way that restricts public access while still allowing access from parent class?以限制公共访问同时仍允许父类访问的方式覆盖子类中的公共方法?
【发布时间】:2010-12-30 22:14:06
【问题描述】:

我有一个通用的 Collection 类,具有各种公共 getter 方法。

要从集合中获取一项,请调用 get()。还有几种方法可以返回多个项目:getMany()、getRange()、getAll()、find()、findAll()、query()、queryAny() 等。

在内部,所有这些返回多个项目的方法都有一个重复调用 get() 的循环,因为它们聚合单个项目以返回。

一个简化的例子:

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 中的单个项目的方式扩展 Collection 时,就会出现问题。基本上,我想禁止访问 get() 方法。

我不能让 get() 成为私有或受保护的函数,因为它在父类中是公共的。

我也不能覆盖 get() 以使其不起作用(即只用返回覆盖它,或抛出异常),因为所有其他方法都依赖于 get(),而我希望它们保持正常运行。

我知道我可以重写所有依赖 get() 的方法来依赖一些新的受保护方法(即 getOne()),但这会违反 DRY 原则。

我不想做的事:

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

如果我执行上述操作,我将不得不重写六个方法(其中一些非常复杂),它们与父类的方法仅相差几个字符。

那么……我还有什么其他选择?是否有不同的手段达到同一目的...?

【问题讨论】:

    标签: php class methods overriding public


    【解决方案1】:

    你可以做一个受保护的方法说_get,这可以是所有方法内部调用的。然后,您可以在所有需要访问的类上公开一个get 方法,并让它调用_get

    【讨论】:

    • 天啊!这就是解决方案,隐藏在众目睽睽之下。我所有的努力都集中在在子类中寻找解决方案——我没有考虑改变父类。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-26
    • 1970-01-01
    • 2011-10-31
    • 1970-01-01
    • 2014-01-26
    • 1970-01-01
    • 2011-02-11
    相关资源
    最近更新 更多