PHP之Trait详解

你的名字 2022-09-03 15:13 231阅读 0赞

php从以前到现在一直都是单继承的语言,无法同时从两个基类中继承属性和方法,为了解决这个问题,php出了Trait这个特性

用法:通过在类中使用use 关键字,声明要组合的Trait名称,具体的Trait的声明使用Trait关键词,Trait不能实例化

如下代码实例:

  1. <?php
  2. trait Dog{
  3. public $name="dog";
  4. public function bark(){
  5. echo "This is dog";
  6. }
  7. }
  8. class Animal{
  9. public function eat(){
  10. echo "This is animal eat";
  11. }
  12. }
  13. class Cat extends Animal{
  14. use Dog;
  15. public function drive(){
  16. echo "This is cat drive";
  17. }
  18. }
  19. $cat = new Cat();
  20. $cat->drive();
  21. echo "<br/>";
  22. $cat->eat();
  23. echo "<br/>";
  24. $cat->bark();
  25. ?>

将会如下输出
在这里插入图片描述

再测试Trait、基类和本类对同名属性或方法的处理,如下代码

  1. <?php
  2. trait Dog{
  3. public $name="dog";
  4. public function drive(){
  5. echo "This is dog drive";
  6. }
  7. public function eat(){
  8. echo "This is dog eat";
  9. }
  10. }
  11. class Animal{
  12. public function drive(){
  13. echo "This is animal drive";
  14. }
  15. public function eat(){
  16. echo "This is animal eat";
  17. }
  18. }
  19. class Cat extends Animal{
  20. use Dog;
  21. public function drive(){
  22. echo "This is cat drive";
  23. }
  24. }
  25. $cat = new Cat();
  26. $cat->drive();
  27. echo "<br/>";
  28. $cat->eat();
  29. ?>

如下显示
在这里插入图片描述
所以:Trait中的方法会覆盖 基类中的同名方法,而本类会覆盖Trait中同名方法
注意点:当trait定义了属性后,类就不能定义同样名称的属性,否则会产生 fatal error,除非是设置成相同可见度、相同默认值。不过在php7之前,即使这样设置,还是会产生E_STRICT 的提醒

一个类可以组合多个Trait,通过逗号相隔,如下

use trait1,trait2

当不同的trait中,却有着同名的方法或属性,会产生冲突,可以使用insteadof或 as进行解决,insteadof 是进行替代,而as是给它取别名
如下实例:

  1. <?php
  2. trait trait1{
  3. public function eat(){
  4. echo "This is trait1 eat";
  5. }
  6. public function drive(){
  7. echo "This is trait1 drive";
  8. }
  9. }
  10. trait trait2{
  11. public function eat(){
  12. echo "This is trait2 eat";
  13. }
  14. public function drive(){
  15. echo "This is trait2 drive";
  16. }
  17. }
  18. class cat{
  19. use trait1,trait2{
  20. trait1::eat insteadof trait2;
  21. trait1::drive insteadof trait2;
  22. }
  23. }
  24. class dog{
  25. use trait1,trait2{
  26. trait1::eat insteadof trait2;
  27. trait1::drive insteadof trait2;
  28. trait2::eat as eaten;
  29. trait2::drive as driven;
  30. }
  31. }
  32. $cat = new cat();
  33. $cat->eat();
  34. echo "<br/>";
  35. $cat->drive();
  36. echo "<br/>";
  37. echo "<br/>";
  38. echo "<br/>";
  39. $dog = new dog();
  40. $dog->eat();
  41. echo "<br/>";
  42. $dog->drive();
  43. echo "<br/>";
  44. $dog->eaten();
  45. echo "<br/>";
  46. $dog->driven();
  47. ?>

输出如下
在这里插入图片描述

as 还可以修改方法的访问控制

  1. <?php
  2. trait Animal{
  3. public function eat(){
  4. echo "This is Animal eat";
  5. }
  6. }
  7. class Dog{
  8. use Animal{
  9. eat as protected;
  10. }
  11. }
  12. class Cat{
  13. use Animal{
  14. Animal::eat as private eaten;
  15. }
  16. }
  17. $dog = new Dog();
  18. $dog->eat();//报错,因为已经把eat改成了保护
  19. $cat = new Cat();
  20. $cat->eat();//正常运行,不会修改原先的访问控制
  21. $cat->eaten();//报错,已经改成了私有的访问控制
  22. ?>

Trait也可以互相组合,还可以使用抽象方法,静态属性,静态方法等,实例如下

  1. <?php
  2. trait Cat{
  3. public function eat(){
  4. echo "This is Cat eat";
  5. }
  6. }
  7. trait Dog{
  8. use Cat;
  9. public function drive(){
  10. echo "This is Dog drive";
  11. }
  12. abstract public function getName();
  13. public function test(){
  14. static $num=0;
  15. $num++;
  16. echo $num;
  17. }
  18. public static function say(){
  19. echo "This is Dog say";
  20. }
  21. }
  22. class animal{
  23. use Dog;
  24. public function getName(){
  25. echo "This is animal name";
  26. }
  27. }
  28. $animal = new animal();
  29. $animal->getName();
  30. echo "<br/>";
  31. $animal->eat();
  32. echo "<br/>";
  33. $animal->drive();
  34. echo "<br/>";
  35. $animal::say();
  36. echo "<br/>";
  37. $animal->test();
  38. echo "<br/>";
  39. $animal->test();
  40. ?>

输出如下
在这里插入图片描述

作者:奋斗live
链接:https://www.jianshu.com/p/fc053b2d7fd1
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

发表评论

表情:
评论列表 (有 0 条评论,231人围观)

还没有评论,来说两句吧...

相关阅读

    相关 phpTraits 详解

    PHP是单继承的语言,在PHP 5.4 Traits出现之前,PHP的类无法同时从两个基类继承属性或方法。php的Traits和Go语言的组合功能有点类似, 通过在类中使用u

    相关 PHPTrait 特性

    Trait是在PHP5.4中加入的,它既不是接口也不是类。主要是为了解决单继承语言的限制。是PHP多重继承的一种解决方案。例如,需要同时继承两个 Abstract Class,

    相关 PHPTrait详解

    > php从以前到现在一直都是单继承的语言,无法同时从两个基类中继承属性和方法,为了解决这个问题,php出了Trait这个特性 用法:通过在类中使用use 关键字,声明要组合

    相关 PHP Trait 使用指南(life)

    通过更好地组织代码和代码复用来最大程度地减少代码重复是面向对象编程的重要目标。但是在 PHP 中,由于使用单一继承模型的局限性,有些时候要做到这些可能会比较困难。您可能有一些要

    相关 PHPTrait详解

    > php从以前到现在一直都是单继承的语言,无法同时从两个基类中继承属性和方法,为了解决这个问题,php出了Trait这个特性 用法:通过在类中使用use 关键字,声明要组合