修改两个类使用的方法

时间:2013-04-23 16:15:47

标签: php oop

我有两个类几乎都有相同的方法,都叫做myMethod(),但myChild2 :: myMethod()中有一行额外的代码,它使用了一个局部变量。我宁愿不复制两个子类中的代码。我想我可以将myMethod移动到myParent,然后添加一个if语句来检测哪个子类正在调用该方法,但我猜这是不对的。最干净的方法是什么?谢谢

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
    }
}

3 个答案:

答案 0 :(得分:1)

你可以这样做:

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
    }
}

取决于你究竟在做什么,我认为这是一个干净的解决方案

答案 1 :(得分:1)

我想说把它移到myParent并添加一个构造函数参数。取决于someOtherLineOfCode是什么,但你至少可以添加一个标志来确定是否执行它,如下所示:

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
}

答案 2 :(得分:1)

有几个选项可以实现您的目标。您选择的那个将取决于唯一线的目的。

覆盖方法

首先,您可以在父级中myMethod(),然后在myChild2()中覆盖它,包括额外的行,然后调用父级。如果额外的代码行可以独立于myMethod()的其余部分执行,那么这将起作用:

class myChild2 extends myParent
{
     public function myMethod()
     {
          someOtherLineOfCode($someLocalVariable);
          parent::myMethod();
      }
}

传递标记参数

如果执行顺序很重要,您可以在运行时检测是否需要额外的功能:

class Parent
{
     function myMethod($enableExtraFunctionality=false)
     {
          // Common stuff
          if ($enableExtraFunctionality) 
          {
               someOtherLineOfCode($someLocalVariable);
          }
          // More common stuff
      }
 }

然后仅在myChild2()

中将变量设置为true
 class myChild2 extends Parent
 {
     function myMethod()
     {
          parent::myMethod(true);
     }
  }

如果您愿意,您也可以将该标志作为类变量而不是函数参数传递。

检测调用类的名称

作为前一种方法的变体,您可以检测孩子的班级名称。有关详细信息,请查看get_class() PHP manual page中的评论。