什么是 trait

  看看 PHP 官网的介绍。

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

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

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

例子1

  手机和汽车都有 GPS 功能,GPS 是用来定位的功能的,因此功能应该是统一的。手机 和 汽车 除了 GPS 功能外,基本没有什么相同之处,因此不能使用继承。而接口的话,我认为不同的类去实现接口时,接口的实现可能是不同的,但是 GPS 的功能就是用来定位的。因此使用 trait ,而不使用 class 和 interface,这是我的理解,不知道是否正确。

  gps.php 的定义:

 <?php

 trait Gps {
public function gps() {
echo 'i can gps';
}
}

  使用 trait 定义了一个 GPS 的 trait 用于复用,它的关键字是 trait 。然后在 car.php 和 mobile.php 中进行引用。

  

  car.php 的定义:

 class Car {
use gps; public function move() {
echo 'i can move';
}
}

  mobile.php 的定义:

 <?php

 class Mobile {
use gps;
public function tel() {
echo 'i can tel';
}
}

  在 car.php 和 mobile.php 中,使用 use 关键字引入了 gps 的 trait ,这样在 car 和 mobile 中就可以调用 gps() 这个方法了。

  test.php 进行测试:

 <?php

 require_once('gps.php');
require_once('car.php');
require_once('mobile.php'); $car = new Car();
$mobile = new Mobile(); $car->gps();
echo "\n";
$mobile->gps();

  输出结果如下:

 i can gps
i can gps

例子2

  在 car 中引入了另外一个国产的 gps 。

  gpschina.php 定义如下:

 <?php

 trait GpsChina {

     public function gps() {
echo 'i can chinae gps';
}
}

  在 car 中引入,修改 car.php 的定义如下:

 <?php

 class Car {
use gps, gpschina; public function move() {
echo 'i can move';
}
}

  再次调用 test.php 进行测试,这时会报错,报错如下:

 Fatal error: Trait method gps has not been applied, because there are collisions with other trait methods on Car in Car.php on line 

  因为在引入的 trait 中 gps 和 gpschina 各有一个 gps ,而直接使用 $car->gps() 时无法确定到底使用的是 gps 的 gps() 方法,还是使用的 gpschina 的 gps() 方法,因此报错了。这样的话,我们需要确定一个。修改 car.php 文件。

 <?php

 class Car {
use gps, gpschina {
GpsChina::gps insteadof Gps;
} public function move() {
echo 'i can move';
}
}

  这样就使用 GpsChina::gps 的方法 替换掉了 Gps 的方法了,在调用 test.php 进行查看。

 i can chinae gps
i can gps

  这样,对于 $car->gps() 后就调用了 gpschina 中的 gps() 方法了。

例子3

  如果在 Car 类中本身有一个 gps() 方法呢?修改 Car 类。

 <?php

 class Car {
use gps, gpschina {
GpsChina::gps insteadof Gps;
} public function gps() {
echo 'car::gps';
} public function move() {
echo 'i can move';
}
}

  调用 test.php 查看结果:

 car::gps
i can gps

  可以看出,调用了 Car 类本身的 gps() 方法。

  

  如果在一个类中,继承自父类的方法、use 引入 trait 的方法 和 类自身的方法同名的话,优先调用 自身类的 方法,如果没有 自身类的方法 则调用 use 引入 trait 的方法,如果前两个都没有,那么就调用继承自父类的方法。

  

  关于 trait 更多的用法,请参考:http://www.php.net/manual/zh/language.oop5.traits.php


我的微信公众号:“码农UP2U”

