Trait是自 PHP 5.4.0 起添加的一个新特性,是 PHP 多重继承的一种解决方案。例如,需要同时继承两个 Abstract Class, 这将会是件很麻烦的事情,Trait 就是为了解决这个问题。

下面是一个例子,类Demo同时继承了Test1Test2

<?php
trait Test1{
public function add($a, $b){
echo $a + $b;
}
} trait Test2{
public function sub($a, $b){
echo $a - $b;
}
} class Demo{
use Test1,Test2;
} $obj = new Demo();
$obj->add(3, 5); // 8 $obj->sub(3, 5); // -2

一些特性

1、优先级:当前类 > trait > 基类 。 即当前类中的方法会覆盖 trait 方法,而 trait 方法又覆盖了基类中的方法。

2、多个 trait: 通过逗号分隔,在 use 声明列出多个 trait,可以都插入到一个类中。

3、冲突的解决:

如果两个 trait 都插入了一个同名的方法,如果没有明确解决冲突将会产生一个致命错误。

为了解决多个 trait 在同一个类中的命名冲突,需要使用 insteadof 操作符来明确指定使用冲突方法中的哪一个。

以上方式仅允许排除掉其它方法,as 操作符可以将其中一个冲突的方法以另一个名称来引入。

<?php
trait A {
public function smallTalk() {
echo 'a';
}
public function bigTalk() {
echo 'A';
}
} trait B {
public function smallTalk() {
echo 'b';
}
public function bigTalk() {
echo 'B';
}
} class Talker {
use A, B {
B::smallTalk insteadof A;
A::bigTalk insteadof B;
}
} class Aliased_Talker {
use A, B {
B::smallTalk insteadof A;
A::bigTalk insteadof B;
B::bigTalk as talk;
}
}
?>

4、trait嵌套:Trait 之间也可以相互的嵌套:在 trait 定义时通过使用一个或多个 trait,它能够组合其它 trait 中的部分或全部成员。

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

需要注意的几点

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

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

单个 Trait 可由多个 Trait 组成

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

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

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

一些看法

坦白讲,第一眼看到 Trait 对它并没有任何好感。PHP5 以来带来的新特性已经足够得多,而且让开发者们有点应接不暇。

同时,Trait 更像是程序员的“语法糖”,然而它提供便利的同时可能会造成巨大的隐患。

针对类中已经实现的方法,Trait 没有效果。

探讨

那么 Trait 的出现是为何呢?有网友的回答比较有意思,但不无道理:

因为php没有javascript作用域链的机制,所以无法把function bind到class里面,曾经以为php 5.3的闭包可以做这个事,最后才发觉作用域的设计不允许这么干。

参考:

1、PHP: Traits - Manual

http://php.net/manual/zh/language.oop5.traits.php

2、PHP 5.4 的 Trait 特性_Web开发_酷勤网

http://www.kuqin.com/web/20111119/315048.html

PHP中Trait特性的更多相关文章

  1. 【Scala篇】--Scala中Trait、模式匹配、样例类、Actor模型

    一.前述 Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大. 模式匹配机制相当于java中的switch-case. 使用了case关键字的类定义就是样例类(case ...

  2. Laravel中Trait的用法实例详解

    本文实例讲述了Laravel中Trait的用法.分享给大家供大家参考,具体如下: 看看PHP官方手册对Trait的定义: 自 PHP 5.4.0 起,PHP 实现了代码复用的一个方法,称为 trait ...

  3. PHP Trait特性

    php类的单继承性,无法同时从两个基类中继承属性和方法,为了解决这个问题,使用Trait特性解决. Trait是一种代码复用技术,为PHP的单继承限制提供了一套灵活的代码复用机制. 用法:通过在类中使 ...

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

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

  5. C#中的 特性 详解(转载)

    本篇幅转载于:http://www.cnblogs.com/rohelm/archive/2012/04/19/2456088.html C#中特性详解 特性提供了功能强大的方法,用于将元数据或声明信 ...

  6. java 对象的this使用 java方法中参数传递特性 方法的递归

    一.this关键字,使用的情形,以及如何使用. 1.使用的情形 类中的方法体中使用this  --初始化该对象 类的构造器中使用this --引用,调用该方法的对象 2.不写this,调用 只要方法或 ...

  7. .net中的特性

    本文来之:http://hi.baidu.com/sanlng/item/afa31eed0a383e0e570f1d3e 在一般的应用中,特性(Attribute,以称为属性)好像被使用的不是很多. ...

  8. Performance Tuning guide 翻译 || Performance Tuning Guide 11G中新增特性

    CSDN 对格式支持比較弱.能够到http://user.qzone.qq.com/88285879/blog/1399382878 看一致的内容. Performance Tuning Guide  ...

  9. C#中的特性 (Attribute) 入门 (二)

    C#中的特性 (Attribute) 入门 (二) 接下来我们要自己定义我们自己的特性,通过我们自己定义的特性来描述我们的代码. 自定义特性 所有的自定义特性都应该继承或者间接的继承自Attribut ...

随机推荐

  1. Mac 下安装ruby,以及CocoaPods安装以及使用网摘

    ruby安装网址:https://ruby-china.org/wiki/install_ruby_guide CocoaPods安装和使用教程地址:http://code4app.com/artic ...

  2. com.microsoft.sqlserver.jdbc.SQLServerException: 用户 'sa' 登录失败。

    com.microsoft.sqlserver.jdbc.SQLServerException: 用户 'sa' 登录失败. at com.microsoft.sqlserver.jdbc.SQLSe ...

  3. 封装ios静态库碰到的一些问题(三)

    静态库封装好以后,就存在一个问题,静态库,模拟器的静态库何真机的静态库是分开的,那么能够合并,答案是肯定的,但是必须我们手工在终端工具下执行命令合并 lipo -create Release-ipho ...

  4. Robot Framework安装教程

    第一步:安装Python,安装的版本是python-2.7.9.amd64.msi 安装教程详见地址:http://jingyan.baidu.com/article/c910274be14d64cd ...

  5. js创建对象的方法

    1. 使用Object构造函数来创建一个对象,下面代码创建了一个person对象,并用两种方式打印出了Name的属性值. var person = new Object(); person.name= ...

  6. 接口测试总结<转>

    本文主要分为两个部分: 第一部分:主要从问题出发,引入接口测试的相关内容并与前端测试进行简单对比,总结两者之前的区别与联系.但该部分只交代了怎么做和如何做?并没有解释为什么要做? 第二部分:主要介绍为 ...

  7. Spring学习笔记 6. 尚硅谷_佟刚_Spring_Bean 之间的关系

    1,继承关系 首先从简单的代码来看,有一个Address类,配置文件有两个bean (1)Address类 package com.zsq; public class Address { privat ...

  8. pushState 和 replaceState

    使用此方法浏览器前进后退仍然可查看对应内容 设置值 history.pushState({}, "页面标题", "xxx.html"); history.rep ...

  9. Android中 int 和 String 互相转换的多种方法

    1 如何将字串 String 转换成整数 int? A. 有两个方法: 1). int i = Integer.parseInt([String]); 或 i = Integer.parseInt([ ...

  10. 使用Maven自动部署Tomcat 6和Tomcat 7下Web应用

    使用Maven自动部署Tomcat 6和Tomcat 7下Web应用 开启Tomcat远程管理权限 在tomcat的config目录下的tomcat-users.xml文件, <role rol ...