博客列表 >PHP大牛成长之路:trait类的应用

PHP大牛成长之路:trait类的应用

周Sir-BLOG
周Sir-BLOG原创
2020年07月25日 00:06:25574浏览

trait类的应用

1、trait应用场景1:代码复用

  1. // 在trait类中定义方法,在不同类中调用
  2. trait tDemo
  3. {
  4. public function show($name,$like,$gender)
  5. {
  6. printf('我叫%s,是个%s的%s孩。',$name,$like,$gender);
  7. }
  8. }
  9. class User1
  10. {
  11. use tDemo;
  12. protected $name = '张三';
  13. protected $gender = '男';
  14. protected $like ='爱打篮球';
  15. public function introduce(){
  16. return $this->show($this->name,$this->like,$this->gender);
  17. }
  18. }
  19. class User2
  20. {
  21. use tDemo;
  22. protected $name = '李丽';
  23. protected $gender = '女';
  24. protected $like ='爱跳舞';
  25. public function introduce(){
  26. return $this->show($this->name,$this->like,$this->gender);
  27. }
  28. }
  29. (new User1)->introduce();
  30. echo '<hr>';
  31. (new User2)->introduce();
  • 输出结果如下:

2、trait应用场景1:实现功能扩展

  1. trait tDemo1
  2. {
  3. // 打印所有属性
  4. public function getProps()
  5. {
  6. printf('<pre>%s</pre>', print_r(get_class_vars(__CLASS__), true));
  7. }
  8. }
  9. trait tDemo2
  10. {
  11. // 打印所有方法
  12. public function getMethods()
  13. {
  14. printf('<pre>%s</pre>', print_r(get_class_methods(__CLASS__), true));
  15. }
  16. }
  17. trait tDemo3
  18. {
  19. use tDemo1, tDemo2;
  20. }
  21. class Demo1
  22. {
  23. use tDemo1, tDemo2; //可引用多个trait实现功能扩展
  24. protected $name = '张三';
  25. protected $gender = '男';
  26. public function show()
  27. {
  28. return $this -> getProps();
  29. }
  30. }
  31. class Demo2
  32. {
  33. use tDemo3; //tDemo3引入了tDemo1、tDemo2,此时只引入一个trait就可以
  34. protected $name = '李丽';
  35. protected $gender = '女';
  36. public function show()
  37. {
  38. return $this -> getProps();
  39. }
  40. }
  41. echo '<h3>Demo1</h3>';
  42. echo '类属性:<br>', (new Demo1)->getProps();
  43. echo '类方法:<br>', (new Demo1)->getMethods();
  44. echo '<hr>';
  45. echo '<h3>Demo2</h3>';
  46. echo '类属性:<br>', (new Demo2)->getProps();
  47. echo '类方法:<br>', (new Demo2)->getMethods();

3、trait 和 interface的组合

  1. // 接口
  2. interface iDemo
  3. {
  4. public static function index();
  5. }
  6. // trait
  7. trait tDemo
  8. {
  9. // 将接口中的抽象方法的实现过程放在trait中实现,并在工作类中调用
  10. public static function index()
  11. {
  12. return __METHOD__;
  13. }
  14. }
  15. // 实现类
  16. class Hello implements iDemo
  17. {
  18. use tDemo;
  19. }
  20. // 客户端
  21. echo Hello::index();

输出:tDemo::index

4、trait组合中命名冲突的解决方案

  1. trait Demo1
  2. {
  3. public function show()
  4. {
  5. return '我是:'.__METHOD__;
  6. }
  7. }
  8. trait Demo2
  9. {
  10. public function show()
  11. {
  12. return '我是:'.__METHOD__;
  13. }
  14. }
  15. trait Demo3
  16. {
  17. use Demo1, Demo2 {
  18. // 给Demo2::show()起个别名: S2
  19. Demo2::show as ds2;
  20. // 调用Demo1::show()替换成Demo2::show()
  21. Demo1::show insteadOf Demo2;
  22. }
  23. }
  24. // 工作类尽可能写得代码清晰,简洁
  25. class Demo
  26. {
  27. use Demo3;
  28. }
  29. echo (new Demo)->show();
  30. echo '<hr>';
  31. // 别名访问Demo2::show
  32. echo (new Demo)->ds2();

5、trait 在继承的上下文中的优先级关系

  1. trait Demo
  2. {
  3. public static function hello()
  4. {
  5. return 'trait中的方法' . __METHOD__;
  6. }
  7. }
  8. // 父类
  9. class Father
  10. {
  11. use Demo;
  12. public static function hello()
  13. {
  14. return '父类中的方法' . __METHOD__;
  15. }
  16. }
  17. // 子类
  18. class Son extends Father
  19. {
  20. use Demo;
  21. public static function hello()
  22. {
  23. return '子类中的方法' . __METHOD__;
  24. }
  25. }
  26. echo son::hello();
  27. // 在继承的上下文中存在同名方法的时候,优先级关系不同,其优先级关系如下:
  28. // 父类引入:优先级关系为: Son > Father > trait(Demo)
  29. // 子类引入:优先级关系为: Son > trait(Demo) > Father

输出结果请自行测试

总结:

Trait不同于继承,定义一个trait类,使用use关键字引入,在一个类中引入Trait类后,相当于require或include了一段代码进来,Trait类的成员及方法可以看做是当前类成员或方法。

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议