批改状态:合格
老师批语:导图是亮点
<?php// trait功能之一:实现代码的复用trait tSum{// 写一个公共的求和方法public function sum ($a,$b) {return $a+$b;}}class Sum1{use tSum;}class Sum2{use tSum;}echo (new Sum1)->sum(10,20);echo '<hr>';echo (new Sum2)->sum(10,20);

<?php// 在继承上下文中的应用,控制优先级,降低单继承的影响trait tMiddle{public static function show () {echo '访问到trait';}}// 基类/父类abstract class Big{public static function show () {echo '访问到基类';}}// 扩展类/子类class Small extends Big{use tMiddle;public static function show () {echo '访问到扩展类';}}// 实例化扩展类来访问,看看优先级(遇到同名方法时)// 1. 不引入trait时// Small::show();// 此时输出:访问到扩展类,表示扩展类>基类// 2.引入trait时,并注释掉扩展类中的方法// Small::show();// 此时输出:访问到trait,表示trait>基类// 3.引入trait,保留扩展类中的方法Small::show();// 此时输出:访问到扩展类,表示扩展类>trait和基类// 综合上述三种情况:当遇到同名方法时,且trait在子类中调用时,扩展类>trait>基类



<?php// trait功能之实现功能的扩展:组合运用多个trait// 求和的traittrait Sum{public static function sum (int $a, int $b) :int{return $a+$b;}}// 求差的traittrait Sub{public static function subtraction (int $a,int $b) :int{return $a-$b>=0 ? $a-$b :$b-$a;}}// 把求和与求差组合为一个traittrait Demo{use Sum,Sub;}// 求积的classclass Multi{// 如果要在这个类中再加入求和与求差,只需引入Sum和Sub这两个traituse Sum,Sub;public static function multiplication (int $a,int $b) :int{return $a*$b;}}echo "两数之和是:".Multi::sum(10,20),'<hr>';echo "两数之差是:".Multi::subtraction(10,20),'<hr>';echo "两数相乘是:".Multi::multiplication(10,20),'<hr>';// 求商的classclass Divi{// 如果把以上两个trait合并为一个,那么在这个类中只需引入一个trait即可实现求和与求差use Demo;public static function division (int $a,int $b) :float{return $a/$b;}}echo "两数之和是:".Divi::sum(20,20),'<hr>';echo "两数之差是:".Divi::subtraction(20,20),'<hr>';echo "两数相除是:".Divi::division(20,20),'<hr>';


<?php// trait的命名冲突解决办法trait tDemo1{public function show () {echo 'aaaaaa','<hr>';}}trait tDemo2{public function show () {echo 'bbbbbb','<hr>';}}trait tDemo3{public function show () {echo 'cccccc','<hr>';}}// 示例一:trait tDemo4{// 两个trait中的方法名一样,有冲突,会报错,解决方案如下:// 1. insteadof 操作符来明确指定使用冲突方法中的哪一个use tDemo1,tDemo2,tDemo3{// tDemo1::show insteadOf tDemo2,tDemo3;// tDemo2::show insteadOf tDemo3,tDemo1;tDemo3::show insteadOf tDemo1,tDemo2;}}class Work1{use tDemo4;}(new Work1)->show();// 示例二:trait tDemo5{use tDemo1,tDemo2{// 2. 使用 as 可以给trait中的方法取别名,但不是重命名,也不会影响其方法tDemo1::show insteadOf tDemo2;tDemo1::show as s1;tDemo2::show as s2;}}class Work2{use tDemo5;}(new Work2)->show();(new Work2)->s1();(new Work2)->s2();


<?php// trait中as语法调整方法的访问控制trait tDemo{public static function show () {return __METHOD__;}}class Work1{use tDemo;}echo Work1::show(),'<hr>';class Work2{// 将访问控制修改为protecteduse tDemo{show as protected;}}// 修改访问控制为protected以后,外部将不能调用echo Work2::show();

<?php// trait与interface组合:可将实现类中的代码放入trait,然后再调用,让实现类的代码尽量简介、清晰// if (!interface_exists(iDemo)) :interface iDemo{public function show ();}// endif;// if (!trait_exists(tDemo)) :trait tDemo{public function show () {return 'aaa';}}// endif;// if (!class_exists(Demo)) :class Demo{use tDemo;}// endif;echo (new Demo)->show();

它们之间的区别我就不做实例演示,这里谈下我的理解。
它们都有自己的应用场景,比如:trait用作代码复用,不仅可以把一些公共的方法放在其中,也可以把实现类的代码放在其中,方便调用;
接口用于将设计与实现完全分离,在实际项目中。肯定是不可或缺的,需要把设计方法放在其中,之后再去实现这个接口
抽象类,可以理解为一个中间层,用它去实现接口,并且使用抽象类实现接口的好处是可以不用实现接口的所有方法,还能把真正实现类的一些公共操作放在其中,也还能在抽象类中定义一些抽象方法,最终让子类去实现

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号