从基类调用继承类的父方法

时间:2012-01-14 00:07:14

标签: php inheritance

以下示例不起作用,因为在类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()将是默认方法,除非替换为替代功能。

3 个答案:

答案 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()是模板方法,因为它定义了要遵循的整体算法。