自 php 5.4.0 起,php 實現了一種**復用的方法,稱為 trait。
1、類中的一般的特性trait都可以實現。但是要混入類中,而不是代替類
2、trait是為了減少單繼承語言的限制,例如需要同時繼承兩個抽象類,這是php語言不支援的功能,trait就是為了解決這個問題
在繼承類鏈中隔離了子類繼承父類的某些特性,相當於要用父類特性的時候,如果有trait在就優先呼叫trait的成員
一、trait的宣告
1、使用trait關鍵字。支援final,static和abstract等修飾詞,所以trait也就支援抽象方法的使用、類定義靜態方法,也可以定義屬性。
2、但trait無法如類一樣new例項化,因為trait就是用來混入類中使用的,不能單獨使用。如果拿inte***ce和trait模擬,trait會有更多方便的地方。
二、優先順序
從基類繼承的成員會被 trait 插入的成員所覆蓋。優先順序是來自當前類的成員覆蓋了 trait 的方法,而 trait 則覆蓋了被繼承的方法。
class base
}trait sayworld
}class myhelloworld extends base
$o = new myhelloworld();
$o->sayhello();//hello world!
三、多個trait
1、通過逗號分隔,在 use 宣告列出多個 trait,可以都插入到乙個類中。
trait hello
}trait world
}class myhelloworld
}$o = new myhelloworld();
$o->sayhello();//hello
$o->sayworld();//world
$o->sayexclamationmark();//!
2、衝突的解決
如果兩個 trait 都插入了乙個同名的方法,如果沒有明確解決衝突將會產生乙個致命錯誤。
為了解決多個 trait 在同乙個類中的命名衝突,需要使用 insteadof 操作符來明確指定使用衝突方法中的哪乙個。
以上方式僅允許排除掉其它方法,as 操作符可以 為某個方法引入別名。 注意,as 操作符不會對方法進行重新命名,也不會影響其方法。
trait a
public function bigtalk()
}trait b
public function bigtalk() }/*
在本例中 talker 使用了 trait a 和 b。由於 a 和 b 有衝突的方法,其定義了使用 trait b 中的 smalltalk 以及
trait a 中的 bigtalk。
*/class talker
}//aliased_talker 使用了 as 操作符來定義了 talk 來作為 b 的 bigtalk 的別名。
class aliased_talker
}$talker = new talker;
echo $talker->smalltalk();//b
echo $talker->bigtalk();//a
$aliased_talker = new aliased_talker;
echo $aliased_talker-> smalltalk();//b
echo $aliased_talker-> bigtalk();//a
echo $aliased_talker-> talk();//b
3、修改方法的訪問控制
使用 as 語法還可以用來調整方法的訪問控制。
trait helloworld
}// 修改 sayhello 的訪問控制
class myclass1
}// 給方法乙個改變了訪問控制的別名
// 原版 sayhello 的訪問控制則沒有發生變化
class myclass2
}
四、從 trait 來組成 trait
正如 class 能夠使用 trait 一樣,其它 trait 也能夠使用 trait。在 trait 定義時通過使用乙個或多個 trait,能夠組合其它 trait 中的部分或全部成員。
trait hello
}trait world
}trait helloworld
class myhelloworld
$o = new myhelloworld();
$o->sayhello();//hello
$o->sayworld();//world
五、trait 的抽象成員
為了對使用的類施加強制要求,trait 支援抽象方法的使用。
trait hello
abstract public function getworld();
}class myhelloworld
public function setworld($val)
}$myhelloworld = new myhelloworld;
$myhelloworld->setworld('america');
echo $myhelloworld->sayhelloworld();//hello america
六、trait 的靜態成員
traits 可以被靜態成員靜態方法定義。
trait counter
}class c1
class c2
$o = new c1(); $o->inc();$o->inc(); // echo 1 2
$p = new c2(); $p->inc(); // echo 1
trait staticexample
}class example
example::dosomething();
七、屬性
trait 定義了乙個屬性後,類就不能定義同樣名稱的屬性,否則會產生 fatal error。 有種情況例外:屬性是相容的(同樣的訪問可見度、初始預設值)。 但在 php 7.0 之前,即使屬性是相容的,也會有 e_strict 的提醒。
trait propertiestrait
class propertie***ample
$example = new propertie***ample;
$example->x;
trait propertiestrait
class propertie***ample
物件導向特性
三大特性 封裝 繼承 多型 封裝封裝屬性 1,私有化成員變數 2,提供get,set方法 3,在方法的內容加入控制語句 static靜態 修飾 成員屬性 方法 塊 static成員屬性 靜態變數,全域性變數 static成員 塊 用於初始化靜態變數 static成員方法 靜態方法 同一類中,在靜態方...
10 scala物件導向程式設計之Trait
1 將trait作為介面使用 2 trait中定義具體方法 3 trait定義具體字段 4 trait中定義抽象字段 5 為例項物件混入trait 6 trait呼叫鏈 7 在trait中覆蓋抽象方法 8 混合使用trait的具體方法和抽象方法 9 trait的構造機制 10 trait field...
物件導向特性 繼承
1 子類繼承父類的方法和字段 class computer 子類,膝上型電腦類 class notecomputer extends computer 2 不需要父類的字段和方法,那麼可以採用重寫的方法覆蓋掉父類的方法。class computer 子類,膝上型電腦類 class notecompu...