Blogger Information
Blog 21
fans 0
comment 0
visits 14730
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
(1204)实例演示trait的功能,三大特性和优先级
Yuming
Original
924 people have browsed it

(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小明
Correcting teacher:灭绝师太灭绝师太

Correction status:qualified

Teacher's comments:
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
1 comments
灭绝师太 2020-12-07 17:37:54
如果trait同名成员优先大于父类同名成员,可以只在trait和父类中声明两个同名成员方法,然后在子类中引用trait, 继承父类,使用子类取调用trait和父类中声明的同名成员方法,结果肯定是show小明,可以试一下~
1 floor
Author's latest blog post