Reputation: 26281
I have two classes which have almost identical methods both called myMethod(), however, myChild2::myMethod() has a single extra line of code in it which uses a local variable. I would rather not duplicate the code in both child classes. I suppose I could move myMethod to myParent, and then add an if statement to detect which child class is calling the method, but I am guessing this is not right. What is the cleanest way to do this? Thank you
class myParent
{
//code...
}
class myChild1 extends myParent
{
public function myMethod()
{
// A bunch of code common to both myChild1::myMethod() and myChild2::myMethod() goes here
// A bunch more code common to both myChild1::myMethod() and myChild2::myMethod() goes here
}
}
class myChild2 extends myParent
{
public function myMethod()
{
// A bunch of code common to both myChild1::myMethod() and myChild2::myMethod() goes here
someOtherLineOfCode($someLocalVariable); // A single unique line of code goes here which uses a local variable
// A bunch more code common to both myChild1::myMethod() and myChild2::myMethod() goes here
}
}
Upvotes: 1
Views: 58
Reputation: 28906
There are a few options to accomplish your goal. The one you choose will depend on the purpose of the unique line.
Override the Method
First, you can myMethod()
in the parent, then override it in myChild2(), including the extra line and then calling the parent. This will work if the extra line of code can be executed independently from the rest of myMethod()
:
class myChild2 extends myParent
{
public function myMethod()
{
someOtherLineOfCode($someLocalVariable);
parent::myMethod();
}
}
Pass a flag parameter
If the order of execution is important, you can detect the need for the extra functionality at runtime:
class Parent
{
function myMethod($enableExtraFunctionality=false)
{
// Common stuff
if ($enableExtraFunctionality)
{
someOtherLineOfCode($someLocalVariable);
}
// More common stuff
}
}
then set the variable to be true only in myChild2()
:
class myChild2 extends Parent
{
function myMethod()
{
parent::myMethod(true);
}
}
If you wish, you can also pass that flag as a class variable instead of as a function parameter.
Detect the calling class's name
As a variation on the previous method, you can detect the child's class name. Check the comments in the get_class() PHP manual page for details.
Upvotes: 1
Reputation: 26502
I would say move it to myParent
and add a constructor parameter. Depends a bit on what someOtherLineOfCode
is, but you could at least just add a flag to determine whether or not to execute it, like so:
class myParent
{
public function __construct($shouldExecute) {
$this->$executeSomeOtherCode = $shouldExecute;
}
public function myMethod()
{
// A bunch of code common to both myChild1::myMethod() and myChild2::myMethod() goes here
if($this->$executeSomeOtherCode) {
someOtherLineOfCode($someLocalVariable); // A single unique line of code goes here which uses a local variable
}
// A bunch more code common to both myChild1::myMethod() and myChild2::myMethod() goes here
}
//code...
}
class myChild1 extends myParent
{
public function __construct()(
parent::__construct(FALSE);
// Do stuff specific for Bar
}
// Other code
}
class myChild2 extends myParent
{
public function __construct()(
parent::__construct(TRUE);
// Do stuff specific for Bar
}
// Other code
}
Upvotes: 1
Reputation: 1257
You could do it like this:
class myParent
{
public function myMethod()
{
// A bunch of code common to both myChild1::myMethod() and myChild2::myMethod() goes here
$this->templateMethod($someLocalVariable);
// A bunch more code common to both myChild1::myMethod() and myChild2::myMethod() goes here
}
protected function templateMethod($x) {}
}
class myChild2 extends myParent
{
protected function templateMethod($x) {
// some extra line
}
}
Depends on what youre exactly doing, I think this is a clean solution
Upvotes: 1