Reputation: 9907
The following example does not work because when parent
is called in class A
, php looks for the parent class of class A
but it doesn't exist. I would rather this line to call Test()
in class B
.
Is this possible?
(I know this seems like a stupid example but it has a practical application)
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();
Thanks!
EDIT
I changed the parent
keyword to the made up method call_parent_method
because I think that may have been confusing people. I know there is no way to do this using the keyword.
Just as David Harkness pointed out, I am trying to implement the Template Method pattern but instead of using two different method names, I'm using one. B::Test()
will be the default method unless substituted with alternate functionality.
Upvotes: 6
Views: 6235
Reputation: 36532
You can use reflection to bypass the natural calling order for overridden methods. In any context simply create a ReflectionMethod
for the method you'd like to call and invoke it. You don't need to do this from the class itself, but you will need to call setAccessible(true)
if the method isn't public.
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();
The output from this is
Hi from C
Hi from A
Hi from B
You could make bypassOverride()
more generic and move it to a helper class if you need to do this a lot.
Upvotes: 6
Reputation: 36532
webbiedave is correct regarding parent
, but it looks like you're trying to implement the Template Method pattern where the abstract base class calls a method that subclasses are expected to implement. Here's an example that demonstrates a horrible way to handle errors in your applications.
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
Here doIt()
is the template method as it defines the overall algorithm to follow.
Upvotes: 1
Reputation: 48897
Is this possible?
No.
It makes no sense to use the parent
keyword except in child classes. It's only purpose is to be used by child classes to call methods that it as overridden. Think about multi-level parent calls where a child calls its parent's method of the same name and, in turn, that parent calls its parent's method of the same name.
Upvotes: 1