0
class TopParent
{
    protected function foo()
    {
        $this->bar();
    }

    private function bar()
    {
       echo 'Bar';
    }
}

class MidParent extends TopParent
{
    protected function foo()
    {
        $this->midMethod();
        parent::foo();
    }

    public function midMethod()
    {
        echo 'Mid';
    }

    public function generalMethod()
    {
       echo 'General';
    }
}

现在的问题是,如果我有一个扩展 MidParent 的类,因为我需要调用

class Target extends MidParent
{
    //How to override this method to return TopParent::foo(); ?
    protected function foo()
    {
    }
}

所以我需要这样做:

$mid = new MidParent();
$mid->foo(); // MidBar
$taget = new Target();
$target->generalMethod(); // General
$target->foo(); // Bar

更新 顶级父级是 ActiveRecord 类,中间是我的模型对象。我想在 yii ConsoleApplication 中使用模型。我在这个模型中使用“用户”模块,控制台应用程序不支持这个模块。所以我需要覆盖调用用户模块的方法afterFind。因此,目标类是覆盖模型中某些方法的类,该模型使用控制台应用程序不支持的某些模块。

4

4 回答 4

2

试试这个(http://php.net/manual/en/language.oop5.final.php - 不允许在儿童中覆盖):

final protected function foo()
{
    $this->midMethod();
    parent::foo();
}

在类中MidParent,并且该类Target不能覆盖此方法。

于 2013-11-06T09:38:58.633 回答
1

直接 - 你不能。这就是 OOP 的工作原理。

您可以通过重新设计来做到这一点,例如在 MidParent add 方法中:

protected function parentFoo()
{
    parent::foo();
}

在目标中:

public function foo()
{
    $this->parentFoo();
}

但是,同样,这只是解决您的问题的解决方法,而不是解决方案。

于 2013-11-06T09:38:14.733 回答
1

实际上,您可以使用Reflection::getParentClass()这样做:

class Foo
{
   public function test($x, $y)
   {
      echo(sprintf('I am test of Foo with %s, %s'.PHP_EOL, $x, $y));
   }
}

class Bar extends Foo
{
   public function test()
   {
      echo('I am test of Bar'.PHP_EOL);
      parent::test();
   }
}

class Baz extends Bar
{
   public function test()
   {
      $class = new ReflectionClass(get_class($this));
      return call_user_func_array(
         [$class->getParentClass()->getParentClass()->getName(), 'test'],
         func_get_args()
      );
   }
}

$obj = new Baz();
$obj->test('bee', 'feo'); //I am test of Foo with bee, feo 

- 但这无论如何都是一种建筑气味。如果你需要这样的东西,那应该告诉你:你做错了什么。我不想推荐任何人使用这种方式,但既然它是可能的 - 就在这里。

于 2013-11-06T09:41:23.380 回答
0

@AnatoliyGusarov,您的问题很有趣,从某种意义上说,您可以使用 yii 和 php 高级功能(如Yii 中的Traits和Traits )来实现您想要的。

鉴于这取决于您使用的 php 版本。但是在 yii 中,您可以通过行为来实现这一点并检查此SOQ

简而言之,您必须使用语言高级功能或 YII 框架功能来解决此类问题,但这归结为实际需求

于 2013-11-06T10:36:33.580 回答