本文參考: http://php.net/language.oop5.traits
一、什么是trait
從PHP 5.4.0 開始 PHP 實現了一種新的代碼復用方式 trait。
二、trait解決了什么問題
trait 的出現是為了解決類似PHP的單繼承語言而准備的一種代碼復用機制,讓開發人員能夠在不能層次結構內獨立的類中復用 method。
三、跟其它語言相比,trait 有什么 好處
Trait 和 Class 組合的語義定義了一種減少復雜性的方式,避免傳統多繼承和 Mixin 類相關典型問題。
四、該如何使用trait
- 示例1,如何使用 trait
<?php trait ezcReflectionReturnInfo { function getReturnType() { /*1*/ } function getReturnDescription() { /*2*/ } } class ezcReflectionMethod extends ReflectionMethod { use ezcReflectionReturnInfo; /* ... */ } class ezcReflectionFunction extends ReflectionFunction { use ezcReflectionReturnInfo; /* ... */ } ?>
- 示例2 ,trait 與 class 方法優先級問題
trait 方法會覆蓋基類中的方法,當前類中的方法會覆蓋 trait 方法
<?php class Base { public function sayHello() { echo 'Hello '; } } trait SayWorld { public function sayHello() { parent::sayHello(); echo "World!\r\n"; } } class MyHelloWorld extends Base { use SayWorld; } class MyNewHelloWorld extends Base{ use SayWorld; public function sayHello(){ echo "Hello sunshine!\r\n"; } } $o = new MyHelloWorld(); $o->sayHello(); $b = new MyNewHelloWorld(); $b->sayHello(); ?>
上面的代碼會輸出:
- 示例3 同時使用多個 trait 通過逗號分隔,在 use 聲明列出多個 trait,可以都插入到一個類中。
<?php trait Hello { public function sayHello() { echo 'Hello '; } } trait World { public function sayWorld() { echo 'World'; } } class MyHelloWorld { use Hello, World; public function sayExclamationMark() { echo '!'; } } $o = new MyHelloWorld(); $o->sayHello(); $o->sayWorld(); $o->sayExclamationMark(); ?>
上面的代碼會輸出:
- 示例4 沖突的解決
如果兩個 trait 都插入了一個同名的方法,如果沒有明確解決沖突將會產生一個致命錯誤。
為了解決多個 trait 在同一個類中的命名沖突,需要使用 insteadof 操作符來明確指定使用沖突方法中的哪一個。
<?php trait A { public function smallTalk() { echo 'a'; } public function bigTalk() { echo 'A'; } } trait B { public function smallTalk() { echo 'b'; } public function bigTalk() { echo 'B'; } } class Talker { use A, B { B::smallTalk insteadof A; A::bigTalk insteadof B; } } class Aliased_Talker { use A, B { B::smallTalk insteadof A; A::bigTalk insteadof B; B::bigTalk as talk; } } ?>
- 示例5 使用trait來組成trait 正如 class 能夠使用 trait 一樣,其它 trait 也能夠使用 trait。在 trait 定義時通過使用一個或多個 trait,能夠組合其它 trait 中的部分或全部成員。
<?php trait Hello { public function sayHello() { echo 'Hello '; } } trait World { public function sayWorld() { echo 'World!'; } } trait HelloWorld { use Hello, World; } class MyHelloWorld { use HelloWorld; } $o = new MyHelloWorld(); $o->sayHello(); $o->sayWorld(); ?>
上面例子會輸出:
除了這些特性,trait 還包括 抽象成員 靜態成員 靜態方法 屬性 等特性,可以參考 http://php.net/language.oop5.traits