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,比如AuthenticatesAndRegistersUsers即是如此:

使用多个Trait可能会引起命名冲突问题,上面的代码给出了解决方案:使用insteadof关键字,如果AuthenticatesUsersRegistersUsers中都定义了redirectPathgetGuard方法,那么将从AuthenticatesUsers中获取对应方法而不是RegistersUsers。另外还可以使用as关键字为方法起个别名,这样也可以避免命名冲突。

此外,这里可能没有完整列出,Trait中还支持定义抽象方法和静态方法,其中抽象方法必须在使用它的类中实现。

这里还需要声明的一点是调用方法的优先级:调用类>Trait>父类(如果有的话),方法可以覆盖,但属性不行,如果Trait中定义了一个属性,如果调用类中也定义这个属性则会报错。

如何使用Trait

Trait的使用方法也很简单,上面已经显示的很清楚明了,即使用use关键字。

可能你已经注意到,命名空间和Trait使用的都是use关键字,不同之处在于导入位置,命名空间在类的定义体外导入,而Trait在类的定义体内导入。

注:PHP解释器在编译时会把Trait复制到类的定义体中,但是不会处理这个操作引入的不兼容问题,如果Trait假定类中有特定的属性或方法,需要先确保类中确实有相应的属性或方法。

Trait 概览的更多相关文章

  1. 现代 PHP 新特性系列(三) —— Trait 概览

    Trait是PHP 5.4引入的新概念,看上去既像类又像接口,其实都不是,Trait可以看做类的部分实现,可以混入一个或多个现有的PHP类中,其作用有两个:表明类可以做什么:提供模块化实现.Trait ...

  2. PHP新特性Trait

    Trait是PHP 5.4引入的新概念,看上去既像类又像接口,其实都不是,Trait可以看做类的部分实现,可以混入一个或多个现有的PHP类中,其作用有两个:表明类可以做什么:提供模块化实现.Trait ...

  3. Activity之概览屏幕(Overview Screen)

    概览屏幕 概览屏幕(也称为最新动态屏幕.最近任务列表或最近使用的应用)是一个系统级别 UI,其中列出了最近访问过的 Activity 和任务. 用户可以浏览该列表并选择要恢复的任务,也可以通过滑动清除 ...

  4. Atitit 软件工程概览attilax总结

    Atitit 软件工程概览attilax总结 1.1. .2 软件工程的发展 进一步地,结合人类发展史和计算机世界演化史来考察软件工程的发展史. 表2 软件工程过程模型 表2将软件工程的主要过程模型做 ...

  5. Scala快速概览

    IDEA工具安装及scala基本操作 目录 一. 1. 2. 3. 4. 二. 1. 2. 3. 三. 1. 2. 3. 4. 5. 6. 7. 四. 1. (1) (2) (3) (4) (5) ( ...

  6. php中trait(性状)与generator(生成器)

    PHP中trait(性状)与generator(生成器) 一.trait (性状) 最近在看Josh Lockhat的<Modern PHP>,这本书很薄.但是其中给出了一个很重要的学习方 ...

  7. 【转】PHP的Trait 特性

    Trait是在PHP5.4中加入的,它既不是接口也不是类.主要是为了解决单继承语言的限制.是PHP多重继承的一种解决方案.例如,需要同时继承两个 Abstract Class, 这将会是件很麻烦的事情 ...

  8. Beginning Scala study note(7) Trait

    A trait provides code reusability in Scala by encapsulating method and state and then offing possibi ...

  9. iOS开发系列—Objective-C之基础概览

    概览 前面我们已经用了几章内容进行C语言介绍,当然要通过几篇文章完整的介绍C语言的知识是不太现实的,例如C语言的文件操作.内存申请等我们都没有重点介绍,当然核心知识点基本都已经提到了,后面有时间我们会 ...

随机推荐

  1. Java其他API介绍

    有一些类虽然不像集合.多线程.网络编程中的类那样属于Java中的核心类,但是它们在开发过程中给我们带来很多便利,这里就对它们做下简要的介绍和演示. 一.System类 System类中的构造方法是私有 ...

  2. 20155319 2016-2017-2 《Java程序设计》第六周学习总结

    20155319 2016-2017-2 <Java程序设计>第六周学习总结 教材学习内容总结 ==第十章 输入/输出== 10.1 InputStream与OutputStream 10 ...

  3. 1029:Ignatius and the Princess IV

    题目大意是找出数组中出现次数超过一半的数. 基本思想:每遇到两个不同的数就消掉,设一个计数器就行了.   存出现次数最大的那个数的出现次数. 当下一个数与当前的数不同时,计数器减一,相同,则加一. 实 ...

  4. Documentation/kobject.txt翻译--sysfs

    你从未想过的关于kobjects,ksets和ktypes的一切:作者:Greg Kroah-Hartman <gregkh@linuxfoundation.org>:上次更新时间:200 ...

  5. nginx 配置实现逻辑预算

    nginx 的配置 不支持逻辑与和逻辑非运算,也不支持if 嵌套,只能用其他方式实现 set $flag 0; if ($host != name) { set $flag "${flag} ...

  6. 使用树莓派制作一套“NAS+私有云盘+下载机”

    ‍ ‍‍原创作者:HackLiu‍‍ ‍ 0×00 前言 ‍‍如果你家里有多台设备需要联网需要娱乐,你一定会或多或少遇到设备碎片化带来的烦恼.当然,已经有很多厂商包括新晋的小米.360在内的互联网公司 ...

  7. 【转】inittab文件

    原文网址:http://blog.csdn.net/shuaishuai80/article/details/6202482 一.inittab文件背景(1)init进程的作用   使用uboot下载 ...

  8. 关于Eclipse

    Navigator窗口 之前看到同事使用Eclipse的Navigator窗口,十分不解这个窗口有啥用:今天通过了解才知道Package Explorer是从工程的角度来显示文件,比如settings ...

  9. wamp安装后无法正常启动(80端口被占用)

    关于wamp启动是80端口被占用的问题详解(win7系统下WAMP 80端口被Microsoft-HTTPAPI/2.0占用的解决办法) VS2010在更新了SP1后,会在开机时自动启动一个服务,占用 ...

  10. bzoj3802: Vocabulary

    Description 给你三个字符串,这些字符串有些单词模糊不可认了,用"?"来代表. 现在你可以用任意英文小写字母来代表它们.要求是使得给定的三个字符串中 所有的"? ...