PHP中的Trait 特性及作用


Posted in PHP onApril 03, 2016

自 PHP 5.4.0 起,PHP 实现了代码复用的一个方法,称为 traits。

Traits 是一种为类似 PHP 的单继承语言而准备的代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用方法集。Traits 和类组合的语义是定义了一种方式来减少复杂性,避免传统多继承和混入类(Mixin)相关的典型问题。

Trait 和一个类相似,但仅仅旨在用细粒度和一致的方式来组合功能。Trait 不能通过它自身来实例化。它为传统继承增加了水平特性的组合;也就是说,应用类的成员不需要继承。

Trait是在PHP5.4中加入的,它既不是接口也不是类。主要是为了解决单继承语言的限制。是PHP多重继承的一种解决方案。例如,需要同时继承两个 Abstract Class, 这将会是件很麻烦的事情,Trait 就是为了解决这个问题。它能被加入到一个或多个已经存在的类中。它声明了类能做什么(表明了其接口特性),同时也包含了具体实现(表明了其类特性)

简单使用

首先,当然是声明个 Trait,PHP5.4 增加了 trait 关键字

trait first_trait {
function first_method() { /* Code Here */ }
function second_method() { /* Code Here */ }
}

同时,如果要在 Class 中使用该 Trait,那么使用 use 关键字

class first_class {
// 注意这行,声明使用 first_trait
use first_trait;
}
$obj = new first_class();
// Executing the method from trait
$obj->first_method(); // valid
$obj->second_method(); // valid

使用多个 Trait

在同个 Class 中可以使用多个 Trait

trait first_trait
{
function first_method() { echo "method"; }
}
trait second_trait {
function second_method() { echo "method"; }
}
class first_class {
// now using more than one trait
use first_trait, second_trait;
}
$obj= new first_class();
// Valid
$obj->first_method(); // Print : method
// Valid
$obj->second_method(); // Print : method

Trait 之间的嵌套

同时,Trait 之间也可以相互的嵌套,例如

trait first_trait {
function first_method() { echo "method"; }
}
trait second_trait {
use first_trait;
function second_method() { echo "method"; }
}
class first_class {
// now using 
use second_trait;
}
$obj= new first_class();
// Valid
$obj->first_method(); // Print : method
// Valid
$obj->second_method(); // Print : method

Trait 的抽象方法(Abstract Method)

我们可以在 Trait 中声明需要实现的抽象方法,这样能使使用它的 Class 必须实现它

trait first_trait {
function first_method() { echo "method"; }
// 这里可以加入修饰符,说明调用类必须实现它
abstract public function second_method();
}
class first_method {
use first_trait;
function second_method() {
/* Code Here */
}
}

Trait 冲突

多个 Trait 之间同时使用难免会冲突,这需要我们去解决。PHP5.4 从语法方面带入了相关 的关键字语法:insteadof 以及 as ,用法参见

trait first_trait {
function first_function() { 
echo "From First Trait";
}
}
trait second_trait {
// 这里的名称和 first_trait 一样,会有冲突
function first_function() { 
echo "From Second Trait";
}
}
class first_class {
use first_trait, second_trait {
// 在这里声明使用 first_trait 的 first_function 替换
// second_trait 中声明的
first_trait::first_function insteadof second_trait;
}
} 
$obj = new first_class();
// Output: From First Trait
$obj->first_function();

上面就是些 Trait 比较基本的使用了,更详细的可以参考官方手册。这里总结下注意的几 点:

Trait 会覆盖调用类继承的父类方法

Trait 无法如 Class 一样使用 new 实例化

单个 Trait 可由多个 Trait 组成

在单个 Class 中,可以使用多个 Trait

Trait 支持修饰词(modifiers),例如 final、static、abstract

我们能使用 insteadof 以及 as 操作符解决 Trait 之间的冲突

