在http://www.php.net/manual/zh/language.oop5.traits.php 查看了一下5.4.0提供的特性trait順便做一個標記(總結);
首先要明確trait和類很相似,或是說類的一般特性它可以實現,但是它為什么會出現呢?
摘錄“Trait 為了減少單繼承語言的限制,使開發人員能夠自由地在不同層次結構內獨立的類中復用方法集。Traits 和類組合的語義是定義了一種方式來減少復雜性,避免傳統多繼承和混入類(Mixin)相關的典型問題。”
在我理解說白了就是在繼承類鏈中隔離了子類繼承父類的某些特性(就是子類“要用父類的特性的時候”,如果trait有,就優先調用trait的方法、屬性等)。
1、Trait 和一個類相似,Trait 不能通過它自身來實例化,應用類的成員不需要繼承;
2、從基類繼承的成員被 trait 插入的成員所覆蓋。優先順序是來自當前類的成員覆蓋了 trait 的方法,而 trait 則覆蓋了被繼承的方法;
3、用use引入trait,可以引入多個
4、如果兩個 trait 都插入了一個同名的方法,如果沒有明確解決沖突將會產生一個致命錯誤,需要使用 insteadof 操作符來明確指定使用沖突方法中的哪一個,as 操作符可以將其中一個沖突的方法以另一個名稱來引入(這里一會會說明在php那個版本會有bug,查看自己的環境測試一下。)
5、使用 as 語法還可以用來調整方法的訪問控制。
6、trait 支持抽象方法的使用、類定義靜態方法、可以定義屬性
然后現在要做的是google一下bug trait 大概看了看
對於組合trait和解決命名沖突這里是存在問題的,5.4.11解決(參見http://git.php.net/?p=php-src.git;a=commitdiff;h=42437dd870de28eee6c9127f4c7e7c78ba8e0152;hp=7b0107cc5d3d90655957680ef9cf916dce6875a7) ;
trait定義的final方法沒有從類繼承的原則去考慮(我的v5.4.8 有這個問題),
對trait於final的方法跟父類同名會報錯,
但是跟子類同名不但沒問題,還調用子類的方法,(https://bugs.php.net/bug.php?id=62204)
開始的時候我還在想這里應該沒問題,因為子類不是trait的實例(其實trait特性剛出來的時候子類可以通過instanceof驗證是trait 片段(我就暫時這么叫着吧,不然叫方法或類也不合適)的實例,不過沒過多久就修復了),所以不需要對final有約束,但是為毛他子類的父類有同名的final方法就會報錯呢 ? 然后從代碼復用的角度講如果加入類繼承的各種特性,那么其實就是中間類嘛?思前想后邏輯就混亂了呵呵
這里包含traits報告的bug,有時間自己還要盯一下
https://bugs.php.net/search.php?cmd=display&search_for=trait&x=-1582&y=-80