trait PHP 实现了一种代码复用的方法(PHP5.4.0起)

栏目: PHP · 发布时间: 6年前

内容简介:trait PHP 实现了一种代码复用的方法(PHP5.4.0起)

PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait。

Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 method。Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。 Trait 和 Class 相似,但仅仅旨在用细粒度和一致的方式来组合功能。 无法通过 trait 自身来实例化。它为传统继承增加了水平特性的组合;也就是说,应用的几个 Class 之间不需要继承。

Example #1 Trait 示例

<?php trait ezcReflectionReturnInfo {     function getReturnType() { /*1*/ }     function getReturnDescription() { /*2*/ } }  class ezcReflectionMethod extends ReflectionMethod {     use ezcReflectionReturnInfo;     /* ... */ }  class ezcReflectionFunction extends ReflectionFunction {     use ezcReflectionReturnInfo;     /* ... */ } ?>
优先级  从基类继承的成员会被 trait 插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法。

Example #2 优先顺序示例

从基类继承的成员被插入的 SayWorld Trait 中的 MyHelloWorld 方法所覆盖。其行为 MyHelloWorld 类中定义的方法一致。优先顺序是当前类中的方法会覆盖 trait 方法,而 trait 方法又覆盖了基类中的方法。
<?php class Base {     public function sayHello() {         echo 'Hello ';     } }  trait SayWorld {     public function sayHello() {         parent::sayHello();         echo 'World!';     } }  class MyHelloWorld extends Base {     use SayWorld; }  $o = new MyHelloWorld(); $o->sayHello(); ?>  以上例程会输出: Hello World!

Example #3 另一个优先级顺序的例子

<?php trait HelloWorld {     public function sayHello() {         echo 'Hello World!';     } }  class TheWorldIsNotEnough {     use HelloWorld;     public function sayHello() {         echo 'Hello Universe!';     } }  $o = new TheWorldIsNotEnough(); $o->sayHello(); ?> 以上例程会输出:  Hello Universe!

多个 trait

通过逗号分隔,在 use 声明列出多个 trait,可以都插入到一个类中。  Example #4 多个 trait 的用法
<?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(); ?> 以上例程会输出:  Hello World! 冲突的解决

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

为了解决多个 trait 在同一个类中的命名冲突,需要使用 insteadof 操作符来明确指定使用冲突方法中的哪一个。  以上方式仅允许排除掉其它方法,as 操作符可以将其中一个冲突的方法以另一个名称来引入。  Example #5 冲突的解决  在本例中 Talker 使用了 trait A 和 B。由于 A 和 B 有冲突的方法,其定义了使用 trait B 中的 smallTalk 以及 trait A 中的 bigTalk。  Aliased_Talker 使用了 as 操作符来定义了 talk 来作为 B 的 bigTalk 的别名。
<?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;     } } ?>

修改方法的访问控制

<?php trait ezcReflectionReturnInfo {     function getReturnType() { /*1*/ }     function getReturnDescription() { /*2*/ } }  class ezcReflectionMethod extends ReflectionMethod {     use ezcReflectionReturnInfo;     /* ... */ }  class ezcReflectionFunction extends ReflectionFunction {     use ezcReflectionReturnInfo;     /* ... */ } ?>

0

<?php trait ezcReflectionReturnInfo {     function getReturnType() { /*1*/ }     function getReturnDescription() { /*2*/ } }  class ezcReflectionMethod extends ReflectionMethod {     use ezcReflectionReturnInfo;     /* ... */ }  class ezcReflectionFunction extends ReflectionFunction {     use ezcReflectionReturnInfo;     /* ... */ } ?>

1

从 trait 来组成 trait

<?php trait ezcReflectionReturnInfo {     function getReturnType() { /*1*/ }     function getReturnDescription() { /*2*/ } }  class ezcReflectionMethod extends ReflectionMethod {     use ezcReflectionReturnInfo;     /* ... */ }  class ezcReflectionFunction extends ReflectionFunction {     use ezcReflectionReturnInfo;     /* ... */ } ?>

2

