2013-04-23 56 views
1

我有兩個幾乎相同的方法,都稱爲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 
    } 
} 

回答

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中的註釋。

+0

謝謝。看起來沒有完全清潔的解決方案。作爲第四個選項,請參閱schlimpf的建議。 – user1032531 2013-04-23 16:36:25

+0

方法1不能用於我的應用程序,因爲它不能獨立於myMethod()的其餘部分執行。你會推薦通過一個標誌或檢測類名嗎? – user1032531 2013-04-23 16:40:33

+0

檢測調用類名將需要更少的代碼行,因爲您不必重寫'myMethod()',而是使父項依賴於存在特定名稱的子項。如果這是我的代碼,我不得不在兩者之間做出選擇,我會選擇標誌選項。 – 2013-04-23 16:44:32

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

取決於什麼youre究竟在做,我覺得這是一個乾淨的解決方案

+0

我也想過這樣做,但不確定它是否更直觀的IF語句。 – user1032531 2013-04-23 16:37:48

+0

這不需要在實例變量上顯式調用'myChild :: templateMethod()'調用嗎?因爲'myParent :: myMethod()'會在不填充'$ someLocalVariable'的情況下執行對'templateMethod()'的調用。 – 2013-04-23 16:41:24

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

新穎的方法,但可能比我想要的要複雜一點。 – user1032531 2013-04-23 16:39:10