PHP 相关文章推荐
PHP脚本的10个技巧(2)
Oct 09 PHP
Windows下IIS6/Apache2.2.4+MySQL5.2+PHP5.2.1安装配置方法
May 03 PHP
php一句话cmdshell新型 (非一句话木马)
Apr 18 PHP
php 获取select下拉列表框的值
May 08 PHP
php preg_filter执行一个正则表达式搜索和替换
Feb 27 PHP
Thinkphp模板中使用自定义函数的方法
Sep 23 PHP
浅析application/x-www-form-urlencoded和multipart/form-data的区别
Jun 22 PHP
ThinkPHP处理Ajax返回的方法
Nov 22 PHP
PHP连接MSSQL方法汇总
Feb 05 PHP
php实现基于openssl的加密解密方法
Sep 30 PHP
php+Memcached实现简单留言板功能示例
Feb 15 PHP
PHP ADODB生成HTML表格函数rs2html功能【附错误处理函数用法】
May 29 PHP
PHP错误处理函数
Apr 03 #PHP
php通过curl添加cookie伪造登陆抓取数据的方法
Apr 02 #PHP
PHP函数nl2br()与自定义函数nl2p()换行用法分析
Apr 02 #PHP
PHP使用stream_context_create()模拟POST/GET请求的方法
Apr 02 #PHP
PHP函数shuffle()取数组若干个随机元素的方法分析
Apr 02 #PHP
PHP函数import_request_variables()用法分析
Apr 02 #PHP
PHP数组函数array_multisort()用法实例分析
Apr 02 #PHP
You might like
PHP学习 运算符与运算符优先级
2008/06/15 PHP
PHP异步调用socket实现代码
2012/01/12 PHP
PHP开发工具ZendStudio下Xdebug工具使用说明详解
2013/11/11 PHP
Joomla语言翻译类Jtext用法分析
2016/05/05 PHP
Laravel学习教程之IOC容器的介绍与用例
2017/08/15 PHP
向大师们学习Javascript(视频与PPT)
2009/12/27 Javascript
js 得到文件后缀(通过正则实现)
2013/07/08 Javascript
为什么Node.js会这么火呢?Node.js流行的原因
2014/12/01 Javascript
JS实现表格数据各种搜索功能的方法
2015/03/03 Javascript
JS与jQuery遍历Table所有单元格内容的方法
2015/12/07 Javascript
Node.js与MySQL交互操作及其注意事项
2016/10/05 Javascript
解决vue keep-alive 数据更新的问题
2018/09/21 Javascript
vue同步父子组件和异步父子组件的生命周期顺序问题
2018/10/07 Javascript
微信小程序实现侧边栏分类
2019/10/21 Javascript
Vue 3.0双向绑定原理的实现方法
2019/10/23 Javascript
JS Thunk 函数的含义和用法实例总结
2020/04/08 Javascript
JavaScript 闭包的使用场景
2020/09/17 Javascript
[49:17]DOTA2-DPC中国联赛 正赛 Phoenix vs Dynasty BO3 第三场 1月26日
2021/03/11 DOTA
python导出hive数据表的schema实例代码
2018/01/22 Python
详解Django中间件的5种自定义方法
2018/07/26 Python
Python实现的批量修改文件后缀名操作示例
2018/12/07 Python
Python scrapy增量爬取实例及实现过程解析
2019/12/24 Python
Python网络爬虫信息提取mooc代码实例
2020/03/06 Python
使用pth文件添加Python环境变量方式
2020/05/26 Python
Python定义一个Actor任务
2020/07/29 Python
pycharm不以pytest方式运行,想要切换回普通模式运行的操作
2020/09/01 Python
Super-Pharm波兰:药房和香水在一个地方
2020/08/18 全球购物
第二层交换机和路由器的区别?第三层交换机和路由器的区别?
2013/05/23 面试题
优秀体育委员自荐书
2014/01/31 职场文书
毕业生就业推荐表自我鉴定
2014/03/20 职场文书
大一新生期末自我评价
2014/09/12 职场文书
反腐倡廉剖析材料
2014/09/30 职场文书
调任通知
2015/04/21 职场文书
浅谈vue2的$refs在vue3组合式API中的替代方法
2021/04/18 Vue.js
CSS Transition通过改变Height实现展开收起元素
2021/08/07 HTML / CSS
【海涛教你打DOTA】死灵飞龙第一视角解说
2022/04/01 DOTA