让我们看一个基本的课程:
class A
{
public function renderSomethingRecursive()
{
//this function can call itself
self::renderSomethingRecursive(); // ERROR!!!!
}
abstract public function addSomething (value);
}
class B extends A
{
public function renderSomethingRecursive()
{
throw new Exception ('This time this method must not be called!');
}
public function addSomething (value)
{
//something, something, something....
parent::renderSomethingRecursive();
}
}
$obj = new B();
$obj->addSomething(....);
当我执行此操作时,B::renderSomethingRecursive()
仍然被调用,我不希望...在A:renderSomethingRecursive()
方法,self::renderSomethingRecursive(); // ERROR!!!!
行调用B::renderSomethingRecursive();
而不是 A::renderSomethingRecursive();
,这是合理的,因为$this
现在是B
而不是A
......但我不知道如何躲闪它。
B::renderSomethingRecursive()
方法应该被删除,但我想保留它作为一个通知,它不能被意外调用。我想做到这一点"私人"使这个不可用,但正如我们所知,它是不可能的:))
有什么想法吗?
答案 0 :(得分:2)
如果您不希望调用该方法,为什么要在B
中定义该方法。只是不要定义它,PHP只能调用一种方法。这样,您就不必使用parent::theMethod
,只需使用this->theMethod();
Abstract class A
{
public function renderSomethingRecursive()
{
$this->renderSomethingRecursive(); // no need for self::, that's for static calls
}
abstract public function addSomething (value);
}
class B extends A
{
public function addSomething (value)
{
$this->renderSomethingRecursive();//calls the abstract method as though it were defined in class B
}
}
这就是全部,真的
答案 1 :(得分:2)
为什么不重构支持组合而不是继承呢?如果你开始将“添加内容”和“递归某些内容”拆分为单独的问题,那么你会发现自己拥有更小,更容易理解的类,它们可以很好地协同工作。
由于您不希望B
的呼叫者能够呼叫renderSomethingRecursive()
,因此完全从该课程中删除该功能。同样打破继承,B
不需要继承A
。
我们仍然希望B
能够“添加内容”,因此它会保留一个名为addSomething()
的函数。由于我们不希望在这两个类中复制addSomething
的正文,因此只要B
被调用A
,我就可以B::addSomething
委托给abstract class A
{
public function renderSomethingRecursive()
{
// this function can call itself
self::renderSomethingRecursive();
}
abstract function addSomething ($value) {
}
class AA extends A
{
public function addSomething($value)
{
// something, something, something....
self::renderSomethingRecursive();
}
}
class B
{
private $a;
public function __construct(A $a)
{
$this->a = $a;
}
public function addSomething ($value) {
$this->a->addSomething($value);
}
}
$obj = new B(new AA());
$obj->addSomething(....);
的实例。
addSomething
这已经越来越好了,但我们可以在完成之前摆脱这个重复的addSomething
。
渲染和管理列表实际上是两个不同的问题,所以让我们分开。首先,我们将B
移至renderSomethingRecursive
。然后我们意识到A
可能也需要访问$ data,我们可以添加一些参数,以便它可以再次访问该数据。 B
不再需要是抽象的,但addSomething
可能是class A
{
public function renderSomethingRecursive($data)
{
// this function can call itself
self::renderSomethingRecursive($data);
}
}
class B
{
private $a;
private $data;
public function __construct(A $a)
{
$this->a = $a;
}
public function addSomething ($value) {
// something, something, something....
// append to $this->data probably
$this->a->renderSomethingRecursive($this->data);
}
}
$obj = new B(new AA());
$obj->addSomething(....);
的不同实现。
你应该留下这样的东西......
{{1}}