PHP中trait使用方法详细介绍
程序员文章站
2024-03-09 10:22:17
说通俗点,php中使用trait关键字是为了解决一个类既想集成基类的属性和方法,又想拥有别的基类的方法,而trait一般情况下是和use搭配使用的。
<...
说通俗点,php中使用trait关键字是为了解决一个类既想集成基类的属性和方法,又想拥有别的基类的方法,而trait一般情况下是和use搭配使用的。
<?php trait drive { public $carname = 'trait'; public function driving() { echo "driving {$this->carname}\n"; } } class person { public function eat() { echo "eat\n"; } } class student extends person { use drive; public function study() { echo "study\n"; } } $student = new student(); $student->study(); $student->eat(); $student->driving(); ?>
输出结果如下:
study eat driving trait
上面的例子中,student类通过继承person,有了eat方法,通过组合drive,有了driving方法和属性carname。
如果trait、基类和本类中都存在某个同名的属性或者方法,最终会保留哪一个呢?
<?php trait drive { public function hello() { echo "hello drive\n"; } public function driving() { echo "driving from drive\n"; } } class person { public function hello() { echo "hello person\n"; } public function driving() { echo "driving from person\n"; } } class student extends person { use drive; public function hello() { echo "hello student\n"; } } $student = new student(); $student->hello(); $student->driving(); ?>
输出结果如下:
hello student driving from drive
因此得出结论:当方法或属性同名时,当前类中的方法会覆盖 trait的 方法,而 trait 的方法又覆盖了基类中的方法。
如果要组合多个trait,通过逗号分隔 trait名称:
use trait1, trait2;
如果多个trait中包含同名方法或者属性时,会怎样呢?答案是当组合的多个trait包含同名属性或者方法时,需要明确声明解决冲突,否则会产生一个致命错误。
<?php trait trait1 { public function hello() { echo "trait1::hello\n"; } public function hi() { echo "trait1::hi\n"; } } trait trait2 { public function hello() { echo "trait2::hello\n"; } public function hi() { echo "trait2::hi\n"; } } class class1 { use trait1, trait2; } ?>
输出结果如下:
复制代码 代码如下:
php fatal error: trait method hello has not been applied, because there are collisions with other trait methods on class1 in ~/php54/trait_3.php on line 20
使用insteadof和as操作符来解决冲突,insteadof是使用某个方法替代另一个,而as是给方法取一个别名,具体用法请看代码:
<?php trait trait1 { public function hello() { echo "trait1::hello\n"; } public function hi() { echo "trait1::hi\n"; } } trait trait2 { public function hello() { echo "trait2::hello\n"; } public function hi() { echo "trait2::hi\n"; } } class class1 { use trait1, trait2 { trait2::hello insteadof trait1; trait1::hi insteadof trait2; } } class class2 { use trait1, trait2 { trait2::hello insteadof trait1; trait1::hi insteadof trait2; trait2::hi as hei; trait1::hello as hehe; } } $obj1 = new class1(); $obj1->hello(); $obj1->hi(); echo "\n"; $obj2 = new class2(); $obj2->hello(); $obj2->hi(); $obj2->hei(); $obj2->hehe(); ?>
输出结果如下:
trait2::hello trait1::hi trait2::hello trait1::hi trait2::hi trait1::hello
as关键词还有另外一个用途,那就是修改方法的访问控制:
trait 也能组合trait,trait中支持抽象方法、静态属性及静态方法,测试代码如下:
<?php trait hello { public function sayhello() { echo "hello\n"; } } trait world { use hello; public function sayworld() { echo "world\n"; } abstract public function getworld(); public function inc() { static $c = 0; $c = $c + 1; echo "$c\n"; } public static function dosomething() { echo "doing something\n"; } } class helloworld { use world; public function getworld() { return 'get world'; } } $obj = new helloworld(); $obj->sayhello(); $obj->sayworld(); echo $obj->getworld() . "\n"; helloworld::dosomething(); $obj->inc(); $obj->inc(); ?>
输出结果如下:
hello world get world doing something 1 2
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: PHP中trait使用方法详细介绍
下一篇: Java实现双向链表(两个版本)