不需要的方法叫

时间:2012-10-28 17:24:45

标签: php oop polymorphism virtual-method

让我们看一个基本的课程:

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()方法应该被删除,但我想保留它作为一个通知,它不能被意外调用。我想做到这一点"私人"使这个不可用,但正如我们所知,它是不可能的:))

有什么想法吗?

2 个答案:

答案 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}}