在php的面向對象開發中,咱們常常會遇到這樣的一種狀況:php
有兩個類 teacher 和 pupil類這兩個類都有以下的一些屬性this
age,sex,address,school,email等。爲此,咱們抽象出了一個父類爲 human類code
<?php #traits 是 php5.4 中新引入的一個特性 class human{ public $name; public $age; public $sex; public $address; public $school; public $email; public function __construct(){ // :todo } public function setName($name){ $this->name = $name; } public function setSex($sex){ $this->sex = $sex; } public fucntion getSex(){ return $this->sex; } public function getName($name){ return $this->name; } // ..... } class teacher extends human{ protected $salary; public function teach(){ //.... } public function getSalary(){ return $this->salary; } } class pupil extends human{ protected $schoolAge; public function learning(){ //.... } public function getSchoolAge(){ return $this->schoolAge; } } ?>
上面的代碼對以上的場景顯然是合適的,可是如今咱們遇到這樣的一種狀況。如今出現了一個寵物好比說:企鵝(holly)。對象
企鵝(holly)的出現讓上面的代碼不在能公用了。繼承
可是企鵝(holly)中又確確實實的存在某些能夠上上面的類公用的某些屬性:好比 name age sex 等!和一些私有的屬性:color,owner...開發
這樣的狀況下 咱們怎麼處理呢?get
有的人說把相應的公用的代碼和human類再進行一次的抽象 提取中公用的一個類 好比creature中!it
造成這樣的一種結構:io
這樣的處理方式是顯然可行的,可是出現了一種問題就是類會愈來愈多,使得系統顯得無比的龐大和臃腫!舉例來說未來又增長了一個玩具toys進來,有諸如function
shape color name 等屬性的話!咱們只能接着擴展相應的類並繼續的提取公用屬性 並抽象父類
極可能造成這樣的一種結構:
很顯然隨着系統的升級,類會愈來愈多,愈來愈不利於維護!
怎麼樣解決上面的問題呢?
在php5.4中 引入了traits,traits究竟是個什麼東西呢?官方給的解釋以下:Traits 是一種爲相似 PHP 的單繼承語言而準備的代碼複用機制。Trait 爲了減小單繼承語言的限制,使開發人員可以自由地在不一樣層次結構內獨立的類中複用方法集。Traits 和類組合的語義是定義了一種方式來減小複雜性,避免傳統多繼承和混入類(Mixin)相關的典型問題。
Traits能夠理解爲一組能被不一樣的類都能調用到的方法集合。但Traits不是類!不能被實例化。
以上面的例子說明以下:
<?php traits Common{ public $name; public $age; public $sex; public function getName(){ return $this->name; } public function getAge(){ return $this->age; } public function getSex(){ return $this->sex; } public function setAge($age){ $this->age=$age; } public function setSex($sex){ $this->sex=$sex; } public function setName($name){ $this->name=$name; } } class human { use Common; public $address; public $email; public $school; //............ } class teacher extends human{ //............. protected $salary; public function teach(){ //.... } public function getSalary(){ return $this->salary; } } class pupil extends human{ protected $schoolAge; public function learn(){ //.... } public function getSchoolAge(){ return $this->schoolAge; } } class pets { use Common; public $owner; public $color; public $feedOn; } ?>
這樣的狀況下 當咱們想擴展這個系統時,咱們只須要分析這個類是否是全部的對象均可用的就能夠對相應的代碼進行擴展,極大的下降了代碼的維護成本和難度!
舉例來說,若是咱們須要增長一個全體對象都存在的id時,咱們只須要擴展traits Common 中的代碼!若是咱們須要給pets 增長一個行動方式(爬行,飛行,遊)的屬性時,咱們只須要擴展pets類便可!
我的看法,多有謬誤,歡迎指正!轉載請說明出處,謝謝!