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类是从模型中覆盖某些方法的类,它使用控制台应用程序不支持的一些模块。
答案 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推进你想要的功能,如Traits和Traits in Yii。
鉴于它取决于你使用的是什么版本的php。但是在yii中你可以通过behaviors实现这一点并检查SOQ。
简而言之,您必须使用语言高级功能或YII框架功能来解决此类问题,但这可以归结为实际要求