以下示例不起作用,因为在类parent
中调用A
时,php会查找类A
的父类,但它不存在。我希望这一行在课程Test()
中拨打B
。
这可能吗?
(我知道这似乎是一个愚蠢的例子,但它有一个实际应用)
abstract class A {
function CallParentTest()
{
return call_parent_method('Test');
}
}
abstract class B extends A {
function Test()
{
return 'test passed';
}
}
class C extends B {
function Test()
{
return $this->CallParentTest();
}
}
$object = new C();
echo $object->Test();
谢谢!
修改
我将parent
关键字更改为编组方法call_parent_method
,因为我认为这可能让人感到困惑。我知道使用关键字无法做到这一点。
就像David Harkness指出的那样,我正在尝试实现模板方法模式,但我没有使用两个不同的方法名称,而是使用了一个。 B::Test()
将是默认方法,除非替换为替代功能。
答案 0 :(得分:6)
您可以使用反射来绕过重写方法的自然调用顺序。在任何上下文中,只需为您要调用的方法创建ReflectionMethod
并调用它。您不需要从类本身执行此操作,但如果该方法不公开,则需要调用setAccessible(true)
。
class A {
public function bypassOverride() {
echo "Hi from A\n";
$r = new ReflectionMethod('B', 'override');
$r->invoke($this);
}
}
class B extends A {
public function override() {
echo "Hi from B\n";
}
}
class C extends B {
public function override() {
echo "Hi from C\n";
$this->bypassOverride();
}
}
$c = new C;
$c->override();
此输出是
Hi from C
Hi from A
Hi from B
如果您需要执行此操作,可以使bypassOverride()
更通用并将其移至辅助类。
答案 1 :(得分:1)
这可能吗?
没有
除了子类之外,使用parent
关键字是没有意义的。它的唯一目的是被子类用来调用它被覆盖的方法。考虑多级父调用,其中子调用其父类的同名方法,反过来,该父调用其父类的同名方法。
答案 2 :(得分:1)
关于parent
,webbiedave是正确的,但看起来你正在尝试实现Template Method模式,其中抽象基类调用一个子类应该实现的方法。这是一个示例,演示了处理应用程序错误的可怕方法。
abstract class ExceptionIgnorer {
public function doIt() {
try {
$this->actuallyDoIt();
}
catch (Exception $e) {
// ignore the problem and it might go away...
}
}
public abstract function actuallyDoit();
}
class ErrorThrower extends ExceptionIgnorer {
public function actuallyDoIt() {
throw new RuntimeException("This will be ignored");
}
}
$thrower = new ErrorThrower;
$thrower->doIt(); // no problem
此处doIt()
是模板方法,因为它定义了要遵循的整体算法。