摘要:很明显这违背了原则。而方式则避免了上述的不足之处相对优雅的实现了代码的复用。中属性的优先级说到优先级就必须要有一个对比的参照物这里的参照对象时引用的类及其父类。其他介绍的的文章如何使用文章首发在中详解及其应用
从PHP的5.4.0版本开始,PHP提供了一种全新的代码复用的概念,那就是Trait。Trait其字面意思是"特性"、"特点",我们可以理解为,使用Trait关键字,可以为PHP中的类添加新的特性。
熟悉面向对象的都知道,软件开发中常用的代码复用有继承和多态两种方式。在PHP中,只能实现单继承。而Trait则避免了这点。下面通过简单的额例子来进行对比说明。
1. 继承 VS 多态 VS Trait现在有Publish.php和Answer.php这两个类。要在其中添加LOG功能,记录类内部的动作。有以下几种方案:
继承
多态
Trait
1.1. 继承如图:
代码结构如下:
// Log.php// Publish.php// Answer.php可以看到继承的确满足了要求。但这却违背了面向对象的原则。而发布(Publish)和回答(Answer)这样的操作和日志(Log)之间的关系并不是子类与父类的关系。所以不推荐这样使用。
1.2. 多态如图:
实现代码:
// Log.php// Publish.php// Answer.php记录日志的操作应该都是一样的,因此,发布(Publish)和回答(Answer)动作中的日志记录实现也是一样的。很明显,这违背了DRY(Don"t Repeat Yourself)原则。所以是不推荐这样实现的。
1.3. Trait如图:
实现代码如下:
// Log.php// Publish.php startLog(); $publish->endLog();// Answer.php startLog(); $answer->endLog();可以看到,我们在没有增加代码复杂的情况下,实现了代码的复用。
1.4. 结论继承的方式虽然也能解决问题,但其思路违背了面向对象的原则,显得很粗暴;多态方式也可行,但不符合软件开发中的DRY原则,增加了维护成本。而Trait方式则避免了上述的不足之处,相对优雅的实现了代码的复用。
2. Trait的作用域了解了Trait的好处,我们还需要了解其实现中的规则,先来说一下作用域。这个比较好证明,实现代码如下:
publicF(); $this->protectF(); $this->privateF(); } } $publish = new Publish(); $publish->doPublish();执行上述代码输出结果如下:
public function protected function private function可以发现,Trait的作用域在引用该Trait类的内部是都可见的。可以理解为use关键字将Trait的实现代码Copy了一份到引用该Trait的类中。
3. Trait中属性的优先级说到优先级,就必须要有一个对比的参照物,这里的参照对象时引用Trait的类及其父类。
通过以下的代码来证明Trait应用中的属性的优先级:
publicF(); $this->protectF(); } } $publish = new Publish(); $publish->doPublish();上述代码的输出结果如下:
Publish::publicF public function Log::protectF protected function通过上面的例子,可以总结出Trait应用中的优先级如下:
来自当前类的成员覆盖了 trait 的方法
trait 覆盖了被继承的方法
类成员优先级为:当前类>Trait>父类
4. Insteadof和As关键字在一个类中,可以引用多个Trait,如下:
startLog(); $this->parameterCheck($para); $this->endLog(); } }通过上面的方式,我们可以在一个类中引用多个Trait。引用多个Trait的时候,就容易出问题了,最常见的问题就是两个Trait中如果出现了同名的属性或者方法该怎么办呢?这个时候就需要用到Insteadof 和 as 这两个关键字了.请看如下实现代码:
startLog(); $this->parameterCheck("params"); $this->csl(); } } $publish = new Publish(); $publish->doPublish();执行上述代码,输出结果如下:
Log::startLog public function Check::parameterCheck parameter checkparams Check::startLog public function就如字面意思一般,insteadof关键字用前者取代了后者,as 关键字给被取代的方法起了一个别名。
在引用Trait时,使用了use关键字,use关键字也用来引用命名空间。两者的区别在于,引用Trait时是在class内部使用的。
其他介绍的Trait的文章:如何使用Trait?
文章首发在:PHP中Trait详解及其应用
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/22266.html
摘要:原文链接是单继承的语言,在出现之前,的类无法同时从两个基类继承属性或方法。的和语言的组合功能类似,通过在类中使用关键字声明要组合的名称,而具体某个的声明使用关键词,不能直接实例化。 原文链接:http://tabalt.net/blog/php-tr... PHP是单继承的语言,在PHP 5.4 Traits出现之前,PHP的类无法同时从两个基类继承属性或方法。php的Traits和G...
摘要:关于作者程序开发人员,不拘泥于语言与技术,目前主要从事和前端开发,使用和,端使用混合式开发。和组合的语义定义了一种减少复杂性的方式,避免传统多继承和类相关典型问题。它为传统继承增加了水平特性的组合也就是说,应用的几个之间不需要继承。 关于作者 程序开发人员,不拘泥于语言与技术,目前主要从事PHP和前端开发,使用Laravel和VueJs,App端使用Apicloud混合式开发。合适和...
摘要:和组合的语义定义了一种减少复杂性的方式,避免传统多继承和类相关典型问题。队列的目的是将耗时的任务延时处理,比如发送邮件,从而大幅度缩短请求和相应的时间。同样的道理,根据引入不同的来完成对应的功能。 showImg(https://segmentfault.com/img/remote/1460000010868178); Trait 概念 在常规的 PHP 开发中,我们都习惯于先编写一...
摘要:类与对象基本概念如果在之后跟着的是一个包含有类名的字符串,则该类的一个实例被创建。如果该类属于一个名字空间,则必须使用其完整名称。如果一个类被声明为,则不能被继承。命名空间通过关键字来声明。 类与对象 基本概念 new:如果在 new 之后跟着的是一个包含有类名的字符串,则该类的一个实例被创建。如果该类属于一个名字空间,则必须使用其完整名称。 Example #3 创建一个实例 ...
阅读 2063·2021-11-24 09:39
阅读 1495·2021-10-11 10:59
阅读 2454·2021-09-24 10:28
阅读 3340·2021-09-08 09:45
阅读 1241·2021-09-07 10:06
阅读 1579·2019-08-30 15:53
阅读 2031·2019-08-30 15:53
阅读 1395·2019-08-30 15:53