Blogger Information
Blog 55
fans 3
comment 0
visits 54647
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
trait的五种常用场景
王佳祥
Original
1130 people have browsed it

trait的五种常用场景

一、代码复用

  1. <?php
  2. //1.trait功能1:代码复用
  3. trait tDemo
  4. {
  5. public function show()
  6. {
  7. //get_class_vars — 返回由类的默认属性组成的数组
  8. printf('<pre>%s</pre>',print_r(get_class_vars(__CLASS__),true));
  9. }
  10. }
  11. class User1
  12. {
  13. use tDemo;
  14. protected $name = '胖子';
  15. protected $sex = '男';
  16. }
  17. class User2
  18. {
  19. use tDemo;
  20. protected $name = '胖子';
  21. protected $sex = '男';
  22. }
  23. (new User1)->show();
  24. (new User2)->show();


二、同名成员在trait,子类,父类的优先级

  1. <?php
  2. //trait功能2:在继承上下文中的应用
  3. trait tDemo
  4. {
  5. //public static $name = 'trait中的属性';
  6. public static function hello()
  7. {
  8. //__METHOD__返回类名称与函数名称
  9. //__FUNCTION__返回函数名称
  10. return 'trait中的方法' . __METHOD__;
  11. }
  12. }
  13. //声明一个抽象类 基类/父类/超类
  14. abstract class Dad
  15. {
  16. public static $name = '基类中的属性';
  17. public static function hello()
  18. {
  19. //__METHOD__返回类名称与函数名称
  20. //__FUNCTION__返回函数名称
  21. return '基类中的方法' . __METHOD__;
  22. }
  23. }
  24. //子类/扩展类
  25. class Son extends Dad
  26. {
  27. //引入trait
  28. use tDemo;
  29. public static $name = '扩展类中的属性';
  30. public static function hello()
  31. {
  32. //__METHOD__返回类名称与函数名称
  33. //__FUNCTION__返回函数名称
  34. return '扩展类中的方法' . __METHOD__;
  35. }
  36. }
  37. echo Dad::$name.'<br>';
  38. echo Dad::hello().'<hr>';
  39. //子类同名成员优先级大于父类同名成员
  40. //如果子类,父类,trait中存在同名方法的时候,而trait在子类中调用,此时
  41. //子类>trait>父类
  42. echo Son::$name.'<br>';
  43. echo Son::hello();


三、trait的扩展功能

  1. <?php
  2. //trait功能3: 实现功能扩展
  3. //trait1
  4. trait tDemo1
  5. {
  6. //1.打印所有属性
  7. public function getProps()
  8. {
  9. //__CLASS__返回当前类的名称字符串
  10. //self:返回当前类的引用
  11. printf('<pre>%s</pre>',print_r(get_class_vars(__CLASS__),true));
  12. }
  13. }
  14. //trait2
  15. trait tDemo2
  16. {
  17. //2.打印所有方法
  18. public function getMethods()
  19. {
  20. printf('<pre>%s</pre>',print_r(get_class_methods(__CLASS__),true));
  21. }
  22. }
  23. //trait3,合并trait1,trait2
  24. trait tDemo3
  25. {
  26. use tDemo1,tDemo2;
  27. }
  28. class Work1
  29. {
  30. use tDemo3;
  31. public $name = '西瓜';
  32. public $price = 0.7;
  33. public function getInfo()
  34. {
  35. return $this->name . ':' . $this->price;
  36. }
  37. //扩展这个类的功能
  38. //添加二个方法
  39. //1.打印所有属性
  40. //2.打印所有方法
  41. }
  42. echo (new Work1)->getInfo(),'<hr>';
  43. echo (new Work1)->getProps(),'<hr>';
  44. echo (new Work1)->getMethods(),'<hr>';


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

  1. <?php
  2. //trait功能4:在trait组合中命名冲突的解决方案
  3. trait tDemo1
  4. {
  5. public function display()
  6. {
  7. //__TRAIT__:返回trait的名称字符串
  8. return __TRAIT__;
  9. }
  10. }
  11. trait tDemo2
  12. {
  13. public function display()
  14. {
  15. //__TRAIT__:返回trait的名称字符串
  16. return __METHOD__;
  17. }
  18. }
  19. trait tDemo3
  20. {
  21. use tDemo1,tDemo2{
  22. //给tDemo2::display()起个别名:td2
  23. tDemo2::display as td2;
  24. //调用tDemo1::display()替换掉tDemo2::display()
  25. tDemo1::display insteadof tDemo2;
  26. }
  27. }
  28. //工作类尽可能写的代码清晰,简洁
  29. class Work
  30. {
  31. use tDemo3;
  32. }
  33. echo (new Work)->display(),'<hr>';
  34. //别名访问
  35. echo (new Work)->td2();


五、trait和interface的组合

  1. <?php
  2. //trait功能5:trait和interface的组合
  3. //接口
  4. //如果这个接口不存在的话,直接创建这个接口
  5. if (!interface_exists('iDemo')):
  6. interface iDemo
  7. {
  8. public static function index();
  9. }
  10. endif;
  11. //trait
  12. if(!trait_exists('tDemo')):
  13. trait tDemo
  14. {
  15. //将接口中的抽象方法的实现过程放在trait中实现,并在工作中调用
  16. public static function index()
  17. {
  18. return __METHOD__;
  19. }
  20. }
  21. endif;
  22. //实现类
  23. if(!class_exists('Hello')):
  24. class Hello implements iDemo
  25. {
  26. use tDemo;
  27. }
  28. endif;
  29. //客户端调用
  30. echo Hello::index();


六、实战:双色球开奖的背景知识

  1. <?php
  2. //实战:双色球开奖
  3. //抽象类 + 接口 + trait
  4. //奖品
  5. $prizes = ['华为p40手机','山地自行车','机械键盘','音箱','耳机','头盔'];
  6. /* trait iCreateId
  7. {
  8. //生成一个唯一的ID
  9. public static function generateId($min,$max)
  10. {
  11. //返回范围内的随机整数
  12. return mt_rand($min,$max);
  13. }
  14. } */
  15. interface iCreateId
  16. {
  17. public static function generateId($min,$max);
  18. }
  19. trait CreateId
  20. {
  21. public static function generateId($min,$max)
  22. {
  23. //返回范围内的随机整数
  24. return mt_rand($min,$max);
  25. }
  26. }
  27. //开奖类
  28. class DrawPrize implements iCreateId
  29. {
  30. use CreateId;
  31. //发奖品
  32. public static function award($prizes,$id)
  33. {
  34. return $prizes[$id];
  35. }
  36. }
  37. $id = DrawPrize::generateId(0,5);
  38. $prize = DrawPrize::award($prizes,$id);
  39. printf('奖品是:<span style="color:red">%s</span>',$prize);


七、学习总结

1.trait代码复用

2.同名成员在父类,子类,trait中的优先级:子类>trait>父类

3.trait可以扩展功能

4.在trait中可以用别名解决命名冲突的问题

5.trait可以实现接口中的方法并调用

Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:trait的本质是代码复用,重点放在它的功能组合与命名冲突的解决上
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post