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

Php 是否可以取消父类中的函数重写并使用顶级父类中的函数,php,oop,yii,polymorphism,encapsulation,Php,Oop,Yii,Polymorphism,Encapsulation,现在的问题是,如果我有一个类,它扩展了MidParent,因为我需要调用 class TopParent { protected function foo() { $this->bar(); } private function bar() { echo 'Bar'; } } class MidParent extends TopParent { protected function foo()

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

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';
    }
}
所以我需要这样做:

class Target extends MidParent
{
    //How to override this method to return TopParent::foo(); ?
    protected function foo()
    {
    }
}
更新
顶级父级是ActiveRecord类,mid是我的模型对象。我想在yii控制台应用程序中使用模型。我在此型号中使用“用户”模块,而控制台应用程序不支持此模块。所以我需要重写方法afterFind,在这里调用用户模块。所以目标类是重写模型中某些方法的类,该模型使用控制台应用程序不支持的某些模块

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

您可以通过稍微重新设计来完成,例如在MidParent add method中:

$mid = new MidParent();
$mid->foo(); // MidBar
$taget = new Target();
$target->generalMethod(); // General
$target->foo(); // Bar
在目标方面:

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

但是,同样,这只是一个解决问题的变通方法,而不是一个解决方案。

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

您可以通过稍微重新设计来完成,例如在MidParent add method中:

$mid = new MidParent();
$mid->foo(); // MidBar
$taget = new Target();
$target->generalMethod(); // General
$target->foo(); // Bar
在目标方面:

protected function parentFoo()
{
    parent::foo();
}
但是,同样,这只是解决您的问题的一种变通方法,而不是解决方案。

试试这个(-not allow to overriding in the childrens):

在类
MidParent
中,类
Target
无法重写此方法。

尝试此方法(-not allow to overriding in the childrens):

在类
MidParent
中,类
Target
不能重写此方法。

实际上,您可以通过以下方式执行此操作:

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

实际上,您可以通过以下方式使用:


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

@anatoligusarov,你的问题很有趣,从某种意义上说,你可以使用yii和php的高级功能,如和,实现你想要的

这取决于您使用的php版本。然而,在yii中,您可以通过检查来实现这一点


简而言之,您必须使用语言高级功能或YII框架功能来解决此类问题,但这归结为实际需求,您的问题很有趣,从某种意义上讲,您可以使用YII和php高级功能(如和)来实现所需

这取决于您使用的php版本。然而,在yii中,您可以通过检查来实现这一点


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

一个问题:为什么要这样做?简言之:不。如果您不想让代码这样做,请清理您的代码做什么以及它什么时候做。使Target::foo调用TopParent::bar?您认为需要这样做的事实表明您没有掌握OOP的概念。这是一个巨大的代码气味,我认为你能做的最好的事情是重新审视你的设计并重构。Re“为什么更新”:如果“控制台应用程序不支持模型中的某些东西,所以你需要更改模型”,这是一个可怕的代码气味。这两件事应该完全分开。模型总是以同样的方式工作,视图显示它能做什么。一个问题:为什么这样做?简言之:不。如果您不想让代码做,请清理代码做什么以及什么时候做。使Target::foo调用TopParent::bar?您认为需要这样做的事实表明您没有掌握OOP的概念。这是一个巨大的代码气味,我认为你能做的最好的事情是重新审视你的设计并重构。Re“为什么更新”:如果“控制台应用程序不支持模型中的某些东西,所以你需要更改模型”,这是一个可怕的代码气味。这两件事应该完全分开。模型总是以同样的方式工作,视图显示它所能显示的内容。我需要在目标中重写,但我也需要在目标中使用TopParent foo()。我需要在目标中重写,但我也需要在目标中使用TopParent foo()
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