PHP新特性Trait
Trait是PHP 5.4引入的新概念,看上去既像类又像接口,其实都不是,Trait可以看做类的部分实现,可以混入一个或多个现有的PHP类中,其作用有两个:表明类可以做什么;提供模块化实现。Trait是一种代码复用技术,为PHP的单继承限制提供了一套灵活的代码复用机制。
为什么使用Trait
PHP语言使用一种典型的单继承模型,在这种模型中,我们先编写一个通用的根类,实现基本的功能,然后扩展这个根类,创建更具体的子类,直接从父类继承实现。这叫做继承层次结构,很多编程语言都使用这个模式。大多数时候这种典型的继承模型能够良好运作,但是如果想让两个无关的PHP类具有类似的行为,应该怎么做呢?
Trait就是为了解决这种问题而诞生的。Trait能够把模块化的实现方式注入多个无关的类中,从而提高代码复用,符合DRY(Don’t Repeat Yourself)原则。比如Laravel底层用户认证相关逻辑以及软删除实现等地方都使用了Trait来实现。以Laravel自带的AuthController
为例,其中的登录、注册以及登录失败尝试次数都是通过Trait实现:
如何创建Trait
创建Trait很简单,跟创建类有点类似,只不过使用的关键字是trait
而不是class
,以上述ThrottlesLogin
为例:
我们通过trait
声明定义的是一个Trait,然后我们可以在这个Trait中像类一样定义要使用的属性和方法。
此外Trait支持嵌套和组合,即通过一个或多个Trait(多个用,分隔)组合成一个Trait,比如
使用多个Trait可能会引起命名冲突问题,上面的代码给出了解决方案:使用insteadof
关键字,如果AuthenticatesUsers
和RegistersUsers
中都定义了redirectPath
和getGuard
方法,那么将从AuthenticatesUsers
中获取对应方法而不是RegistersUsers
。另外还可以使用as
关键字为方法起个别名,这样也可以避免命名冲突。
此外,这里可能没有完整列出,Trait中还支持定义抽象方法和静态方法,其中抽象方法必须在使用它的类中实现。
这里还需要声明的一点是调用方法的优先级:调用类>Trait>父类(如果有的话),方法可以覆盖,但属性不行,如果Trait中定义了一个属性,如果调用类中也定义这个属性则会报错。
如何使用Trait
Trait的使用方法也很简单,上面已经显示的很清楚明了,即使用use
关键字。
可能你已经注意到,命名空间和Trait使用的都是use
关键字,不同之处在于导入位置,命名空间在类的定义体外导入,而Trait在类的定义体内导入。
注:PHP解释器在编译时会把Trait复制到类的定义体中,但是不会处理这个操作引入的不兼容问题,如果Trait假定类中有特定的属性或方法,需要先确保类中确实有相应的属性或方法。
原文链接:Trait 概览
PHP新特性Trait的更多相关文章
- PHP 新特性:如何善用接口与Trait
首先! 接口也可以继承,通过使用 extends 操作符. 案例: <?php interface a { public function foo(); } interface b extend ...
- Java 8新特性终极指南
目录结构 介绍 Java语言的新特性 2.1 Lambdas表达式与Functional接口 2.2 接口的默认与静态方法 2.3 方法引用 2.4 重复注解 2.5 更好的类型推测机制 2.6 扩展 ...
- JDK各个版本的新特性jdk1.5-jdk8
JDK各个版本的新特性 对于很多刚接触java语言的初学者来说,要了解一门语言,最好的方式就是要能从基础的版本进行了解,升级的过程,以及升级的新特性,这样才能循序渐进的学好一门语言.今天先为大家介绍一 ...
- JDK各版本新特性!
1.JDK1.5 新特性 1.自动装箱与拆箱:自动装箱的过程:每当需要一种类型的对象时,这种基本类型就自动地封装到与它相同类型的包装中.自动拆箱的过程:每当需要一个值时,被装箱对象中的值就被自动地提取 ...
- java8新特性全面解析
在Java Code Geeks上有大量的关于Java 8 的教程了,像玩转Java 8--lambda与并发,Java 8 Date Time API 教程: LocalDateTime和在Java ...
- Java8 十大新特性详解(转)
本教程将Java8的新特新逐一列出,并将使用简单的代码示例来指导你如何使用默认接口方法,lambda表达式,方法引用以及多重Annotation,之后你将会学到最新的API上的改进,比如流,函数式接口 ...
- java5、java6、java7、java8的新特性
Java5: 1.泛型 Generics: 引用泛型之后,允许指定集合里元素的类型,免去了强制类型转换,并且能在编译时刻进行类型检查的好处. Parameterized Type作为参数 ...
- php 新特性
PHP 5.6 1.可以使用表达式定义常量 https://php.net/manual/zh/migration56.new-features.php 在之前的 PHP 版本中,必须使用静态值来定义 ...
- Java8新特性【转】
地址:http://ifeve.com/java-8-features-tutorial/ 1.简介 毫无疑问,Java 8是自Java 5(2004年)发布以来Java语言最大的一次版本升级,Ja ...
随机推荐
- java之servlet学习基础(二)
上一次写到Servlet的实现方法,主要还是通过继承HttpServlet来实现Servlet.下面主要是回顾一下HttpServletRequest和HttpServletResponse对象中的一 ...
- IEnumerable对象的Distinct方法重写
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource ...
- python中print不换行
python中的print打印的结果总是进行了换行,如果不想换行显示可以在print中添加“end ='' ” 一般print显示: for i in range(3): print(i) #显示结果 ...
- Golang之路【目录】
我正在写一套使用Golang全栈开发的教程,名字暂叫“Golang之路”,希望大家多提建议. 目录如下: Golang之路[第一篇]:Golang简介和入门Golang之路[第二篇]:Golang基础 ...
- 创建Gitblit本地服务器(For windows )01
1.先下载gitblit 貌似需要FQ,百度云链接https://pan.baidu.com/s/1WUtBswj5TkFFcd_hiFFCcw,提取码: xr9n .因为gitblit是基于jav ...
- 解决:Adobe Acrobat Pro中设置背景颜色后,出现白色条纹
找到 编辑->首选项->页面显示->渲染->使用2D图形加速 取消即可
- jQuery源码框架fn解读
(function( window, undefined ){ var jQuery = (function(){ var jQuery = function( selector, context ) ...
- shell传递参数
简单介绍python的脚本传参 我们知道python脚本传递参数,有一个很方便的方式-sys.argv.它将脚本本身名字和后面的各项参数都放入一个列表. 使用的时候,索引这个列表就可以了.例如: py ...
- mysql无密码登陆
mysql登陆不上或者密码忘记可以尝试一下无密码登陆 以下一波神操作!! 首先关闭数据库服务(数据库在Centos7版本以上或者Redhat版本上被改名为mariadb) systemctl stop ...
- 将 Idea 常用快捷键 设置为 Eclipse 的快捷键