php5.4新功能Traits
php5.4新功能Traits介绍
1. traits
Traits是在5.4中新增的一个用于实现代码重用的方法。
php是一种单一继承的语言,我们无法像java一样在一个class中extends多个基类来实现代码重用,现在Traits能解决这一代码重用的问题,它能让开发者在多个不同的class中实现代码重用。
Traits和class在语义的定义上都是为了减少代码的复杂性,避免多重继承的问题。
Traits 和class相似,但是仅用于以统一和较细粒度的方式来提供一组功能,在Traits内部无法进行实例化,即不存在类似class的构造函数__construct()。Traits作为一个php传统继承的扩展并实现水平集成;因此,在应用程序的class中可以不再需要继承。
1)如何使用
在类中用关键字'use' 来引用 Traits。多个Traits 用','隔开。
实例代码如下:
- <?php
- trait ezcReflectionReturnInfo {
- function getReturnType() {
- }
- function getReturnDescription() {
- }
- }class ezcReflectionMethod extends ReflectionMethod {
- use ezcReflectionReturnInfo;
- /* ... */
- }
- class ezcReflectionFunction extends ReflectionFunction {
- use ezcReflectionReturnInfo;
- /* ... */
- }
- ?>
2)优先级
基类中的成员函数将被Traits中的函数覆盖,当前类中的成员函数将覆盖Traits中的函数。
- <?php
- class Base {
- public function sayHello() {
- echo 'Hello ';
- }
- }
- trait SayWorld {
- public function sayHello() {
- parent::sayHello();
- echo "World!\n";
- }
- }
- class MyHelloWorld extends Base {
- use SayWorld;
- }
- class MyHelloWorldExt extends Base {
- use SayWorld;
- public function sayHello() {
- /**
- * 这里是5.4中的新的改动,5.4之前的版本会提示:
- * PHP Fatal error: Cannot use string offset as an array
- * 5.4中改进为返回字符串中的该索引号的字符
- */
- $str = "Arvin";
- echo $str[0][0];// echo 'A';
- }
- public function shortArray() {
- $array = ['first', 2, 3, 4];//5.4中的数组简单语法
- echo $array[0];//5.4中的数组解引用取数组元素方法
- }
- }
- $o = new MyHelloWorld();
- $o->sayHello();
- $oe = new MyHelloWorldExt();
- $oe->sayHello();
- echo "\n";
- $oe->shortArray();
- 输出:
- Hello World!
- A
- first
3)多Traits
多个Traits可以添加到一个class的声明中,多个Traits之间用","隔开。
- <?php
- trait Hello {
- public function sayHello() {
- echo 'Hello ';
- }
- }
- trait World {
- public function sayWorld() {
- echo 'World';
- }
- }
- class MyHelloWorld {
- use Hello, World;
- }
- $o = new MyHelloWorld();
- $o->sayHello();
- $o->sayWorld();
- ?>
输出结果:
Hello World
4)多Traits冲突
如果添加到同一个class的两个Traits中有相同的函数名称,且没有明确的进行处理,将产生一个错误。
为了解决同一个类中两个Tratis中的同名函数冲突,需要用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;
- }
- }
- ?>
上面的例子中,Talker使用Traits A 和B,因此两者中相同的函数名称存在冲突。
alker中定义了smallTalk取自Traits B,bigTalk取自Traits A。
Aliased_Talker中通过使用as操作符来确保Traits B中的bigTalk通过别名talk来实现。
5)改变函数访问权限
我们可以使用as语法来改变Traits中函数的访问权限属性。
- <?php
- trait HelloWorld {
- public function sayHello() {
- echo 'Hello World!';
- }
- }
- // Change visibility of sayHello,改变sayHello的访问权限。
- class MyClass1 {
- use HelloWorld { sayHello as protected; }
- }
- // Alias method with changed visibility
- // sayHello visibility not changed,设置别名myPrivateHello。
- class MyClass2 {
- use HelloWorld { sayHello as private myPrivateHello; }
- }
- ?>
6)Traits组成新Traits
就像许多类一样可以在类中使用Traits,Traits中一样可以使用Traits。可以在一个Traits中定义一个或者多个Traits,这些Traits 可以作为部分或者全部成员被定义在其他Traits中。
- <?php
- trait Hello {
- public function sayHello() {
- echo 'Hello ';
- }
- }
- trait World {
- public function sayWorld() {
- echo 'World!';
- }
- }
- trait HelloWorld {
- use Hello, World;
- }
- class MyHelloWorld {
- use HelloWorld;
- }
- $o = new MyHelloWorld();
- $o->sayHello();
- $o->sayWorld();
- ?>
以上例程会输出:
- Hello World!
7)抽象Trait成员
为了在类中强制实现某些方法,可以在Traits中使用抽象方法。
例如:
- <?php
- trait Hello {
- public function sayHelloWorld() {
- echo 'Hello '.$this->getWorld();
- }
- abstract public function getWorld();
- }
- class MyHelloWorld {
- private $world;
- use Hello;
- public function __construct($world) {
- $this->world = $world;
- }
- public function getWorld() {
- return $this->world;
- }
- }
- /**
- * 这里用到了5.4新功能 类实例化解引用操作
- * (new class())->method();
- */
- (new MyHelloWorld('Arvin'))->sayHelloWorld();
- ?>
- 该实例输出:
- Hello Arvin
8)静态Trait成员
在Traits中不能定义static 静态变量,但是可以定义在Tratis的函数中。Tratis中同样可以定义静态函数。
- <?php
- trait Counter {
- public function inc() {
- static $c = 0;//静态变量
- $c += 1;
- echo "$c\n";
- }
- /**
- * 静态方法
- */
- public static function doSomething() {
- echo 'Doing something';
- }
- }
- class C1 {
- use Counter;
- }
- (new C1())->inc(); // echo 1
- C1::doSomething();
- ?>
- 输出为:
- 1
- Doing something
9) Traits 定义属性
如果在一个trait中定义了一个属性,则在引用该trait的类中不能定义同名的属性,如果该类中定义有和trait中已定义属性具有相同的名字和访问可见性,则是一个E_STRICT
提示,否则抛出语法错误。
<?php
trait PropertiesTrait {
public $x = 1;
public $y = 2;
} class PropertiesExample {
use PropertiesTrait;
public $x = 1;
//public $y = 3;
} $example = new PropertiesExample;
echo $example->x, $example->y;
?> 输出:
12
在最后贴上php5.4.0部分新功能changelog:
Added short array syntax support ([1,2,3]), see UPGRADING guide for full details.
Added binary numbers format (0b001010).
Added support for Class::{expr}() syntax.
Added support for Traits.//本文的主要内容
Added closure $this support back.
Added array dereferencing support.//数组解引用支持,上文中有实例
Added callable typehint.
Added indirect method call through array. #47160.
Added DTrace support.//传说DTrace是一个性能分析工具,可以跟踪出函数调用点,返回点等数据
Added class member access on instantiation (e.g. (new foo)->bar()) support.//类新实例解引用操作,上文中有实例
转载 http://blog.csdn.net/longlongmylove/article/details/7521379
php5.4新功能Traits的更多相关文章
- PHP5各个版本的新功能和新特性总结
因为 PHP 那“集百家之长”的蛋疼语法,加上社区氛围不好,很多人对新版本,新特征并无兴趣.本文将会介绍自 PHP5.2 起,直至 PHP5.6 中增加的新特征 本文目录:PHP5.2 以前:auto ...
- PHP5各个版本的新功能和新特性总结(转载 http://www.jb51.net/article/48150.htm)
本文目录:PHP5.2 以前:autoload, PDO 和 MySQLi, 类型约束PHP5.2:JSON 支持PHP5.3:弃用的功能,匿名函数,新增魔术方法,命名空间,后期静态绑定,Heredo ...
- PHP 5.2、5.3、5.4、5.5、5.6 版本区别对比以及新功能详解
截至目前(2015.1), PHP 的最新稳定版本是 PHP5.5, 但有差不多一半的用户仍在使用已经不在维护 的 PHP5.2, 其余的一半用户在使用 PHP5.3 . 因为 PHP 那“集百家之 ...
- 从淘宝 UWP 的新功能 -- 比较页面来谈谈 UWP 的窗口多开功能
前言 之前在 剁手党也有春天 -- 淘宝 UWP ”比较“功能诞生记 这篇随笔中介绍了一下 UWP 淘宝的“比较”新功能呱呱坠地的过程.在鲜活的文字背后,其实都是程序员不眠不休的血泪史(有血有泪有史) ...
- Sql Server 2016新功能之 Row-Level Security
Sql Server 2016 有一个新功能叫 Row-Level Security ,大概意思是行版本的安全策略(原来我是个英语渣_(:з」∠)_) 直接上例子.这个功能相当通过对表添加一个函数作为 ...
- What's new in Windows 10 Enterprise with Microsoft Edge.(Windows 10 新功能)
What's new in Windows 10 Enterprise with Microsoft Edge --带有Edge浏览器的Windows 10 企业版的新功能 本文摘录自公司群发邮件, ...
- MySQL 5.7 Replication 相关新功能说明
背景: MySQL5.7在主从复制上面相对之前版本多了一些新特性,包括多源复制.基于组提交的并行复制.在线修改Replication Filter.GTID增强.半同步复制增强等.因为都是和复制相关, ...
- SQL Server2016 新功能实时查询统计信息
SQL Server2016 新功能实时查询统计信息 很多时候有这样的场景,开发抱怨DBA没有调优好数据库,DBA抱怨开发写的程序代码差,因此,DBA和开发都成为了死对头,无法真正排查问题. DBA只 ...
- 一个新人如何学习在大型系统中添加新功能和Debug
文章背景: 今年七月份正式入职,公司主营ERP软件,楼主所在的组主要负责二次开发,使用的语言是Java. 什么叫二次开发呢?ERP软件的客户都是企业.而这些企业之间的情况都有所不同,一套标准版本的企业 ...
随机推荐
- Go Web:Handler
Multiplexer根据URL将请求路由给指定的Handler.Handler用于处理请求并给予响应.更严格地说,用来读取请求体.并将请求对应的响应字段(respones header)写入Resp ...
- YTKNetwork源码详解
本篇是第三篇关于网络请求的,将讲述YTKNetwork源码,上述两篇分别讲述AFNetworking源码解析以及结合自己项目封装AFNetworking. AFNetworking源码解析:https ...
- @property详解,@property修饰符以及各个修饰符区别(上)
相信很多参加过面试的人员很多都会被问到:weak与assign的区别,copy与strong的区别.如果你仅仅说一点点copy一般对NSString,weak对于控件的修饰,assign对于基本类型, ...
- C#异常处理。
一.什么是异常? 程序运行时发生的错误. 二.异常处理的一般代码模式. try{..可能发生异常的代码} catch{..对异常的处理} finally{...无论是否发生异常.是否捕获异常都会执行的 ...
- 【转载】 Sqlserver查看数据库死锁的SQL语句
在Sqlsever数据库中,有时候操作数据库过程中会进行锁表操作,在锁表操作的过程中,有时候会出现死锁的情况出现,这时候可以使用SQL语句来查询数据库死锁情况,主要通过系统数据库Master数据库来查 ...
- python面向对象学习(一)基本概念
目录 1. 面向对象基本概念 1.1 过程和函数 1.2 面相过程 和 面相对象 基本概念 2. 类和对象的概念 1.1 类 1.3 对象 3. 类和对象的关系 4. 类的设计 大驼峰命名法 4.1 ...
- Unix awk的流程控制BEGIN和END的讲解
你可能对Unix比较熟悉,但你可能对Unix awk很陌生,这一点也不奇怪,的确,与其优秀的功能相比,awk还远没达到它应有的知名度. 流程控制语句是任何程序设计语言都不能缺少的部分.任何好的语言都有 ...
- spring-framework-中文文档一:IoC容器、介绍Spring IoC容器和bean
5. IoC容器 5.1介绍Spring IoC容器和bean 5.2容器概述 本章介绍Spring Framework实现控制反转(IoC)[1]原理.IoC也被称为依赖注入(DI).它是一个过程, ...
- ecstore Fatal error: Class 'base_request' not found
1.首次安装已存在的ecstore报错: Fatal error: Class 'base_request' not found 报错效果图:(ecstore 乱码需要安装zend guard loa ...
- 浅析 JavaScript 中的 Function.prototype.bind() 方法
Function.prototype.bind()方法 bind() 方法的主要作用就是将函数绑定至某个对象,bind() 方法会创建一个函数,函数体内this对象的值会被绑定到传入bind() 函数 ...