PHP之Trait详解(多继承)

本文参考:  http://php.net/language.oop5.traits 

一、什么是trait

    从PHP 5.4.0 开始 PHP 实现了一种新的代码复用方式 trait。

二、trait解决了什么问题

    trait 的出现是为了解决类似PHP的单继承语言而准备的一种代码复用机制,让开发人员能够在不能层次结构内独立的类中复用 method。

三、跟其它语言相比,trait 有什么 好处

    Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。

四、该如何使用trait

  • 示例1,如何使用 trait
     

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    <?php

    trait ezcReflectionReturnInfo {

        function getReturnType() { /*1*/ }

        function getReturnDescription() { /*2*/ }

    }

    class ezcReflectionMethod extends ReflectionMethod {

        use ezcReflectionReturnInfo;

        /* ... */

    }

    class ezcReflectionFunction extends ReflectionFunction {

        use ezcReflectionReturnInfo;

        /* ... */

    }

    ?>

  • 示例2 ,trait 与 class 方法优先级问题
    trait 方法会覆盖基类中的方法,当前类中的方法会覆盖 trait 方法
     

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    <?php

    class Base {

        public function sayHello() {

            echo 'Hello ';

        }

    }

    trait SayWorld {

        public function sayHello() {

            parent::sayHello();

            echo "World!\r\n";

        }

    }

    class MyHelloWorld extends Base {

        use SayWorld;

    }

    class MyNewHelloWorld extends Base{

        use SayWorld;

        public function sayHello(){

        echo "Hello sunshine!\r\n";

        }

    }

    $o new MyHelloWorld();

    $o->sayHello();

    $b new MyNewHelloWorld();

    $b->sayHello();

    ?>

    上面的代码会输出:

  • 示例3  同时使用多个 trait  通过逗号分隔,在 use 声明列出多个 trait,可以都插入到一个类中。
     

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    <?php

    trait Hello {

        public function sayHello() {

            echo 'Hello ';

        }

    }

    trait World {

        public function sayWorld() {

            echo 'World';

        }

    }

    class MyHelloWorld {

        use Hello, World;

        public function sayExclamationMark() {

            echo '!';

        }

    }

    $o new MyHelloWorld();

    $o->sayHello();

    $o->sayWorld();

    $o->sayExclamationMark();

    ?>

    上面的代码会输出:

  • 示例4 冲突的解决 

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

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

     

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    <?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;

        }

    }

    ?>

  • 示例5  使用trait来组成trait   正如 class 能够使用 trait 一样,其它 trait 也能够使用 trait。在 trait 定义时通过使用一个或多个 trait,能够组合其它 trait 中的部分或全部成员。
     

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    <?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();

    ?>

    上面例子会输出:

除了这些特性,trait 还包括 抽象成员  静态成员  静态方法  属性 等特性,可以参考    http://php.net/language.oop5.traits  

猜你喜欢

转载自my.oschina.net/u/232595/blog/2088018
今日推荐