什么是 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”

最新文章

  1. [AlwaysOn Availability Groups]排查:AG超过RPO
  2. YII2 项目安装步骤及异常记录
  3. form表单取消按钮自动提交
  4. JS正则检测密码强度
  5. [Eclipse] Eclipse配置Tomcat插件
  6. BZOJ1829 : [Usaco2010 Mar]starc星际争霸
  7. sql server 关联更新
  8. Cocos2d-x开发实例:单点触摸事件
  9. [Irving] Ext.Net动态添加GridPanel列绑定Checkbox值失败的解决办法
  10. 也谈Excel导出
  11. Android仿微信图片上传,可以选择多张图片,缩放预览,拍照上传等
  12. bootstrap 导航栏
  13. android 开发心得杂记
  14. spring 自动化构建项目
  15. 用mybatis实现dao的编写或者实现mapper代理
  16. wpf改变网格字体颜色
  17. git纯净提交代码(只提交自己改过的文件)
  18. vue环境安装
  19. POSIX 线程取消点的 Linux 实现
  20. escape()、encodeURI()、encodeURIComponent()区别详解 (转)

热门文章

  1. 直接命令行中执行PHP代码(PHP CLI模式)
  2. JMS消息传递类型特点介绍
  3. mysql 常用命令行总结
  4. 微信网站登录doem
  5. Java生鲜电商平台-电商会员体系系统的架构设计与源码解析
  6. 漫谈golang设计模式 工厂模式
  7. Pi Network有梦想是好的,最新消息和下载注册流程。
  8. 【JavaWeb】EL表达式
  9. [Go] gocron源码阅读-go语言web框架Macaron
  10. appium---uiautomator定位方法