我有两个类几乎都有相同的方法,都叫做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
}
}
答案 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()
:
class myChild2 extends Parent
{
function myMethod()
{
parent::myMethod(true);
}
}
如果您愿意,您也可以将该标志作为类变量而不是函数参数传递。
检测调用类的名称
作为前一种方法的变体,您可以检测孩子的班级名称。有关详细信息,请查看get_class() PHP manual page中的评论。