2016-04-26 59 views
1

我有一個PHP特質的問題。 我想在課堂上和課堂中使用的特質中使用特質。PHP:在類和其他性狀相互衝突的性狀

例子:

trait Loggable { 
    protected function log(msg) { 
    echo msg; 
    } 
} 

trait SomeOtherTrait { 
    use Loggable; 
} 

class MyClass { 
    use SomeOtherTrait, Loggable; 
} 

但是這導致了衝突,因爲可記錄的是在課堂上使用兩次(一次在課堂上,一旦通過其他性狀),但由於封裝我不明白的問題功能是什麼特質,是嗎? 所以我只是想使用的日誌方法無處不在我包括可記錄性狀...

所以問題是:爲什麼我有碰撞?兩者(特質和班級)都指向相同的特質和方法,所以它不應該是衝突。

+0

的可能的複製(http://stackoverflow.com/questions/13582061/how-to -use-a-trait-several-in-a-class) –

+0

不幸的是,這個解決方案不起作用。將SomeOtherTrait改爲'使用Loggable {log as traitLog; }'然後'$ this-> traitLog(...)'給出相同的錯誤 – JaschaL

+0

特徵不能替代多重繼承。它只是複製粘貼的替代品。在這種情況下,你粘貼了相同的特徵兩次,所以所有的方法出現兩次。解決方案非常簡單,只是不要在頂層包含'Loggable'。 – Evert

回答

1

SomeOtherTrait使用特徵Loggable,因此您可以訪問Loggable的所有受保護和公共成員,同樣適用於使用SomeOtherTrait的所有類。在這裏您可以訪問Loggable和SomeOtherTrait的所有公共和受保護成員。

trait Loggable { 
    protected function log($msg) { 
     echo $msg; 
    } 
} 

trait SomeOtherTrait { 
    use Loggable; 
} 

class MyClass { 
    use SomeOtherTrait; 

    public function test() 
    { 
     $this->log("test"); 
    } 
} 

$myClass = new MyClass(); 

$myClass->test(); 
1

使用特點副本其所有的方法和屬性的類。這與擴展不一樣。所以實際上你試圖複製相同的log方法兩次到MyClass

如果您確實需要/想要使用兩種特徵,則需要按照the manual中所述解決此衝突。例如:

class MyClass { 
    use SomeOtherTrait, Loggable { 
    SomeOtherTrait::log insteadof Loggable; 
    } 
} 

或者:?如何在課堂上使用的性狀幾次]

class MyClass { 
    use SomeOtherTrait, Loggable { 
    Loggable::log as originalLog; 
    SomeOtherTrait::log as overriddenLog; 
    } 

    public function test() { 
    $this->originalLog('Logged with Loggable'); 
    $this->overriddenLog('Logged with SomeOtherTrait'); 
    } 
}