zoukankan      html  css  js  c++  java
  • 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 用','隔开。

    实例代码如下:

    1. <?php  
    2. trait ezcReflectionReturnInfo {  
    3. function getReturnType() {  
    4. }  
    5. function getReturnDescription() {  
    6. }  
    7. }class ezcReflectionMethod extends ReflectionMethod {  
    8. use ezcReflectionReturnInfo;  
    9. /* ... */  
    10. }  
    11. class ezcReflectionFunction extends ReflectionFunction {  
    12. use ezcReflectionReturnInfo;  
    13. /* ... */  
    14. }  
    15. ?>  

     

    2)优先级
    基类中的成员函数将被Traits中的函数覆盖,当前类中的成员函数将覆盖Traits中的函数。

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

     

    3)多Traits

    多个Traits可以添加到一个class的声明中,多个Traits之间用","隔开。

    1. <?php  
    2. trait Hello {  
    3.     public function sayHello() {  
    4.         echo 'Hello ';  
    5.     }  
    6. }  
    7.   
    8. trait World {  
    9.     public function sayWorld() {  
    10.         echo 'World';  
    11.     }  
    12. }  
    13.   
    14. class MyHelloWorld {  
    15.     use Hello, World;  
    16. }  
    17.   
    18. $o = new MyHelloWorld();  
    19. $o->sayHello();  
    20. $o->sayWorld();  
    21. ?>  

    输出结果:

    Hello World

    4)多Traits冲突
    如果添加到同一个class的两个Traits中有相同的函数名称,且没有明确的进行处理,将产生一个错误。
    为了解决同一个类中两个Tratis中的同名函数冲突,需要用insteadof操作符来选择正确的函数。
    因为方法的唯一性和排他性,'as'操作符允许用在冲突函数之后以解决内部冲突的问题。

    1. <?php  
    2. trait A {  
    3. public function smallTalk() {  
    4. echo 'a';  
    5. }  
    6. public function bigTalk() {  
    7. echo 'A';  
    8. }  
    9. }  
    10.   
    11. trait B {  
    12. public function smallTalk() {  
    13. echo 'b';  
    14. }  
    15. public function bigTalk() {  
    16. echo 'B';  
    17. }  
    18. }  
    19.   
    20. class Talker {  
    21. use A, B {  
    22. B::smallTalk insteadof A;  
    23. A::bigTalk insteadof B;  
    24. }  
    25. }  
    26.   
    27. class Aliased_Talker {  
    28. use A, B {  
    29. B::smallTalk insteadof A;  
    30. A::bigTalk insteadof B;  
    31. B::bigTalk as talk;  
    32. }  
    33. }  
    34. ?>  

    上面的例子中,Talker使用Traits A 和B,因此两者中相同的函数名称存在冲突。
    alker中定义了smallTalk取自Traits B,bigTalk取自Traits A。
    Aliased_Talker中通过使用as操作符来确保Traits B中的bigTalk通过别名talk来实现。
    5)改变函数访问权限
    我们可以使用as语法来改变Traits中函数的访问权限属性。

    1. <?php  
    2. trait HelloWorld {  
    3. public function sayHello() {  
    4. echo 'Hello World!';  
    5. }  
    6. }  
    7.   
    8. // Change visibility of sayHello,改变sayHello的访问权限。  
    9. class MyClass1 {  
    10. use HelloWorld { sayHello as protected; }  
    11. }  
    12.   
    13. // Alias method with changed visibility  
    14. // sayHello visibility not changed,设置别名myPrivateHello。  
    15. class MyClass2 {  
    16. use HelloWorld { sayHello as private myPrivateHello; }  
    17. }  
    18. ?>  

     

    6)Traits组成新Traits
    就像许多类一样可以在类中使用Traits,Traits中一样可以使用Traits。可以在一个Traits中定义一个或者多个Traits,这些Traits 可以作为部分或者全部成员被定义在其他Traits中。

    1. <?php  
    2. trait Hello {  
    3. public function sayHello() {  
    4. echo 'Hello ';  
    5. }  
    6. }  
    7.   
    8. trait World {  
    9. public function sayWorld() {  
    10. echo 'World!';  
    11. }  
    12. }  
    13.   
    14. trait HelloWorld {  
    15. use Hello, World;  
    16. }  
    17.   
    18. class MyHelloWorld {  
    19. use HelloWorld;  
    20. }  
    21.   
    22. $o = new MyHelloWorld();  
    23. $o->sayHello();  
    24. $o->sayWorld();  
    25. ?>  

    以上例程会输出:

    1. Hello World!  

    7)抽象Trait成员
    为了在类中强制实现某些方法,可以在Traits中使用抽象方法。
    例如:

    1. <?php  
    2. trait Hello {  
    3.     public function sayHelloWorld() {  
    4.         echo 'Hello '.$this->getWorld();  
    5.     }  
    6.     abstract public function getWorld();  
    7. }  
    8.   
    9. class MyHelloWorld {  
    10.     private $world;  
    11.     use Hello;  
    12.     public function __construct($world) {  
    13.         $this->world = $world;  
    14.     }  
    15.     public function getWorld() {  
    16.         return $this->world;  
    17.     }  
    18. }  
    19.   
    20. /** 
    21.  * 这里用到了5.4新功能 类实例化解引用操作 
    22.  * (new class())->method(); 
    23.  */  
    24. (new MyHelloWorld('Arvin'))->sayHelloWorld();  
    25. ?>  
    26.   
    27. 该实例输出:  
    28. Hello Arvin  

     

    8)静态Trait成员

    在Traits中不能定义static 静态变量,但是可以定义在Tratis的函数中。Tratis中同样可以定义静态函数。

    1. <?php  
    2. trait Counter {  
    3.     public function inc() {  
    4.         static $c = 0;//静态变量  
    5.         $c += 1;  
    6.         echo "$c ";  
    7.     }  
    8.     /** 
    9.      * 静态方法 
    10.      */  
    11.     public static function doSomething() {  
    12.         echo 'Doing something';  
    13.     }  
    14. }  
    15.   
    16. class C1 {  
    17.     use Counter;  
    18. }  
    19.   
    20. (new C1())->inc(); // echo 1  
    21. C1::doSomething();  
    22. ?>  
    23. 输出为:  
    24. 1  
    25. 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
  • 相关阅读:
    Ribbon 负载均衡搭建
    MicroService 微服务提供者搭建
    转 Spring boot 集成 Dubbo 快速搭建
    (转)Spring boot 集成Kafka
    转 Spring boot 集成ActiveMQ(包含双向队列实现)
    (转)异步实现服务器推送消息(聊天功能示例)
    (转)Spring boot 配置异步处理执行器
    (转)SSH框架快速搭建(Maven)
    (转)Hbase 操作工具类
    (转)Java AES加密算法工具类
  • 原文地址:https://www.cnblogs.com/cmderq/p/9130897.html
Copyright © 2011-2022 走看看