在http://www.php.net/manual/zh/language.oop5.traits.php 查看了一下5.4.0提供的特性trait顺便做一个标记(总结);
首先要明确trait和类很相似,或是说类的一般特性它可以实现,但是它为什么会出现呢?
摘录“Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用方法集。Traits 和类组合的语义是定义了一种方式来减少复杂性,避免传统多继承和混入类(Mixin)相关的典型问题。”
在我理解说白了就是在继承类链中隔离了子类继承父类的某些特性(就是子类“要用父类的特性的时候”,如果trait有,就优先调用trait的方法、属性等)。
1、Trait 和一个类相似,Trait 不能通过它自身来实例化,应用类的成员不需要继承;
2、从基类继承的成员被 trait 插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法;
3、用use引入trait,可以引入多个
4、如果两个 trait 都插入了一个同名的方法,如果没有明确解决冲突将会产生一个致命错误,需要使用 insteadof 操作符来明确指定使用冲突方法中的哪一个,as 操作符可以将其中一个冲突的方法以另一个名称来引入(这里一会会说明在php那个版本会有bug,查看自己的环境测试一下。)
5、使用 as 语法还可以用来调整方法的访问控制。
6、trait 支持抽象方法的使用、类定义静态方法、可以定义属性
然后现在要做的是google一下bug trait 大概看了看
对于组合trait和解决命名冲突这里是存在问题的,5.4.11解决(参见http://git.php.net/?p=php-src.git;a=commitdiff;h=42437dd870de28eee6c9127f4c7e7c78ba8e0152;hp=7b0107cc5d3d90655957680ef9cf916dce6875a7) ;
trait定义的final方法没有从类继承的原则去考虑(我的v5.4.8 有这个问题),
对trait于final的方法跟父类同名会报错,
但是跟子类同名不但没问题,还调用子类的方法,(https://bugs.php.net/bug.php?id=62204)
开始的时候我还在想这里应该没问题,因为子类不是trait的实例(其实trait特性刚出来的时候子类可以通过instanceof验证是trait 片段(我就暂时这么叫着吧,不然叫方法或类也不合适)的实例,不过没过多久就修复了),所以不需要对final有约束,但是为毛他子类的父类有同名的final方法就会报错呢 ? 然后从代码复用的角度讲如果加入类继承的各种特性,那么其实就是中间类嘛?思前想后逻辑就混乱了呵呵
这里包含traits报告的bug,有时间自己还要盯一下
https://bugs.php.net/search.php?cmd=display&search_for=trait&x=-1582&y=-80