以限制公共访问的方式覆盖子类中的公共方法,同时仍允许从父类访问?

时间:2009-12-29 21:22:35

标签: php class methods override public

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

要从Collection中获取一个项目,请调用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()和I希望他们保持功能。

我知道我可以覆盖依赖于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;
     }
}

如果我做了上述操作,我必须覆盖六种方法(其中一些非常复杂),并且它们与父类的方法只有几个字符不同。

那么......我还有其他选择吗?对同一端有不同的方法......?

1 个答案:

答案 0 :(得分:3)

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