[TOC] #### 1. trait 的介紹 --- 眾所周知,PHP 是單繼承的語言,也就是 PHP 中的類只能繼承一個父類,無法同時從多個基類中繼承屬性和方法,于是 PHP 實現(xiàn)了一種代碼復用的方法,稱之為 trait,使開發(fā)人員可以在不同層次結(jié)構(gòu)內(nèi)獨立的類中復用屬性和方法 trait 不是接口也不是類,不可以被實例化也不可以被繼承,只是用來將公共代碼(屬性和方法)提供給其他類使用的 #### 2. trait 的基礎用法 --- trait 的成員:trait 的成員只能有屬性和方法,不能定義類常量 ``` // 定義一個 trait trait Say { // 在 trait 中不能定義常量 // 報錯提示:Traits cannot have constants // const PI = 3.14; // 錯誤示例 // 屬性 public static $name = 'liang'; // 方法 public static function hello() { echo 'Hello World !'; } } class User { use Say; // 在類中引入 trait } // 測試輸出 echo User::$name; echo User::hello(); ``` #### 3. trait 的優(yōu)先級 --- 類成員和 trait 成員同名,屬性和方法有不同的處理 如果是屬性同名,PHP 直接拋出致命錯誤,方法同名則會有優(yōu)先級之分 優(yōu)先順序是來自當前類的成員覆蓋了 trait 的方法,而 trait 則覆蓋了被繼承的方法 ``` 當前類成員 > trait 成員 > 繼承的成員 ``` #### 4. trait 的 as 用法 --- ```php trait User { protected function hello() { echo 'user hello'; } } class Person { use User { # 起別名 hello as helloNewName; # 起別名并且修改方法的訪問控制 hello as public helloNewName; } } $o = new Person; $o->helloNewName(); // user hello ``` #### 5. 引入多個 trait 時的成員同名問題 --- 引入多個 trait 時,如果存在成員同名,那么 PHP 會直接拋出致命錯誤 為了解決多個 trait 在同一個類中的命名沖突,需要使用 insteadof 操作符來明確指定使用沖突方法中的哪一個 也就是需要使用 insteadof 操作符指定使用哪個 trait 中的成員 ```php trait User { public function hello() { echo 'user hello <br>'; } } trait Admin { public function hello() { echo 'admin hello <br>'; } } class Person { use User, Admin { // 指定 hello 方法應用哪個 trait 上的 Admin::hello insteadof User; // User 上的 hello 想要使用的話就定義個別名,不想使用可以不定義別名 User::hello as helloUser; } } $o = new Person; $o->hello(); $o->helloUser(); ```