<?php trait ezcReflectionReturnInfo {     function getReturnType() { /*1*/ }     function getReturnDescription() { /*2*/ } }  class ezcReflectionMethod extends ReflectionMethod {     use ezcReflectionReturnInfo;     /* ... */ }  class ezcReflectionFunction extends ReflectionFunction {     use ezcReflectionReturnInfo;     /* ... */ } ?>

3

Trait 的抽象成员

<?php trait ezcReflectionReturnInfo {     function getReturnType() { /*1*/ }     function getReturnDescription() { /*2*/ } }  class ezcReflectionMethod extends ReflectionMethod {     use ezcReflectionReturnInfo;     /* ... */ }  class ezcReflectionFunction extends ReflectionFunction {     use ezcReflectionReturnInfo;     /* ... */ } ?>

4

<?php trait ezcReflectionReturnInfo {     function getReturnType() { /*1*/ }     function getReturnDescription() { /*2*/ } }  class ezcReflectionMethod extends ReflectionMethod {     use ezcReflectionReturnInfo;     /* ... */ }  class ezcReflectionFunction extends ReflectionFunction {     use ezcReflectionReturnInfo;     /* ... */ } ?>

5

Trait 的静态成员

<?php trait ezcReflectionReturnInfo {     function getReturnType() { /*1*/ }     function getReturnDescription() { /*2*/ } }  class ezcReflectionMethod extends ReflectionMethod {     use ezcReflectionReturnInfo;     /* ... */ }  class ezcReflectionFunction extends ReflectionFunction {     use ezcReflectionReturnInfo;     /* ... */ } ?>

6

<? PHP

<?php trait ezcReflectionReturnInfo {     function getReturnType() { /*1*/ }     function getReturnDescription() { /*2*/ } }  class ezcReflectionMethod extends ReflectionMethod {     use ezcReflectionReturnInfo;     /* ... */ }  class ezcReflectionFunction extends ReflectionFunction {     use ezcReflectionReturnInfo;     /* ... */ } ?>

7

Example #10 静态方法

<?php trait ezcReflectionReturnInfo {     function getReturnType() { /*1*/ }     function getReturnDescription() { /*2*/ } }  class ezcReflectionMethod extends ReflectionMethod {     use ezcReflectionReturnInfo;     /* ... */ }  class ezcReflectionFunction extends ReflectionFunction {     use ezcReflectionReturnInfo;     /* ... */ } ?>

8

属性

<?php trait ezcReflectionReturnInfo {     function getReturnType() { /*1*/ }     function getReturnDescription() { /*2*/ } }  class ezcReflectionMethod extends ReflectionMethod {     use ezcReflectionReturnInfo;     /* ... */ }  class ezcReflectionFunction extends ReflectionFunction {     use ezcReflectionReturnInfo;     /* ... */ } ?>

9

优先级  从基类继承的成员会被 trait 插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法。

0

优先级  从基类继承的成员会被 trait 插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法。

1

Example #12 解决冲突

优先级  从基类继承的成员会被 trait 插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法。

2

单例

优先级  从基类继承的成员会被 trait 插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法。

3

来源:http://PHP.net/manual/zh/language.oop5.traits.PHP#language.oop5.traits.multiple


以上所述就是小编给大家介绍的《trait PHP 实现了一种代码复用的方法(PHP5.4.0起)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

程序员的呐喊

程序员的呐喊

[美]Steve Yegge / 徐旭铭 / 人民邮电出版社 / 2014-5-1 / 45.00元

《程序员的呐喊》的作者是业界知名的程序员—来自google的steve yegge,他写过很多颇富争议的文章,其中有不少就收录在这本书中。本书是他的精彩文章的合集。 《程序员的呐喊》涉及编程语言文化、代码方法学、google公司文化等热点话题。 对工厂业界的各种现象、技术、趋势等,作者都在本书中表达了自己独特犀利的观点。比如java真的是一门优秀的面向对象语言吗?重构真的那么美好吗?强......一起来看看 《程序员的呐喊》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

SHA 加密
SHA 加密

SHA 加密工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具