是否可以取消父类中的函数重写并使用顶级父级的函数

时间:2013-11-06 09:30:50

标签: php oop yii polymorphism encapsulation

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类,mid是我的模型对象。我想在yii ConsoleApplication中使用model。我在此模型中使用“user”模块,而控制台应用程序不支持此模块。所以我需要覆盖调用用户模块的方法afterFind。所以Target类是从模型中覆盖某些方法的类,它使用控制台应用程序不支持的一些模块。

4 个答案:

答案 0 :(得分:2)

试试这个(http://php.net/manual/en/language.oop5.final.php - 不允许覆盖孩子们):

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

和类Target无法覆盖此方法。

答案 1 :(得分:1)

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

你可以通过一点重新设计来做到这一点,例如在MidParent添加方法:

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

并在目标中:

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

但是,再一次,这只是解决问题而不是解决方案的解决方法。

答案 2 :(得分: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 

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

答案 3 :(得分:0)

@AnatoliyGusarov,你的问题很有意思,从某种意义上说,你可以使用yii和php推进你想要的功能,如TraitsTraits in Yii

鉴于它取决于你使用的是什么版本的php。但是在yii中你可以通过behaviors实现这一点并检查SOQ

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