PHP 中的关于 trait 的简单的更多相关文章

  1. Android中NDK的搭建及简单使用 Android.mk相关介绍 JNI的使用

    Android中NDK的搭建及简单使用: 使用NDK,简述其重要步骤:.搭建NDK环境(作用:用于自动生成jni下的.c对应的so文件)---到Android NDK官网或Android官网下载ndk ...

  2. (转)Java中使用正则表达式的一个简单例子及常用正则分享

    转自:http://www.jb51.net/article/67724.htm 这篇文章主要介绍了Java中使用正则表达式的一个简单例子及常用正则分享,本文用一个验证Email的例子讲解JAVA中如 ...

  3. java 中 “文件” 和 “流” 的简单分析

    java 中 FIle 和 流的简单分析 File类 简单File 常用方法 创建一个File 对象,检验文件是否存在,若不存在就创建,然后对File的类的这部分操作进行演示,如文件的名称.大小等 / ...

  4. C/C++中substr函数的应用(简单讲解)

    substr(字符串,截取开始位置,截取长度) //返回截取的字 substr('Hello World',0,1) //返回结果为 'H'  *从字符串第一个字符开始截取长度为1的字符串 subst ...

  5. shell中,我们可以通过简单的一个判断来判断命令是否存在

    shell中,我们可以通过简单的一个判断来判断命令是否存在 which "Command" > /dev/null if [ $? -eq 0 ] then echo com ...

  6. DELPHI中完成端口(IOCP)的简单分析(4)

    DELPHI中完成端口(IOCP)的简单分析(4)   在我以前写的文章中,一直说的是如何接收数据.但是对于如何发送数据却一点也没有提到.因为从代码量上来说接收的代码要比发送多很多.今天我就来写一下如 ...

  7. DELPHI中完成端口(IOCP)的简单分析(3)

    DELPHI中完成端口(IOCP)的简单分析(3)   fxh7622关注4人评论7366人阅读2007-01-17 11:18:24   最近太忙,所以没有机会来写IOCP的后续文章.今天好不容易有 ...

  8. DELPHI中完成端口(IOCP)的简单分析(2)

    DELPHI中完成端口(IOCP)的简单分析(2)   今天我写一下关于DELPHI编写完成端口(IOCP)的工作者线程中的东西.希望各位能提出批评意见.上次我写了关于常见IOCP的代码,对于IOCP ...

  9. DELPHI中完成端口(IOCP)的简单分析(1)

    DELPHI中完成端口(IOCP)的简单分析(1)   用DELPHI开发网络代码已经有一段时间了! 我发现在网上用VC来实现完成端口(IOCP)的代码很多,但是使用DELPHI来实现的就比较少了.对 ...

随机推荐

  1. IT兄弟连 Java语法教程 流程控制语句 经典案例

    使用continue忽略本次循环剩下的语句 continue的功能和break有点类似,区别是continue只是忽略本次循环剩下的语句,接着开始下一次循环,并不会终止循环:而break则是完全终止循 ...

  2. 实现拖拽列表-微信小程序

    之前在网上搜索拖拽列表的实现时,发现了有好多的方法都是基于像素位置的计算实现的,这种方法要求列表元素的大小以及列表的位置有着非常严格的要求,修改和拓展起来非常的麻烦.于是我自己动手实现了一个基于页面元 ...

  3. 数据库之MySQL查询

    查询 创建数据库.数据表 -- 创建数据库 create database python_test1 charset=utf8; -- 使用数据库 use python_test1; -- stude ...

  4. 打开excel打印时报“不能使用对象链接和嵌入”

    解决思路: 1.以WIN + R 打开命令行, 在命令行中输入dcomcnfg,打开组件服务. 2.在组件服务窗口中,点击到[控制根节点]->[组件服务]->[计算机]->[我的电脑 ...

  5. [译]Zookeeper的优点与局限性

    1.Zookeeper的优点与局限性 在学习了Zookeeper(后文都简称zk)的介绍和功能后,您已经很好地理解了zk. 现在,在这个zk教程中,我们将讨论zk的优点和局限性. zk有几个功能对用户 ...

  6. 设置view的layer属性方法

    1.需要导入QuartzCore.framewoork框架到工程2.在文件中导入#import 3.设置 必须导入的空间 #import<QuartzCore/QuartzCore.h> ...

  7. 剑指offer 18:树的子结构

    题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 解题思路 验证B是不是A的子树,直觉做法,按照任意次序遍历A树,一旦出现和B树根节点相同的子节点, ...

  8. 026.[转] 基于Docker及Kubernetes技术构建容器云平台 (PaaS)

    [编者的话] 目前很多的容器云平台通过Docker及Kubernetes等技术提供应用运行平台,从而实现运维自动化,快速部署应用.弹性伸缩和动态调整应用环境资源,提高研发运营效率. 本文简要介绍了与容 ...

  9. win7个性化不能换界面:此页面上的一个或多个设置已被系统管理员禁用,关机里的切换用户和锁定为灰色

    win7个性化不能换界面:此页面上的一个或多个设置已被系统管理员禁用,关机里的切换用户和锁定为灰色 找到注册表 cmd-regedit HKEY_CURRENT_USER\Software\Micro ...

  10. show()和隐藏hide() slideDown()和 slideUp() fadeIn()和fadeOut()

    1==>显示show()和隐藏hide() 是一组动画 与切换toggle()$("div").show():当不传递参数时,没有动画效果,它将某个元素瞬间显示出来 $(&q ...