Blogger Information
Blog 56
fans 1
comment 0
visits 62317
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
trait的五种应用场景
零龙
Original
1565 people have browsed it

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就像一个灵活的物品,可以在多种类型中使用。
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