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

UPDATE 上の親は ActiveRecord クラス、中間は私のモデル オブジェクトです。yii ConsoleApplication でモデルを使用したい。このモデルでは 'user' モジュールを使用していますが、コンソール アプリはこのモジュールをサポートしていません。そのため、ユーザー モジュールが呼び出されるメソッド afterFind をオーバーライドする必要があります。したがって、Target クラスは、コンソール アプリケーションがサポートしないいくつかのモジュールを使用するモデルからいくつかのメソッドをオーバーライドするクラスです。

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

実際には、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 に答える
1

直接 - できません。これがOOPの仕組みです。

MidParent add メソッドなど、少し再設計することでそれを行うことができます。

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

そしてターゲットで:

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

ただし、繰り返しますが、これは質問を解決するための回避策にすぎず、解決策ではありません。

于 2013-11-06T09:38:14.733 に答える
0

@AnatoliyGusarov、あなたの質問は興味深いものであり、ある意味では、yii を使用して望むものを達成でき、YiiのTraitsやTraits などの PHP の高度な機能を実現できます。

使用している php のバージョンによって異なりますが、yii では動作によってこれを達成し、このSOQを確認できます。

一言で言えば、言語の高度な機能または YII フレームワークの機能を使用して、この種の問題を回避する必要がありますが、それは実際の要件に要約されます

于 2013-11-06T10:36:33.580 に答える