php - trait

本质上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 类中有方法重复了会报错, 解决方案:
    1. insteadof: 通过该关键字指定方法名冲突时该使用哪个Trait类的方法

          use A, B {
                B::a insteadof A; //a方法冲突时使用B类的a方法而不使用A类的a方法
                A::b insteadof B; //b方法冲突时使用A类的b方法而不使用B类的b方法
              }
    2. as: 通过as关键字将同名方法指定为一个别名,且仅作用于当前类中

          use A, B {
            B::a as c; //声明B类的a方法为c,作用于该类
            A::b as d; //声明A类的b方法为d,作用于该类    }

    最后编辑于
    ©著作权归作者所有,转载或内容合作请联系作者
    平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

    推荐阅读更多精彩内容

    • 官方解释 自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait。 Trait...
      钧辉阅读 283评论 0 1
    • 查看框架源码的时候,发现trait这一个东西,在它里面可以定义属性和方法,很像类,但是却不是类。 1.和类的区别:...
      JuMinggniMuJ阅读 499评论 0 0
    • 自PHP5.4之前,PHP面向对象需要复用代码的方式是使用类的继承。但PHP只支持单继承,在应对较复杂的业务逻辑中...
      闲睡猫阅读 375评论 0 2
    • Trait PHP 实现了一种代码复用的方法,称为trait。Trait是类似PHP的单继承语言而准备的一种代码复...
      NoFacePeace阅读 193评论 0 0
    • Trait是自 PHP 5.4.0 起添加的一个新特性,是 PHP 多重继承的一种解决方案。例如,需要同时继承两个...
      BULL_DEBUG阅读 438评论 0 2