网站首页 语言 会计 电脑 医学 资格证 职场 文艺体育 范文
当前位置:书香门第 > 计算机 > php语言

PHP中trait的使用方法

栏目: php语言 / 发布于: / 人气:2.54W

PHP中使用trait关键字是为了解决一个类既想集成基类的属性和方法,下面是小编为大家整理的PHP中trait的使用方法,欢迎参考~

PHP中trait的使用方法

?

123456789101112131415161718192021222324trait Drive { public$carName='trait'; publicfunctiondriving() { echo"driving {$this->carName}"; } } classPerson { publicfunctioneat() { echo"eat"; } } classStudentextendsPerson { useDrive; publicfunctionstudy() { echo"study"; } } $student=newStudent(); $student->study(); $student->eat(); $student->driving(); ?>

输出结果如下:

?

123study eat driving trait

上面的例子中,Student类通过继承Person,有了eat方法,通过组合Drive,有了driving方法和属性carName。

如果Trait、基类和本类中都存在某个同名的属性或者方法,最终会保留哪一个呢?

?

123456789101112131415161718192021222324252627trait Drive { publicfunctionhello() { echo"hello drive"; } publicfunctiondriving() { echo"driving from drive"; } } classPerson { publicfunctionhello() { echo"hello person"; } publicfunctiondriving() { echo"driving from person"; } } classStudentextendsPerson { useDrive; publicfunctionhello() { echo"hello student"; } } $student=newStudent(); $student->hello(); $student->driving(); ?>

输出结果如下:

?

12hello student driving from drive

因此得出结论:当方法或属性同名时,当前类中的方法会覆盖 trait的 方法,而 trait 的.方法又覆盖了基类中的方法。

如果要组合多个Trait,通过逗号分隔 Trait名称:

?

1use Trait1, Trait2;

如果多个Trait中包含同名方法或者属性时,会怎样呢?答案是当组合的多个Trait包含同名属性或者方法时,需要明确声明解决冲突,否则会产生一个致命错误。

?

123456789101112131415161718192021trait Trait1 { publicfunctionhello() { echo"Trait1::hello"; } publicfunctionhi() { echo"Trait1::hi"; } } trait Trait2 { publicfunctionhello() { echo"Trait2::hello"; } publicfunctionhi() { echo"Trait2::hi"; } } classClass1 { useTrait1, Trait2; } ?>

输出结果如下:

复制代码 代码如下:

PHP Fatal error: Trait method hello has not been applied, because there are collisions with other trait methods on Class1 in ~/php54/trait_ on line 20

使用insteadof和as操作符来解决冲突,insteadof是使用某个方法替代另一个,而as是给方法取一个别名,具体用法请看代码:

?

1234567891011121314151617181920212223242526272829303132333435363738394041trait Trait1 { publicfunctionhello() { echo"Trait1::hello"; } publicfunctionhi() { echo"Trait1::hi"; } } trait Trait2 { publicfunctionhello() { echo"Trait2::hello"; } publicfunctionhi() { echo"Trait2::hi"; } } classClass1 { useTrait1, Trait2 { Trait2::hello insteadof Trait1; Trait1::hi insteadof Trait2; } } classClass2 { useTrait1, Trait2 { Trait2::hello insteadof Trait1; Trait1::hi insteadof Trait2; Trait2::hiashei; Trait1::helloashehe; } } $Obj1=newClass1(); $Obj1->hello(); $Obj1->hi(); echo""; $Obj2=newClass2(); $Obj2->hello(); $Obj2->hi(); $Obj2->hei(); $Obj2->hehe(); ?>

输出结果如下:

?

1234567Trait2::hello Trait1::hi Trait2::hello Trait1::hi Trait2::hi Trait1::hello

as关键词还有另外一个用途,那就是修改方法的访问控制:

Trait 也能组合Trait,Trait中支持抽象方法、静态属性及静态方法,测试代码如下:

?

1234567891011121314151617181920212223242526272829303132333435trait Hello { publicfunctionsayHello() { echo"Hello"; } } trait World { useHello; publicfunctionsayWorld() { echo"World"; } abstractpublicfunctiongetWorld(); publicfunctioninc() { static$c= 0; $c=$c+ 1; echo"$c"; } publicstaticfunctiondoSomething() { echo"Doing something"; } } classHelloWorld { useWorld; publicfunctiongetWorld() { return'get World'; } } $Obj=newHelloWorld(); $Obj->sayHello(); $Obj->sayWorld(); echo$Obj->getWorld() .""; HelloWorld::doSomething(); $Obj->inc(); $Obj->inc(); ?>

输出结果如下:

?

123456Hello World get World Doing something 1 2

Tags:PHP trait