2016-03-28 77 views
1

假設我有一個trait和一個類,每個類都有一個名稱相同的方法,但類的方法是靜態的,而特徵的方法不是。是否可以定義一個既能從這個類繼承又能使用這個特性的類?如何使用與靜態方法衝突的非靜態方法的特質?

在代碼中,這看起來像

trait MyTrait 
{ 
    public function doStuff() 
    { 
     return 'trait'; 
    } 
} 

class ParentClass 
{ 
    public static function doStuff() 
    { 
     return 'parent'; 
    } 
} 

class ChildClass extends ParentClass // I'm feeling really original today apparently 
{ 
    use MyTrait; 
} 

我首先想到的是別名對該性狀的方法,像

class ChildClass extends ParentClass 
{ 
    use MyTrait { 
     doStuff as doOtherStuff; 
    } 
} 

但似乎性狀仍試圖覆蓋方法從父類,所以這會引發錯誤

Cannot make static method ParentClass::doStuff() non static in class MyTrait 

是我想要做的可能嗎?如果是這樣,怎麼樣?如果不是,請解釋爲什麼不。謝謝!

編輯
不幸的是,改變方法名是不是對我來說是可行的選擇,因爲這兩個類和特質是相當廣泛的應用在應用程序中的其他部分。根據the PHP docs,特徵的方法總是覆蓋繼承的方法。 (如果你將ParentClass::doStuff改爲非靜態的,你可以在工作中看到這個,但這不是我可以做的任何事情。)也許我要問的是,是否有可能讓特質的方法不是重寫繼承靜態方法(這似乎是正常的行爲)?

我還創建了第二個特徵,其別名MyTrait::doStuffdoOtherStuff並使用它來代替。

trait MyTrait2 
{ 
    use MyTrait { 
     doStuff as doOtherStuff; 
    } 
} 

class ChildClass extends ParentClass 
{ 
    use MyTrait2; 
} 

但是,這產生了同樣的錯誤,我覺得很奇怪。

Cannot make static method ParentClass::doStuff() non static in class MyTrait2 

回答

0

這可能是一種誤解。靜態方法和非靜態方法不應該做同樣的工作,所以應該有不同的名稱,也許你的名字不夠明確。

你不能這樣做,因爲當你創建一個別名時,舊名和新名都存在。因此,「doStuff」仍然存在,它會與ParentClass產生衝突。

見這個例子:

trait MyTrait 
{ 
    public function doStuff() 
    { 
     return 'foo'; 
    } 
} 

class Foo 
{ 
    use MyTrait { 
     doStuff as doOtherStuff; 
    } 
} 

echo Foo::doStuff(); // doStuff still works 
+0

權。我同意你在這裏的想法,並發現如果這個類的方法是非靜態的,那麼這個特性將覆蓋它。但改變方法名稱對我來說不是一個可行的選擇。父類和特性都在我正在使用的應用程序中廣泛使用,所以更改這兩者都是一件痛苦的事情。 –