2015-08-03 95 views
2

我陷入了一個我無法自己解決的問題。如何覆蓋抽象類中的特徵方法?

我有延伸的抽象類(對我來說這些都是幾個控制器類和抽象類Controller,所使用的框架不會是這裏很重要,因爲這是一個普遍的問題,PHP ...)類使用特質。我想重寫一個方法定義在其中的一個特點。這隻有在我的子類中定義方法但不在抽象類中時纔有效。


所以,這一個完美的作品:

class MyController extends Controller 
{ 
    use AnyTrait; 

    public function anyMethodFromAnyTrait() 
    { 
     // override AnyTrait::anyMethodFromAnyTrait() 
    } 
} 

我也知道如何從AnyTrait使用as調用anyMethodFromAnyTrait方法。

class MyController extends Controller 
{ 
    use AnyTrait { AnyTrait::anyMethodFromAnyTrait as method } 

    public function anyMethodFromAnyTrait() 
    { 
     // invoke AnyTrait::anyMethodFromAnyTrait() 
     $this->method(); 
    } 
} 

兩者都像魅力一樣工作。


但我的問題有點不同。

當使用特點,在我抽象類定義方法我不能夠覆蓋性狀的方法。

假設下列的控制器類:

class MyController extends Controller 
{ 
    public function anyAction() 
    { 
     // let's see what happens… 
     $this->anyMethodFromAnyTrait(); 
    } 
} 

...和抽象的多數民衆贊成由MyController擴展:

abstract class Controller 
{ 
    use AnyTrait 

    public function anyMethodFromAnyTrait() 
    { 
     // do something different than AnyTrait 
    } 
} 

...這是何等的不工作。每當我呼叫$this->anyMethodFromAnyTrait()MyController內,將調用在AnyTrait中實施的特徵的方法。我的摘要Controller中的同名方法將被忽略。

因此,我只能在具體子類中重寫trait的方法,但不能在由該子類擴展的抽象類中重寫。

因此,性狀中的方法定義比抽象類中的相同方法定義獲得PHP更高的優先級。

您是否知道該行爲的任何解決方法?

+0

我不能重現與PHP 5.5或PHP 7的行爲?請你把我鏈接到一個具體的http://3v4l.org重現案例? – bwoebi

+0

任何你不能在Controller中使用'使用AnyTrait {AnyTrait :: anyMethodFromAnyTrait作爲方法}的原因? – Marek

+0

您是否找到任何解決方案? – llioor

回答

1

一種解決方法是僅在子類中使用特徵。 PHP總是偏好「本地」特徵方法。

它在子類中工作的原因是超類的特徵方法被擴展,而不是特徵使用本身。

+0

感謝您的回覆。這種解決方法實際上是我想要避免的,因爲我可以想象出於某種原因使用抽象類。 ;-) – Arvid

+0

但是爲什麼使用一個特質的函數,然後在同一個類中覆蓋它? 你想實現什麼?或者它的功能「不需要」的特質? – devnull

+0

該功能絕對是想要的,這就是爲什麼我使用這個特質。但是我想通過在開頭添加幾行代碼來改變方法的行爲。不幸的是,這個特質是我正在使用的框架的一部分,因此我不能只是改變方法本身。 ...我想我會實現一個完整的其他解決方案,我不需要重寫特徵函數。 – Arvid

相關問題