原文出处:http://blog.csdn.net/longlongmylove/article/details/7521379
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] view
plaincopy
- trait ezcReflectionReturnInfo {
- function getReturnType() {
- }
- function getReturnDescription() {
- }
- }class ezcReflectionMethod extends ReflectionMethod {
- use ezcReflectionReturnInfo;
- /* ... */
- }
- class ezcReflectionFunction extends ReflectionFunction {
- use ezcReflectionReturnInfo;
- /* ... */
- }
- ?>
2)优先级
基类中的成员函数将被Traits中的函数覆盖,当前类中的成员函数将覆盖Traits中的函数。
[php] view
plaincopy
- 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();
[php] view
plaincopy
- 输出:
- Hello World!
- A
- first
3)多Traits多个Traits可以添加到一个class的声明中,多个Traits之间用","隔开。
[php] view
plaincopy
- 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<phelvetica neue font-size:15px line-height:24px>4)多Traits冲突<br>如果添加到同一个class的两个Traits中有相同的函数名称,且没有明确的进行处理,将产生一个错误。<br>为了解决同一个类中两个Tratis中的同名函数冲突,需要用insteadof操作符来选择正确的函数。<br>因为方法的唯一性和排他性,'as'操作符允许用在冲突函数之后以解决内部冲突的问题。<divcourier new width:936.53125px overflow:auto padding-top:1px line-height:26px margin:18px background-color:rgb><p></p>
<p>[php] view
plaincopy
</p>
<ol start="1">
<li><span><span><?php </span></span></span></li>
<li><span>trait A { </span></li>
<li><span><span>public</span><span> </span><span>function</span><span> smallTalk() { </span></span></li>
<li><span><span>echo</span><span> </span><span>'a'</span><span>; </span></span></li>
<li><span>} </span></li>
<li><span><span>public</span><span> </span><span>function</span><span> bigTalk() { </span></span></li>
<li><span><span>echo</span><span> </span><span>'A'</span><span>; </span></span></li>
<li><span>} </span></li>
<li><span>} </span></li>
<li><span> </span></li>
<li><span>trait B { </span></li>
<li><span><span>public</span><span> </span><span>function</span><span> smallTalk() { </span></span></li>
<li><span><span>echo</span><span> </span><span>'b'</span><span>; </span></span></li>
<li><span>} </span></li>
<li><span><span>public</span><span> </span><span>function</span><span> bigTalk() { </span></span></li>
<li><span><span>echo</span><span> </span><span>'B'</span><span>; </span></span></li>
<li><span>} </span></li>
<li><span>} </span></li>
<li><span> </span></li>
<li><span><span>class</span><span> Talker { </span></span></li>
<li><span><span>use</span><span> A, B { </span></span></li>
<li><span>B::smallTalk insteadof A; </span></li>
<li><span>A::bigTalk insteadof B; </span></li>
<li><span>} </span></li>
<li><span>} </span></li>
<li><span> </span></li>
<li><span><span>class</span><span> Aliased_Talker { </span></span></li>
<li><span><span>use</span><span> A, B { </span></span></li>
<li><span>B::smallTalk insteadof A; </span></li>
<li><span>A::bigTalk insteadof B; </span></li>
<li><span>B::bigTalk <span>as</span><span> talk; </span></span></li>
<li><span>} </span></li>
<li><span>} </span></li>
<li><span>?> </span></li>
</ol>
<phelvetica neue font-size:15px line-height:24px>上面的例子中,Talker使用Traits A 和B,因此两者中相同的函数名称存在冲突。<br>alker中定义了smallTalk取自Traits B,bigTalk取自Traits A。<br>Aliased_Talker中通过使用as操作符来确保Traits B中的bigTalk通过别名talk来实现。<br>5)改变函数访问权限<br>我们可以使用as语法来改变Traits中函数的访问权限属性。<divcourier new width:936.53125px overflow:auto padding-top:1px line-height:26px margin:18px background-color:rgb><p></p>
<p>[php] view
plaincopy
</p>
<ol start="1">
<li><span><span><?php </span></span></span></li>
<li><span>trait HelloWorld { </span></li>
<li><span><span>public</span><span> </span><span>function</span><span> sayHello() { </span></span></li>
<li><span><span>echo</span><span> </span><span>'Hello World!'</span><span>; </span></span></li>
<li><span>} </span></li>
<li><span>} </span></li>
<li><span> </span></li>
<li><span><span>// Change visibility of sayHello,改变sayHello的访问权限。</span><span> </span></span></li>
<li><span><span>class</span><span> MyClass1 { </span></span></li>
<li><span><span>use</span><span> HelloWorld { sayHello </span><span>as</span><span> </span><span>protected</span><span>; } </span></span></li>
<li><span>} </span></li>
<li><span> </span></li>
<li><span><span>// Alias method with changed visibility</span><span> </span></span></li>
<li><span><span>// sayHello visibility not changed,设置别名myPrivateHello。</span><span> </span></span></li>
<li><span><span>class</span><span> MyClass2 { </span></span></li>
<li><span><span>use</span><span> HelloWorld { sayHello </span><span>as</span><span> </span><span>private</span><span> myPrivateHello; } </span></span></li>
<li><span>} </span></li>
<li><span>?> </span></li>
</ol>
<phelvetica neue font-size:15px line-height:24px> <phelvetica neue font-size:15px line-height:24px>6)Traits组成新Traits<br>就像许多类一样可以在类中使用Traits,Traits中一样可以使用Traits。可以在一个Traits中定义一个或者多个Traits,这些Traits 可以作为部分或者全部成员被定义在其他Traits中。<divcourier new width:936.53125px overflow:auto padding-top:1px line-height:26px margin:18px background-color:rgb><p></p>
<p>[php] view
plaincopy
</p>
<ol start="1">
<li><span><span><?php </span></span></span></li>
<li><span>trait Hello { </span></li>
<li><span><span>public</span><span> </span><span>function</span><span> sayHello() { </span></span></li>
<li><span><span>echo</span><span> </span><span>'Hello '</span><span>; </span></span></li>
<li><span>} </span></li>
<li><span>} </span></li>
<li><span> </span></li>
<li><span>trait World { </span></li>
<li><span><span>public</span><span> </span><span>function</span><span> sayWorld() { </span></span></li>
<li><span><span>echo</span><span> </span><span>'World!'</span><span>; </span></span></li>
<li><span>} </span></li>
<li><span>} </span></li>
<li><span> </span></li>
<li><span>trait HelloWorld { </span></li>
<li><span><span>use</span><span> Hello, World; </span></span></li>
<li><span>} </span></li>
<li><span> </span></li>
<li><span><span>class</span><span> MyHelloWorld { </span></span></li>
<li><span><span>use</span><span> HelloWorld; </span></span></li>
<li><span>} </span></li>
<li><span> </span></li>
<li><span><span>$o</span><span> = </span><span>new</span><span> MyHelloWorld(); </span></span></li>
<li><span><span>$o</span><span>->sayHello(); </span></span></li>
<li><span><span>$o</span><span>->sayWorld(); </span></span></li>
<li><span>?> </span></li>
</ol>
<phelvetica neue font-size:15px line-height:24px>以上例程会输出:<divcourier new width:936.53125px overflow:auto padding-top:1px line-height:26px margin:18px background-color:rgb><p></p>
<p>[php] view
plaincopy
</p>
<ol start="1"><li><span><span>Hello World! </span></span></li></ol>
<phelvetica neue font-size:15px line-height:24px>7)抽象Trait成员<br>为了在类中强制实现某些方法,可以在Traits中使用抽象方法。<br>例如:<divcourier new width:936.53125px overflow:auto padding-top:1px line-height:26px margin:18px background-color:rgb><p></p>
<p>[php] view
plaincopy
</p>
<ol start="1">
<li><span><span><?php </span></span></span></li>
<li><span>trait Hello { </span></li>
<li><span> <span>public</span><span> </span><span>function</span><span> sayHelloWorld() { </span></span></li>
<li><span> <span>echo</span><span> </span><span>'Hello '</span><span>.</span><span>$this</span><span>->getWorld(); </span></span></li>
<li><span> } </span></li>
<li><span> <span>abstract</span><span> </span><span>public</span><span> </span><span>function</span><span> getWorld(); </span></span></li>
<li><span>} </span></li>
<li><span> </span></li>
<li><span><span>class</span><span> MyHelloWorld { </span></span></li>
<li><span> <span>private</span><span> </span><span>$world</span><span>; </span></span></li>
<li><span> <span>use</span><span> Hello; </span></span></li>
<li><span> <span>public</span><span> </span><span>function</span><span> __construct(</span><span>$world</span><span>) { </span></span></li>
<li><span> <span>$this</span><span>->world = </span><span>$world</span><span>; </span></span></li>
<li><span> } </span></li>
<li><span> <span>public</span><span> </span><span>function</span><span> getWorld() { </span></span></li>
<li><span> <span>return</span><span> </span><span>$this</span><span>->world; </span></span></li>
<li><span> } </span></li>
<li><span>} </span></li>
<li><span> </span></li>
<li><span><span>/**</span> </span></li>
<li><span><span> * 这里用到了5.4新功能 类实例化解引用操作</span> </span></li>
<li><span><span> * (new class())->method();</span> </span></li>
<li><span><span> */</span><span> </span></span></li>
<li><span>(<span>new</span><span> MyHelloWorld(</span><span>'Arvin'</span><span>))->sayHelloWorld(); </span></span></li>
<li><span>?> </span></li>
<li><span> </span></li>
<li><span>该实例输出: </span></li>
<li><span>Hello Arvin </span></li>
</ol>
<phelvetica neue font-size:15px line-height:24px> <phelvetica neue font-size:15px line-height:24px>8)静态Trait成员<phelvetica neue font-size:15px line-height:24px>在Traits中不能定义static 静态变量,但是可以定义在Tratis的函数中。Tratis中同样可以定义静态函数。<divcourier new width:936.53125px overflow:auto padding-top:1px line-height:26px margin:18px background-color:rgb><p></p>
<p>[php] view
plaincopy
</p>
<ol start="1">
<li><span><span><?php </span></span></span></li>
<li><span>trait Counter { </span></li>
<li><span> <span>public</span><span> </span><span>function</span><span> inc() { </span></span></li>
<li><span> <span>static</span><span> </span><span>$c</span><span> = 0;</span><span>//静态变量</span><span> </span></span></li>
<li><span> <span>$c</span><span> += 1; </span></span></li>
<li><span> <span>echo</span><span> </span><span>"$c\n"</span><span>; </span></span></li>
<li><span> } </span></li>
<li><span> <span>/**</span> </span></li>
<li><span><span> * 静态方法</span> </span></li>
<li><span><span> */</span><span> </span></span></li>
<li><span> <span>public</span><span> </span><span>static</span><span> </span><span>function</span><span> doSomething() { </span></span></li>
<li><span> <span>echo</span><span> </span><span>'Doing something'</span><span>; </span></span></li>
<li><span> } </span></li>
<li><span>} </span></li>
<li><span> </span></li>
<li><span><span>class</span><span> C1 { </span></span></li>
<li><span> <span>use</span><span> Counter; </span></span></li>
<li><span>} </span></li>
<li><span> </span></li>
<li><span>(<span>new</span><span> C1())->inc(); </span><span>// echo 1</span><span> </span></span></li>
<li><span>C1::doSomething(); </span></li>
<li><span>?> </span></li>
<li><span>输出为: </span></li>
<li><span>1 </span></li>
<li><span>Doing something </span></li>
</ol>
<phelvetica neue font-size:15px line-height:24px>9) Traits 定义属性<phelvetica neue font-size:15px line-height:24px>如果在一个trait中定义了一个属性,则在引用该trait的类中不能定义同名的属性,如果该类中定义有和trait中已定义属性具有相同的名字和访问可见性,则是一个<span><codeandale mono sans font-size:13px line-height:normal>E_STRICT</codeandale></span> 提示,否则抛出语法错误。<pre name="code" courier pitch monospace font-size: line-height: margin-bottom: padding: background-color: rgb><?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.//类新实例解引用操作,上文中有实例
登录后复制
本文旨在抛砖引玉,希望大家一起继续探究php5.4的新功能。^_^
以上就介绍了Traits的用法,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
-
2024-10-22 09:46:29
-
2024-10-13 13:53:41
-
2024-10-12 12:15:51
-
2024-10-11 22:47:31
-
2024-10-11 19:36:51
-
2024-10-11 15:50:41
-
2024-10-11 15:07:41
-
2024-10-11 14:21:21
-
2024-10-11 12:59:11
-
2024-10-11 12:17:31