博客列表 >(1204)实例演示trait的功能,三大特性和优先级

(1204)实例演示trait的功能,三大特性和优先级

Yuming
Yuming原创
2020年12月07日 03:26:48937浏览

(1204)实例演示trait的功能,三大特性和优先级

trait 可以当作类,但是不能被实例化,所以严格来讲不是类,
trait 就是
引入一些新功能,对我们没有任何影响(命名冲突除外),我们引入 trait 的当前类的优先级大于使用 use 引入的优先级,所以 trait 的功能可以看作是一种拓展。 重写没有任何影响,不重写也可以直接调用 trait 内的功能。

  • 重写没有任何影响
  1. trait show{
  2. public static function getName (){
  3. return 'trait小明';
  4. }
  5. }
  6. //父类
  7. class One {
  8. public static function getName (){
  9. return 'One小明';
  10. }
  11. }
  12. //子类
  13. class Two extends One{
  14. use show;
  15. public static function getName (){
  16. return 'Two小明';
  17. }
  18. }
  19. echo Two::getName(); //Two小明
  • 不重写也可以直接调用 trait 内的功能
  1. trait show{
  2. public static function getName (){
  3. return 'trait小明';
  4. }
  5. }
  6. //父类
  7. class One {
  8. public static function getName (){
  9. return 'One小明';
  10. }
  11. }
  12. //子类
  13. class Two extends One{
  14. use show;
  15. }
  16. echo Two::getName(); //trait小明

1.实例 解析 trait 新特性的功能;

  • 特性一实现代码的复用

    简单一点理解就是我们可以把公共的方法写到 trait 中,这样可以节省大量重复代码,有点类似于 js 的封装

  1. trait Copy{
  2. public static function getName(){
  3. echo 'trait小明';
  4. }
  5. }
  6. class CopyOne{
  7. use Copy;
  8. }
  9. class CopyTwo extends CopyOne{
  10. use Copy;
  11. }
  12. CopyTwo::getname(); //trait
  • 特性二 实现功能多拓展, php 是单继承语言,多拓展这种特性极大的简化了我们撸代码的效率
  1. trait FunOne{
  2. public static function sayOne(){
  3. echo 'hello 拓展One';
  4. }
  5. }
  6. trait FunTwo{
  7. public static function sayTwo(){
  8. echo 'hello 拓展Two';
  9. }
  10. }
  11. trait FunOneAndTwo{
  12. use FunOne,FunTwo;
  13. }
  14. class WorkOne{
  15. use FunOneAndTwo; //hello 拓展Two
  16. }
  17. WorkOne::sayTwo();
  • 由于我们第二个特性实现拓展,那么势必会在多拓展的时候遇到方法重名的问题,也就是命名冲突,那么 php 提供了相应的 trait 中命名冲突的 解决方案

*如果命名冲突会爆出以下错误Trait method getName has not been applied, because there are collisions with other trait methods on reName in

这时候我们使用 trait 特性解决命名冲突问题

  1. // 解决方案
  2. trait reNameOne{
  3. public static function getName(){
  4. echo 'nameONE';
  5. }
  6. }
  7. /**
  8. *
  9. */
  10. trait reNameTwo
  11. {
  12. public static function getName(){
  13. echo 'nameTwo';
  14. }
  15. }
  16. /**
  17. * reNameOneAndTwo
  18. */
  19. trait reNameOneAndTwo
  20. {
  21. use reNameOne,reNameTwo{
  22. reNameTwo::getName as nameOne;
  23. reNameOne::getName insteadOf reNameTwo; // 告诉引擎不要去reNameTwo中找getNmame,因为已经被替换了
  24. }
  25. }
  26. class reName{
  27. use reNameOneAndTwo;
  28. }
  29. reName::getName();

2.子类同名成员优先大于父类同名成员,如果子类,父类,trait 中存在同名方法的时候, 而 trait 在子类中调用,此时子类 > trait > 父类

  1. // trait类
  2. trait show{
  3. // private static $name = 'trait小明';
  4. public static function getName (){
  5. return 'trait小明';
  6. }
  7. }
  8. //父类
  9. class One {
  10. // private static $name = 'One小明';
  11. public static function getName (){
  12. return 'One小明';
  13. }
  14. }
  15. //子类
  16. class Two extends One{
  17. use show;
  18. // private static $name = 'Two小明';
  19. public static function getName (){
  20. return 'Two小明';
  21. }
  22. }
  23. echo Two::getName(); //Two小明
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议
灭绝师太2020-12-07 17:37:541楼
如果trait同名成员优先大于父类同名成员,可以只在trait和父类中声明两个同名成员方法,然后在子类中引用trait, 继承父类,使用子类取调用trait和父类中声明的同名成员方法,结果肯定是show小明,可以试一下~