博客列表 >trait的五种应用场景

trait的五种应用场景

零龙
零龙原创
2020年08月03日 22:02:431564浏览

trait的五种应用场景

  • php中继承是单继承,如果某个类有成员要被其他类使用,就需要称为其他类的父类才行,这样可能会导致继承链会长,合适吗?
  • 引入:继承的角度出发,继承链可以解决问题,但是的确效率会打折扣,同时,如果某些功能是共性使用,但是并不符合(不属于同一类)继承条件,那么使用继承也有所违背面上对象规则,此时可以使用php提供的另外一种代码复用技术trait

    1:代码复用

    2:在继承上下文中的应用

    3:实现功能扩展

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

    5:trait和interface的组合

    1.代码复用

  • 定义:trait是为类似php的单继承语言而准备的一种代码复用机制,trait可以使得但继承语言为了复用而不得不继承的尴尬,让面向对象更加纯粹
  • 1-1、trait是一种类似class的关键字
  1. <?php
  2. // 定义trait
  3. trait show{
  4. }
  • 1-2、trait内部可以像类一样拥有成员属性(包含静态),成员方法(包含静态),但不能有常量
    示例:
  1. trait uSername //定义trait
  2. {
  3. public function show() //定义一个公用的方法
  4. {
  5. return '姓名:'.$this->username.'|国家:'.$this->nation.'|电话:'.$this->mobile;
  6. //返回一段用户信息
  7. }
  8. public static function show1() //定义一个show1静态方法
  9. {
  10. printf('<pre>%s</pre>',print_r(get_class_vars(__CLASS__),true));
  11. //打印当前类返回的数组get_class_vars
  12. }
  13. }
  14. class User //定义一个User类
  15. {
  16. use uSername; //调用trait
  17. protected $username ='曹操'; //为隐私属性赋值
  18. public $nation ='魏国'; //为公用属性赋值
  19. private $mobile ='13666666666';//为私有属性赋值
  20. }
  21. echo (new User)->show(); //实例化User调用trait
  22. echo '<hr>';
  23. class User1 //定义一个User1类
  24. {
  25. use uSername; //调用trait
  26. public $username ='刘备'; //为公用属性赋值
  27. private $nation ='蜀国'; //为私有属性赋值
  28. protected $mobile ='13555555555'; //为隐私属性赋值
  29. }
  30. echo (new User1)->show(); //实例化User调用trait
  31. echo '<hr>';
  32. User::show1(); //使用静态实例化调用trait中的show1方法
  33. echo '<hr>';
  34. User1::show1(); //使用静态实例化调用trait中的show1方法

示例图

学习心得:在使用trait中能体会到在类中需要引入外部的数据或者方法很繁琐,使用trait可以任意调用使用。

2:在继承上下文中的应用

  • 在实例中创建了trait及抽象类和子类,知道了通过实例化子类对程序的执行顺序。
    示例:
  1. trait aTtribute //创建trait
  2. {
  3. public static function show() //创建一个静态的show方法
  4. {
  5. echo '我是trait->show<br>';
  6. return Attribute1::show(); //返回一条字符串
  7. }
  8. }
  9. abstract class Attribute1 //抽象类不可以被实例化
  10. {
  11. use aTtribute; //调用trait
  12. public static function show() //抽象类中创建一个静态的show方法
  13. {
  14. //返回trait的show方法
  15. return '我是父类show<br>';
  16. }
  17. }
  18. class Attribute2 extends Attribute1 //创建Attribute的子类
  19. {
  20. use aTtribute; //调用trait
  21. public static function show() //创建一个静态的show方法
  22. {
  23. echo '我是子类show<br>';
  24. return aTtribute::show(); //返回抽象类的的show方法
  25. }
  26. }
  27. echo Attribute2::show(); //输出Attribute2子类的show()方法
  28. //子类同名成员优先大于父类同名成员
  29. //如果子类、父类、trait中存在同名方法的时候,而trait在子类中调用
  30. //先调用子类->在调用trait->父类

总结:在编写程序的过程中,知悉了trait在上下文中的执行顺序

3:实现功能扩展

示例:

  1. trait tDemo
  2. {
  3. //1.打印所有属性
  4. public function getProps()
  5. {
  6. printf('<pre>%s</pre>',print_r(get_class_vars(__CLASS__),true));
  7. }
  8. }
  9. trait tDemo1
  10. {
  11. //2.打印所有方法
  12. public function getMethost()
  13. {
  14. printf('<pre>%s</pre>',print_r(get_class_methods(__CLASS__),true));
  15. }
  16. //__CLASS__:返回当前类的名称字符串
  17. //self:返回当前类的引用
  18. }
  19. trait tDemo2
  20. {
  21. use tDemo1,tDemo;
  22. }
  23. class Users
  24. {
  25. use tDemo2;
  26. public $name ='刘备';
  27. public $nation ='蜀国';
  28. public function show()
  29. {
  30. return $this->name.':'.$this->nation;
  31. }
  32. //扩展这个类的功能
  33. //添加二个公共方法
  34. }
  35. echo (new Users)->show();
  36. echo (new Users)->getProps();
  37. echo (new Users)->getMethost();

示例图

总结:将两个trait放到一个trait中在类里调用,通过实例化将trait实例化,程序中可以看出,trait可以为类扩展出无限个方法和属性。

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

  • 在trait中有重名的方法,可以使用insteadOf替换将重名的的方法重命名。
  • 格式
    trait名称::重名的方法 as 新的命名;
    trait名称::重名的方法 insteadOf替换 trait名称::重名的方法;
    示例:
  1. <?php
  2. trait tDemo
  3. {
  4. public static $car = '汽车';
  5. public static function show() //定义的了静态show方法
  6. {
  7. return self::$car;
  8. }
  9. }
  10. trait tDemo1
  11. {
  12. public static $train = '火车';
  13. public static function show() //定义的了静态show方法
  14. {
  15. return self::$train;
  16. }
  17. }
  18. trait tDemo2
  19. {
  20. use tDemo, tDemo1 {
  21. tDemo1::show as toshow;
  22. // 给tDemo1::show()起个别名: toshow
  23. tDemo::show insteadOf tDemo1;
  24. // 调用tDemo1::show()替换掉tDemo::show()
  25. }
  26. }
  27. class Work
  28. {
  29. use tDemo2;
  30. }
  31. echo (new Work)->show();
  32. echo '<hr>';
  33. echo (new Work)->toshow();

5:trait和interface的组合

  • 通过trait实现interface接口的方法,然后实例化

    示例

  1. <?php
  2. interface iDemo //定义一个接口
  3. {
  4. public static function index();
  5. }
  6. trait tDemo //定义一个trait
  7. {
  8. public static function index() //在tDemo中定义一个接口方法
  9. {
  10. return '我是在trait中的!';
  11. }
  12. }
  13. class Hello implements iDemo //定义一个类实现iDemo
  14. {
  15. use tDemo; //类中应用trait
  16. }
  17. echo (new Hello)->index();
  18. //本实例定义一个接口,然后在trait中实现接口方法,然后实例化

示例图

对trait的使用总结,trait就像一个灵活的物品,可以在多种类型中使用。
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议