本质上trait本身是对类的一个扩展,在trait中使用$this ,self,static,parent都与当前类一样,zend底层将trait代码嵌入到类当中,相当于底层帮我们实现了代码复制功能
trait、继承和实例化的区别:
对于当前一个类需要用到另一个或多个类的方法的情况,我们一般会想到的方式有继承、直接实例化另外一个或多个类等等的方法,下面来对比一下这些方法和Trait类的区别:
继承方式:对于继承,可以完美地复用另一个类的一些方法,但是对于需要复用多个类的方法时,PHP是不支持多继承的,而且只能访问public和protected方法;与直接实例化的区别:我们也可以在当前类中直接实例化要用到的A类与B类,但是这种方法在控制访问范围反面,只允许访问A、B类中public的方法;使用Trait类则完全将A、B两个类的方法导入到当前类中,可以视为当前类的一部分,唯一区别是可以存在于当前类同名的方法,此时由优先级顺序来控制。调用
当前类, 可以直接调用 trait 中的所有方法和属性(因为相当于调用的是当前类中的属性和方法,所以trait 中的私有方法和属性都可以被调用)当前类的子类不可以调用 trait 中的私有方法和属性当前类和 trait 类中的方法会被重写, 但属性不会, 如果当前类和 trait 类中包含相同的属性则会报错. 但是当前类的子类的属性可以和 trait 里重复方法重复时的调用顺序: 当前类 > trait类> 父类其他
同一个类中可以同时trait 多个类Trait 中还支持定义抽象方法和静态方法,其中抽象方法必须在使用它的类中实现如果引入的 trait 类中有方法重复了会报错, 解决方案:
-
insteadof: 通过该关键字指定方法名冲突时该使用哪个Trait类的方法
use A, B {
B::a insteadof A; //a方法冲突时使用B类的a方法而不使用A类的a方法
A::b insteadof B; //b方法冲突时使用A类的b方法而不使用B类的b方法
}
-
as: 通过as关键字将同名方法指定为一个别名,且仅作用于当前类中
use A, B {
B::a as c; //声明B类的a方法为c,作用于该类
A::b as d; //声明A类的b方法为d,作用于该类 }
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。