转载链接:https://www.jb51.net/article/105579.htm

1.trait简介

1.1 特性

(1)优先级:当前类中的方法 > trait中的方法 > 基类中的方法
(2)多个trait使用,分隔
(3)trait 冲突使用insteadof操作符号来指定使用冲突方法中的哪一个
(4)as操作符可以为方法设置别名,也可以修改trait中的方法的访问控制
(5)其他trait也可以使用trait。
(6)Traits 可以被静态成员静态方法定义。
(7)在引用Trait时,使用了use关键字,use关键字也用来引用命名空间。两者的区别在于,引用Trait时是在class内部使用的。比如thinkphp5框架中use concern\ModelRelationQuery;
(8)Trait 定义了一个属性后,类就不能定义同样名称的属性(名字,值和访问控制相同就没问题),否则会产生 fatal error。

1.2 优点

解决代码复用,解决PHP单继承的问题;

1.3 区别

trait和class的区别是trait不能被实例化

1.4 代码

<?phpclass Base{//    public function sayHello(){//        echo "hello";
//    }
}trait Mood{public $a =1;public function sayMood(){echo "!";}
}trait Sayworld{public function sayHello(){//        parent::sayHello();echo "world";}abstract public function getWorld();public static function doSomething(){echo "static function";}
}class MyHelloWorld extends Base{use Sayworld,Mood{sayHello as public;}public $a =1 ; //=2值不同就会fatal errorpublic function getWorld(){return "getWorld";}
//    public function sayHello()
//    {        parent::sayHello();
//        echo "MyHelloWorld";
//    }
}$o = new MyHelloWorld();
$o->sayHello();
$o->sayMood();
$o::doSomething();
trait Man{use Sayworld;public function eat(){echo "man word";}public function talk(){echo "Chinese";}public function inc(){static $i=1;$i++;echo $i;}}trait Woman{public function eat(){echo "woman home";}public function talk(){echo "English";}
}class Person{use Man,Woman{Woman::eat insteadof Man;Man::talk insteadof Woman;Woman::talk as talks;}public function getWorld(){// TODO: Implement getWorld() method.}}
class Animals{use Man;public function getWorld(){// TODO: Implement getWorld() method.}
}
$person = new Person();
//$person->eat();
//$person->talks();
//$person->sayHello();
$person->inc();
(new Animals())->inc();  //静态变量不会改变  都是2

2.使用场景

熟悉面向对象的都知道,软件开发中常用的代码复用有继承和多态两种方式。在PHP中,只能实现单继承。而Trait则避免了这点。下面通过简单的额例子来进行对比说明。

  1. 继承 VS 多态 VS Trait
    现在有Publish.php和Answer.php这两个类。要在其中添加LOG功能,记录类内部的动作。有以下几种方案:
    继承
    多态
    Trait

2.1. 继承

如图:

代码结构如下:
// Log.php

<?php
Class Log
{public function startLog(){// echo ...}public function endLog(){// echo ...}
}

// Publish.php

<?php
Class Publish extends Log
{}

// Answer.php

<?php
Class Answer extends Log
{}

可以看到继承的确满足了要求。但这却违背了面向对象的原则。而发布(Publish)和回答(Answer)这样的操作和日志(Log)之间的关系并不是子类与父类的关系。所以不推荐这样使用。

2.2. 多态

如图:

// Log.php

<?php
Interface Log
{public function startLog();public function endLog();
}

// Publish.php

<?php
Class Publish implements Log
{public function startLog(){// TODO: Implement startLog() method.}public function endLog(){// TODO: Implement endLog() method.}
}

// Answer.php

<?php
Class Answer implements Log
{public function startLog(){// TODO: Implement startLog() method.}public function endLog(){// TODO: Implement endLog() method.}
}

记录日志的操作应该都是一样的,因此,发布(Publish)和回答(Answer)动作中的日志记录实现也是一样的。很明显,这违背了DRY(Don’t Repeat Yourself)原则。所以是不推荐这样实现的。

2.3. Trait

如图:

// Log.php

<?php
trait Log{public function startLog() {// echo ..}public function endLog() {// echo ..}
}

// Publish.php

<?php
class Publish {use Log;
}
$publish = new Publish();
$publish->startLog();
$publish->endLog();

// Answer.php

<?php
class Answer {use Log;
}
$answer = new Answer();
$answer->startLog();
$answer->endLog();

可以看到,我们在没有增加代码复杂的情况下,实现了代码的复用。

2.4. 结论

继承的方式虽然也能解决问题,但其思路违背了面向对象的原则,显得很粗暴;多态方式也可行,但不符合软件开发中的DRY原则,增加了维护成本。而Trait方式则避免了上述的不足之处,相对优雅的实现了代码的复用。

PHP中trait的特性相关推荐

  1. PHP 5.4中的traits特性

    Trait 是 PHP5.4 中的新特性,是 PHP 多重继承的一种解决方案.例如,需要同时继承两个 Abstract Class, 这将会是件很麻烦的事情,Trait 就是为了解决这个问题.简单使用 ...

  2. php v5.,PHP V5.3 中的新特性,第 5 部分- 从 PHP V5.2 升级到 PHP V5.3

    PHP V5.3 中的新特性,第 5 部分: 从PHP V5.2 升级到 PHP V5.3 1 2 3 4 5 下一页 PHP V5.3 将于不久后发布."PHP V5.3 中的新特性&qu ...

  3. Entity Framework 4.3 中的新特性

    原文地址:http://www.cnblogs.com/supercpp/archive/2012/02/20/2354751.html EF4.3于2月9号正式发布了,微软的EF小组最近一年开始发力 ...

  4. 第一次来,试发一帖!--ASP.NET 2.0 中的SqlCacheDependency特性

    ASP.NET中的Page Cache是个很有用的东东,只要简单的在页面上方加上一个OutputCache标签,就可以让页面在制定的Duration内直接把自动保存在缓存中的页面内容输出,而不需要让A ...

  5. Spring 2.5:Spring MVC中的新特性

    转载说明:infoQ就是牛人多,看人家去年就把Spring2.5注视驱动的MVC写出来了,还是这么详细,我真是自叹不如,今天偶尔看到这篇文章非常认真的拜读了2遍,简直是茅厕顿开啊....\(^o^)/ ...

  6. MS CRM 2011中的新特性(1)——界面部分

    MS crm2011中,在界面部分的调整包括有ribbon.入门窗格.最近访问列表.以及实例的表单方面的调整,下面一一介绍. Ribbon特性 MS CRM2011中,使用了Ribbon作为工作菜单的 ...

  7. angular routerlink传递参数_[翻译]在 Angular 中使用 async-await 特性

    在 Angular 中使用 async-await 特性 原文链接: https://medium.com/@balramchavan/using-async-await-feature-in-ang ...

  8. WWDC2017 笔记 - Cocoa Touch 中的新特性

    这篇文章是 What's New in Cocoa Touch / UIKit Session 201 的一些整理.[基于OC] 转自我的 Blog: Danny's Dream Drag Drop ...

  9. Java中的继承性特性

    继承性是java中的第二特性之一.而继承性最为关键的地方为:代码重用性的问题,利用继承性可以从已有的类中继续派生出新的子类,也可以利用子类扩展出更多的操作功能. 继承性的实现代码为:class 子类 ...

最新文章

  1. python SMTP发送邮件常出现问题
  2. 2021年人工神经网络第四次作业:基于MATLAB的求解
  3. SpringBoot 中常用注解@PathVaribale/@RequestParam/@GetMapping介绍
  4. x264_sps_init
  5. 为什么C语言还是被很多人说成过时了?
  6. 面试题45:圆圈中最后剩下的数字
  7. 整理了 25 个前端相关的学习网站和一些靠谱的小工具,都来看看吧
  8. 人脸方向学习(二十一):Face Landmark Detection-FAB-解读
  9. 设计模式---责任链模式(C++实现)
  10. 知识融合(实体对齐)笔记
  11. Java基本数据类型与包装数据类型的使用标准
  12. 查看mysql默认端口号和修改端口号
  13. Otsu阈值分割详解
  14. 市场上常见电阻阻值表
  15. 科研为什么需要甘特图
  16. 2G/3G LAC与4G/5G TAC的协同优化
  17. 华中科技大学计算机视觉张朋,计算机视觉与深度学习前沿研讨会圆满举办
  18. ORACLE 19c via Docker on Mac安装教程客户端配置连接Navicat GUI
  19. 数据库之关系模型介绍
  20. 红帽杯find_it

热门文章

  1. android 应用状态,保持应用程序状态在Android上
  2. Vue中使用LayUI没有效果
  3. 深度学习和目标检测系列教程 14-300:训练第一个 YOLOv3 检测器
  4. 知识图谱有哪些方向是可以深入研究的?
  5. 详解京东商城智能对话系统(生成+检索)
  6. MIT开源高性能自动微分框架Enzyme:速度提升4.5倍
  7. ECCV 2018论文解读 | DeepVS:基于深度学习的视频显著性方法
  8. 揭秘阿里小蜜:基于检索模型和生成模型相结合的聊天引擎 | PaperDaily #25
  9. 【腾讯面试题】MySQL常用数据库引擎
  10. AIProCon在线大会笔记之张钹院士:探索第三代人工智能,需要勇闯无人区的人才!