Traits的用法

WBOY
Libérer: 2016-07-29 09:15:16
original
1461 Les gens l'ont consulté
原文出处: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

  1. trait ezcReflectionReturnInfo {  
  2. function getReturnType() {  
  3. }  
  4. function getReturnDescription() {  
  5. }  
  6. }class ezcReflectionMethod extends ReflectionMethod {  
  7. use ezcReflectionReturnInfo;  
  8. /* ... */  
  9. }  
  10. class ezcReflectionFunction extends ReflectionFunction {  
  11. use ezcReflectionReturnInfo;  
  12. /* ... */  
  13. }  
  14. ?>  
 2)优先级
基类中的成员函数将被Traits中的函数覆盖,当前类中的成员函数将覆盖Traits中的函数。

[php] view plaincopy

  1. class Base {  
  2.     public function sayHello() {  
  3.         echo 'Hello ';  
  4.     }  
  5. }  
  6.   
  7. trait SayWorld {  
  8.     public function sayHello() {  
  9.         parent::sayHello();  
  10.         echo "World!\n";  
  11.     }  
  12. }  
  13.   
  14. class MyHelloWorld extends Base {  
  15.     use SayWorld;  
  16. }  
  17.   
  18. class MyHelloWorldExt extends Base {  
  19.     use SayWorld;  
  20.     public function sayHello() {  
  21.         /** 
  22.          * 这里是5.4中的新的改动,5.4之前的版本会提示: 
  23.          * PHP Fatal error:  Cannot use string offset as an array 
  24.          * 5.4中改进为返回字符串中的该索引号的字符 
  25.          */  
  26.         $str  = "Arvin";  
  27.         echo $str[0][0];// echo 'A';  
  28.     }  
  29.   
  30.     public function shortArray() {  
  31.         $array = ['first', 2, 3, 4];//5.4中的数组简单语法  
  32.         echo $array[0];//5.4中的数组解引用取数组元素方法  
  33.     }  
  34. }  
  35.   
  36. $o = new MyHelloWorld();  
  37. $o->sayHello();  
  38. $oe = new MyHelloWorldExt();  
  39. $oe->sayHello();  
  40. echo "\n";  
  41. $oe->shortArray();  

[php] view plaincopy

  1. 输出:  
  2. Hello World!  
  3. A  
  4. first  
 3)多Traits多个Traits可以添加到一个class的声明中,多个Traits之间用","隔开。

[php] view plaincopy

  1. trait Hello {  
  2.     public function sayHello() {  
  3.         echo 'Hello ';  
  4.     }  
  5. }  
  6.   
  7. trait World {  
  8.     public function sayWorld() {  
  9.         echo 'World';  
  10.     }  
  11. }  
  12.   
  13. class MyHelloWorld {  
  14.     use Hello, World;  
  15. }  
  16.   
  17. $o = new MyHelloWorld();  
  18. $o->sayHello();  
  19. $o->sayWorld();  
  20. ?>  
输出结果:
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
Copier après la connexion
 在最后贴上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.//类新实例解引用操作,上文中有实例
Copier après la connexion
本文旨在抛砖引玉,希望大家一起继续探究php5.4的新功能。^_^

以上就介绍了Traits的用法,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal