PHP 中的关于 trait 的简单
什么是 trait
看看 php 官网的介绍。
自 php 5.4.0 起,php 实现了一种代码复用的方法,称为 trait。
trait 是为类似 php 的单继承语言而准备的一种代码复用机制。trait 为了减少单继承语言的限制,使开发人员能够*地在不同层次结构内独立的类中复用 method。trait 和 class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 mixin 类相关典型问题。
trait 和 class 相似,但仅仅旨在用细粒度和一致的方式来组合功能。 无法通过 trait 自身来实例化。它为传统继承增加了水平特性的组合;也就是说,应用的几个 class 之间不需要继承。
例子1
手机和汽车都有 gps 功能,gps 是用来定位的功能的,因此功能应该是统一的。手机 和 汽车 除了 gps 功能外,基本没有什么相同之处,因此不能使用继承。而接口的话,我认为不同的类去实现接口时,接口的实现可能是不同的,但是 gps 的功能就是用来定位的。因此使用 trait ,而不使用 class 和 interface,这是我的理解,不知道是否正确。
gps.php 的定义:
1 <?php 2 3 trait gps { 4 public function gps() { 5 echo 'i can gps'; 6 } 7 }
使用 trait 定义了一个 gps 的 trait 用于复用,它的关键字是 trait 。然后在 car.php 和 mobile.php 中进行引用。
car.php 的定义:
1 class car { 2 use gps; 3 4 public function move() { 5 echo 'i can move'; 6 } 7 }
mobile.php 的定义:
1 <?php 2 3 class mobile { 4 use gps; 5 public function tel() { 6 echo 'i can tel'; 7 } 8 }
在 car.php 和 mobile.php 中,使用 use 关键字引入了 gps 的 trait ,这样在 car 和 mobile 中就可以调用 gps() 这个方法了。
test.php 进行测试:
1 <?php 2 3 require_once('gps.php'); 4 require_once('car.php'); 5 require_once('mobile.php'); 6 7 $car = new car(); 8 $mobile = new mobile(); 9 10 $car->gps(); 11 echo "\n"; 12 $mobile->gps();
输出结果如下:
1 i can gps 2 i can gps
例子2
在 car 中引入了另外一个国产的 gps 。
gpschina.php 定义如下:
1 <?php 2 3 trait gpschina { 4 5 public function gps() { 6 echo 'i can chinae gps'; 7 } 8 }
在 car 中引入,修改 car.php 的定义如下:
1 <?php 2 3 4 class car { 5 use gps, gpschina; 6 7 public function move() { 8 echo 'i can move'; 9 } 10 }
再次调用 test.php 进行测试,这时会报错,报错如下:
1 fatal error: trait method gps has not been applied, because there are collisions with other trait methods on car in car.php on line 4
因为在引入的 trait 中 gps 和 gpschina 各有一个 gps ,而直接使用 $car->gps() 时无法确定到底使用的是 gps 的 gps() 方法,还是使用的 gpschina 的 gps() 方法,因此报错了。这样的话,我们需要确定一个。修改 car.php 文件。
1 <?php 2 3 class car { 4 use gps, gpschina { 5 gpschina::gps insteadof gps; 6 } 7 8 public function move() { 9 echo 'i can move'; 10 } 11 }
这样就使用 gpschina::gps 的方法 替换掉了 gps 的方法了,在调用 test.php 进行查看。
1 i can chinae gps 2 i can gps
这样,对于 $car->gps() 后就调用了 gpschina 中的 gps() 方法了。
例子3
如果在 car 类中本身有一个 gps() 方法呢?修改 car 类。
1 <?php 2 3 class car { 4 use gps, gpschina { 5 gpschina::gps insteadof gps; 6 } 7 8 public function gps() { 9 echo 'car::gps'; 10 } 11 12 13 public function move() { 14 echo 'i can move'; 15 } 16 }
调用 test.php 查看结果:
1 car::gps 2 i can gps
可以看出,调用了 car 类本身的 gps() 方法。
如果在一个类中,继承自父类的方法、use 引入 trait 的方法 和 类自身的方法同名的话,优先调用 自身类的 方法,如果没有 自身类的方法 则调用 use 引入 trait 的方法,如果前两个都没有,那么就调用继承自父类的方法。
关于 trait 更多的用法,请参考:http://www.php.net/manual/zh/language.oop5.traits.php
上一篇: jsp中页面间传汉字参数转码的方法
下一篇: jsp页面中插入css样式的三种方法总结