您现在的位置是:首页>建站教程>基础入门

PHP中的trait详解

王青召个人博客 2023-02-02 基础入门 8655人已围观

简介trait是php5.4以后新增加的一个功能,可以将多个类中,共用的一些属性和方法提取出来做来公共trait类,就像是装配汽车的配件,如果你的类中要用到这些配件,就直接用use导入就可以了,相当于把trait中的代码复制到当前类中.

一、Trait是什么?

trait是php5.4以后新增加的一个功能,可以将多个类中,共用的一些属性和方法提取出来做来公共trait类,就像是装配汽车的配件,如果你的类中要用到这些配件,就直接用use导入就可以了,相当于把trait中的代码复制到当前类中.




二、Trait类的使用

简单地讲,Trait就是一种不同于继承的语法,定义一个trait类,在其他类中使用它则是采用use关键字,有点类似于命名空间的用法,但是含义不同。use关键字在一个类中引入Trait类后,相当于require或include了一段代码进来,不同之处在于use的Trait类与当前类是可以看做同一个类的,即当前类可以用$this关键字调用Trait类的方法。


简单例子:


//创建triat类Test1

trait Test1{

public $name = 'YzmCMS';

public function hello1(){

return 'Test1::hello1()';

}

}


//创建triat类Test2

trait Test2{

function hello2(){

return 'Test2::hello2()';

}

}


//创建Demo1类

class Demo1{

use Test1, Test2;  //引入Trait类

public function demo(){

return 'Demo1::demo()';

}

}



$obj = new Demo1;

echo $obj->hello1(); //访问trait类Test1中的hello1()

echo '<br>';

echo $obj->name; //访问ttrait类Test1中的$name属性

echo '<br>';

echo $obj->hello2(); //访问ttrait类Test1中的hello2()

可以看出当前类可以简单地use两个Trait类,并调用其中的方法,而不仅限于继承,只能使用一个父类的方法。




三、Trait类的访问控制

我们知道,继承的方式,如果基类是private修饰控制的,则子类是无法调用的。但是Trait不一样,因为它类似于Require到当前类中了,所以不管是public、protected或private都是可以在本类中直接使用的。




四、Trait类的优先级控制

Trait类与当前使用类、继承的基类之间的调用优先级顺序如下:


当前使用类>Trait类>继承的基类




五、多个Trait类的冲突控制

在PHP中,如果当前类use了两个Trait类,同时两个trait类都存在一个同名的方法,此时如果没有明确解决冲突将会产生一个致命错误。


例子:


trait A {

    public function smallTalk() {

        echo 'a';

    }

    public function bigTalk() {

        echo 'A';

    }

}

 

trait B {

    public function smallTalk() {

        echo 'b';

    }

    public function bigTalk() {

        echo 'B';

    }

}

 

class Aliased {

    use A, B {

        B::smallTalk insteadof A;

        A::bigTalk insteadof B;

        B::bigTalk as talk;

    }  //这里千万不要加分号 ;

}

$a = new Aliased();

$a->bigTalk();  //A

$a->talk();     //B

$a->smallTalk();  //b

1、insteadof关键字:通过该关键字指定方法名冲突时该使用哪个Trait类的方法,即:


如果C类use了A、B两个Trait类,且A、B两个类都存在a、b方法,则在C类use A、B类时使用insteadof声明冲突的解决方法即可:


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,作用于该类

}

六、与继承、直接实例化的区别

对于当前一个类需要用到另一个或多个类的方法的情况,我们一般会想到的方式有继承、直接实例化另外一个或多个类等等的方法,下面来对比一下这些方法和Trait类的区别:


1、继承方式:对于继承,可以完美地复用另一个类的一些方法,但是对于需要复用多个类的方法时,PHP是不支持多继承的,而且只能访问public和protected方法;


2、与直接实例化的区别:我们也可以在当前类中直接实例化要用到的A类与B类,但是这种方法在控制访问范围反面,只允许访问A、B类中public的方法;


3、使用Trait类则完全将A、B两个类的方法导入到当前类中,可以视为当前类的一部分,唯一区别是可以存在于当前类同名的方法,此时由优先级顺序来控制。


站点信息

  • 建站时间:2022年11月15日
  • 文章统计175 篇文章
  • 网站地图网站地图
  • 站长微信:扫描二维码,关注我

打赏本站

  • 如果你觉得本站很棒,可以通过扫码支付打赏哦!
  • 微信扫码:你说多少就多少~
  • 支付宝扫码:你说多少就多少~

客服在线

服务时间

周一至周日 9:00-21:00