PHP中trait的特性
转载链接: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则避免了这点。下面通过简单的额例子来进行对比说明。
- 继承 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的特性相关推荐
- PHP 5.4中的traits特性
Trait 是 PHP5.4 中的新特性,是 PHP 多重继承的一种解决方案.例如,需要同时继承两个 Abstract Class, 这将会是件很麻烦的事情,Trait 就是为了解决这个问题.简单使用 ...
- 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 ...
- Entity Framework 4.3 中的新特性
原文地址:http://www.cnblogs.com/supercpp/archive/2012/02/20/2354751.html EF4.3于2月9号正式发布了,微软的EF小组最近一年开始发力 ...
- 第一次来,试发一帖!--ASP.NET 2.0 中的SqlCacheDependency特性
ASP.NET中的Page Cache是个很有用的东东,只要简单的在页面上方加上一个OutputCache标签,就可以让页面在制定的Duration内直接把自动保存在缓存中的页面内容输出,而不需要让A ...
- Spring 2.5:Spring MVC中的新特性
转载说明:infoQ就是牛人多,看人家去年就把Spring2.5注视驱动的MVC写出来了,还是这么详细,我真是自叹不如,今天偶尔看到这篇文章非常认真的拜读了2遍,简直是茅厕顿开啊....\(^o^)/ ...
- MS CRM 2011中的新特性(1)——界面部分
MS crm2011中,在界面部分的调整包括有ribbon.入门窗格.最近访问列表.以及实例的表单方面的调整,下面一一介绍. Ribbon特性 MS CRM2011中,使用了Ribbon作为工作菜单的 ...
- angular routerlink传递参数_[翻译]在 Angular 中使用 async-await 特性
在 Angular 中使用 async-await 特性 原文链接: https://medium.com/@balramchavan/using-async-await-feature-in-ang ...
- WWDC2017 笔记 - Cocoa Touch 中的新特性
这篇文章是 What's New in Cocoa Touch / UIKit Session 201 的一些整理.[基于OC] 转自我的 Blog: Danny's Dream Drag Drop ...
- Java中的继承性特性
继承性是java中的第二特性之一.而继承性最为关键的地方为:代码重用性的问题,利用继承性可以从已有的类中继续派生出新的子类,也可以利用子类扩展出更多的操作功能. 继承性的实现代码为:class 子类 ...
最新文章
- python SMTP发送邮件常出现问题
- 2021年人工神经网络第四次作业:基于MATLAB的求解
- SpringBoot 中常用注解@PathVaribale/@RequestParam/@GetMapping介绍
- x264_sps_init
- 为什么C语言还是被很多人说成过时了?
- 面试题45:圆圈中最后剩下的数字
- 整理了 25 个前端相关的学习网站和一些靠谱的小工具,都来看看吧
- 人脸方向学习(二十一):Face Landmark Detection-FAB-解读
- 设计模式---责任链模式(C++实现)
- 知识融合(实体对齐)笔记
- Java基本数据类型与包装数据类型的使用标准
- 查看mysql默认端口号和修改端口号
- Otsu阈值分割详解
- 市场上常见电阻阻值表
- 科研为什么需要甘特图
- 2G/3G LAC与4G/5G TAC的协同优化
- 华中科技大学计算机视觉张朋,计算机视觉与深度学习前沿研讨会圆满举办
- ORACLE 19c via Docker on Mac安装教程客户端配置连接Navicat GUI
- 数据库之关系模型介绍
- 红帽杯find_it
热门文章
- android 应用状态,保持应用程序状态在Android上
- Vue中使用LayUI没有效果
- 深度学习和目标检测系列教程 14-300:训练第一个 YOLOv3 检测器
- 知识图谱有哪些方向是可以深入研究的?
- 详解京东商城智能对话系统(生成+检索)
- MIT开源高性能自动微分框架Enzyme:速度提升4.5倍
- ECCV 2018论文解读 | DeepVS:基于深度学习的视频显著性方法
- 揭秘阿里小蜜:基于检索模型和生成模型相结合的聊天引擎 | PaperDaily #25
- 【腾讯面试题】MySQL常用数据库引擎
- AIProCon在线大会笔记之张钹院士:探索第三代人工智能,需要勇闯无人区的人才!