user1032531
user1032531

Reputation: 26281

Modifing method used by two classes

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

Answers (3)

George Cummins
George Cummins

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

Jon Newmuis
Jon Newmuis

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

mario.schlipf
mario.schlipf

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

Related Questions