在php的面向对象开发中,我们经常会遇到这样的一种情况:
有两个类 teacher 和 pupil类这两个类都有如下的一些属性
age,sex,address,school,email等。为此,我们抽象出了一个父类为 human类
<?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...
这样的情况下 我们怎么处理呢?
有的人说把相应的公用的代码和human类再进行一次的抽象 提取中公用的一个类 比如creature中!
形成这样的一种结构:
这样的处理方式是显然可行的,但是出现了一种问题就是类会越来越多,使得系统显得无比的庞大和臃肿!举例来讲将来又增加了一个玩具toys进来,有诸如
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类即可!
个人见解,多有谬误,欢迎指正!转载请说明出处,谢谢!