当前位置:Gxlcms > PHP教程 > Traits的用法

Traits的用法

时间:2021-07-01 10:21:17 帮助过:30人阅读

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

输出结果:

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

[php] view plaincopy

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

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

[php] view plaincopy

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

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

[php] view plaincopy

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

以上例程会输出:

[php] view plaincopy

  1. Hello World!

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

[php] view plaincopy

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

8)静态Trait成员

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

[php] view plaincopy

  1. trait Counter {
  2. public function inc() {
  3. static $c = 0;//静态变量
  4. $c += 1;
  5. echo "$c\n";
  6. }
  7. /**
  8. * 静态方法
  9. */
  10. public static function doSomething() {
  11. echo 'Doing something';
  12. }
  13. }
  14. class C1 {
  15. use Counter;
  16. }
  17. (new C1())->inc(); // echo 1
  18. C1::doSomething();
  19. ?>
  20. 输出为:
  21. 1
  22. Doing something

9) Traits 定义属性

如果在一个trait中定义了一个属性,则在引用该trait的类中不能定义同名的属性,如果该类中定义有和trait中已定义属性具有相同的名字和访问可见性,则是一个E_STRICT 提示,否则抛出语法错误。

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.//类新实例解引用操作,上文中有实例
本文旨在抛砖引玉,希望大家一起继续探究php5.4的新功能。^_^

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

人气教程排行