批改状态:合格
老师批语:咱们是不是学得有点太多了, 希望大家要私下多努力
当我们引用两个trait,且他们有中有一个方法同名,这是就会产生冲突,那如何解决这种冲突呢
将其中一个用另一个代替,这样就不会产生冲突了
示例:
trait tDemo1{public function hello(){echo 'hello';}}trait tDemo2{public function hello(){echo 'the world';}}trait tDemo3{use tDemo1,tDemo2{// 1.替代,将tDemo1的hello替代tDemo2的方法// 这样,在调用tDemo2的时候,就会用tDemo1代替执行tDemo1::hello insteadof tDemo2;}}class Work{use tDemo3;}$work = new Work();echo $work->hello();echo '<hr>';
将其中一个方法,给它起一个别名,调用的时候用别名,名称不会冲突,也是一种方法
示例
trait tDemo1{public function hello(){echo 'hello';}}trait tDemo2{public function hello(){echo 'the world';}}trait tDemo3{use tDemo1,tDemo2{// 2.别名法,将tDemo2的hello用一个其他名字代替// 这样,在调用tDemo2的时候,就可以用别名调用tDemo2::hello as say;}}class Work{use tDemo3;}$work = new Work();echo $work->say();echo '<hr>';
当在trait中引用了另外一个trait,且这个trait不被别人调用时,这时就出现了trait访问控制,分别是public ,protected ,private 这三个
示例
trait tDemo1{public function hello(){echo 'hello1';}}trait tDemo2{public function hello(){echo 'hello2';}}trait tDemo3{use tDemo1,tDemo2{// tDemo1::hello as say;tDemo1::hello insteadOf tDemo2;tDemo2::hello as book;}// 通过`as`可以修改trait成员的访问控制,// public:表示可以访问// protected:不可访问// 将tHello中的hello方法设为保护的// use tDemo2 {hello as public;}}class Work{use tDemo3;}$work = new Work();echo $work->hello();// 此时无法调用,因为hello方法已经成为受保护的了echo $work->book();
先就从trait说起,Trait是一种代码复用技术,为PHP的单继承限制提供一套灵活的代码复用机制。再讲接口的优点,接口主要的优点就是多态,还有多继承,一个接口,可以让具有继承关系的不同类对象,可以对相同名称的成员调用,产生不同的反应结果。一个类还可以继承多个接口,那么trait实现接口的优点就出来了,实现模块坏开发,当一个类继承多个接口,用trait将每个模块实现,代码复用就体现出来了。写的代码会非常的优雅。
用trait实现接口,有几个缺点
trait实现接口特别要注意优先级,当类中的方法与trait中的方法重名时,优先级的关系需要搞清楚。trait重名时,trait的权重大于父类示例
// 随机输出一个用户的级别以及优惠力度$Data = [['id' => '1','name' => '张三','level' => 'normalUser'],['id' => '2','name' => '李四','level' => 'vipUser'],['id' => '3','name' => '王麻子','level' => 'newUser'],];interface iUserData{public static function generateId(int $min , int $max):int;}trait iPrint{static public function printLevel($level){if($level == 'normalUser'):echo '普通用户'.'<br>';elseif ($level == 'vipUser' ):echo 'VIP用户'.'<br>';elseif ($level == 'newUser'):echo '新用户'.'<br>';else:echo '用户不存在'.'<br>';endif;}}trait iCreateId1{public static function generateId(int $min , int $max):int{return mt_rand($min,$max);}}// abstract class Discount implements iUserDataabstract class Discount implements iUserData{use iCreateId1;public static function discount1($level){if($level == 'normalUser'):echo '九折'.'<br>';elseif ($level == 'vipUser'):echo '七折'.'<br>';elseif ($level == 'newUser'):echo '八折'.'<br>';endif;}}// 工作类:输出类class User extends Discount{use iCreateId1,iPrint;public static function awrad(array $Data,int $id){echo '用户名称为'.$Data[$id]['name'].'<br>';}}$id = User::generateId(0,2);$user = User::printLevel($Data[$id]['level']);$userdata = User::discount1($Data[$id]['level']);$userdata1 = User::awrad($Data,$id);
输出:
新用户八折用户名称为王麻子
这个案例看似简单,如果用循环控制语句,可能几行代码就实现出来了,但是用面向对象实现出来,并不会那么简单,首先得知道数组的结构,以及函数传参,再用trait把它们是实现一个功能模块。用抽象类实现接口的好处就是,可以只实现其中的一个方法,而不用像继承类那样,把全部的都要实现。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号