亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 語言 > PHP > 正文

PHP使用traits實現代碼復用的例子

2024-09-04 11:43:47
字體:
來源:轉載
供稿:網友

PHP 5.4中的traits,是新引入的特性,用于實現代碼重用的方法,下面我們就一起來看看PHP使用traits實現代碼復用的例子,希望文章可以幫助到各位.

PHP5.4后新增traits實現代碼復用機制,Trait和類相似,但不能被實例化,無需繼承,只需要在類中使用關鍵詞use引入即可,可引入多個Traits,用','隔開.

(1)Trait簡單使用

  1. <?php 
  2. trait A { 
  3.     public $var1 = 'test1'
  4.     public function test1() { 
  5.         echo 'trait A::test1()'
  6.     } 
  7.  
  8. trait B { 
  9.     public $var2 = 'test2'
  10.     public function test2() { 
  11.         echo 'trait B::test2()'
  12.     } 
  13.  
  14. class C { 
  15.     use A,B; 
  16.  
  17. $c = new C(); 
  18. echo $c->var1; //test1 
  19. $c->test2(); //trait B::test2() 
  20. ?> 

(2)優先級問題

Trait會覆蓋繼承的方法,當前類會覆蓋Trait方法.

  1. trait A { 
  2.     public $var1 = 'test'
  3.     public function test() { 
  4.         echo 'A::test()'
  5.     } 
  6.     public function test1() { 
  7.         echo 'A::test1()'
  8.     } 
  9.  
  10. class B { 
  11.     public function test() { 
  12.         echo 'B::test()'
  13.     } 
  14.     public function test1() { 
  15.         echo 'B::test1()'
  16.     } 
  17. class C extends B{ 
  18.     use A; 
  19.     public function test() { 
  20.         echo 'c::test()'
  21.     } //開源軟件:Vevb.com 
  22.  
  23. $c = new C(); 
  24. $c->test(); //c::test() 
  25. $c->test1(); //A::test1() 

(3)多個Trait沖突問題

如果沒有解決沖突,會產生致命錯誤,可用insteadof來明確使用沖突中哪一個方法,可用as操作符將其中一個沖突方法另起名.

  1. trait A { 
  2.     public function test() { 
  3.         echo 'A::test()'
  4.     } 
  5.  
  6. trait B { 
  7.     public function test() { 
  8.         echo 'B::test()'
  9.     } 
  10.  
  11. class C { 
  12.     use A,B { 
  13.         B::test insteadof A; 
  14.         B::test as t; 
  15.     } 
  16.  
  17. $c = new C(); 
  18. $c->test(); //B::test() 
  19. $c->t(); //B::test()   可以用as另起名 

(4)as可用來修改方法訪問控制

  1. trait  HelloWorld  { 
  2.     public function  sayHello () { 
  3.         echo  'Hello World!' ; 
  4.     } 
  5.  
  6. // 修改 sayHello 的訪問控制 
  7. class  A  { 
  8.     use  HelloWorld  {  sayHello  as protected; } 
  9.  
  10. // 給方法一個改變了訪問控制的別名 
  11. // 原版 sayHello 的訪問控制則沒有發生變化 
  12. class  B  { 
  13.     use  HelloWorld  {  sayHello  as private  myPrivateHello ; } 
  14.  
  15. $b = new A(); 
  16. $b->sayHello(); //Fatal error: Call to protected method A::sayHello() from context '' 

(5)Trait中使用Trait

  1. trait A { 
  2.     public function test1() { 
  3.         echo 'test1'
  4.     } 
  5.  
  6. trait B { 
  7.     public function test2() { 
  8.         echo 'test2'
  9.     } 
  10.  
  11. trait C { 
  12.     use A,B; 
  13.  
  14. class D { 
  15.     use C; 
  16.  
  17. $d = new D(); 
  18. $d->test2();  //test2 

(6)Trait支持抽象方法、支持靜態方法、不可以直接定義靜態變量,但靜態變量可被trait方法引用.

  1. trait A { 
  2.     public function test1() { 
  3.         static $a = 0; 
  4.         $a++; 
  5.         echo $a
  6.     } 
  7.  
  8.     abstract public function test2(); //可定義抽象方法 
  9.  
  10. class B { 
  11.     use A; 
  12.     public function test2() { 
  13.  
  14.     } 
  15.  
  16. $b = new B(); 
  17. $b->test1(); //1 
  18. $b->test1(); //2 

(7)Trait可定義屬性,但類中不能定義同樣名稱屬性.

  1. trait A { 
  2.    public $test1
  3.  
  4. class B { 
  5.     use A; 
  6.     public $test2

接著看.

  1. <?php 
  2.     trait Drive { 
  3.         public $carName = 'trait'
  4.         public function driving() { 
  5.             echo "driving {$this->carName}\n"
  6.         } 
  7.     } 
  8.     class Person { 
  9.         public function eat() { 
  10.             echo "eat\n"
  11.         } 
  12.     } 
  13.     class Student extends Person { 
  14.         use Drive; 
  15.         public function study() { 
  16.             echo "study\n"
  17.         } 
  18.     } 
  19.     $student = new Student(); 
  20.     $student->study(); 
  21.     $student->eat(); 
  22.     $student->driving(); 
  23. //輸出結果如下: 
  24. study 
  25. eat 
  26. driving trait 

上面的例子中,Student類通過繼承Person,有了eat方法,通過組合Drive,有了driving方法和屬性carName.

如果Trait、基類和本類中都存在某個同名的屬性或者方法,最終會保留哪一個呢?通過下面的代碼測試一下:

  1. <?php  
  2.     trait Drive { 
  3.         public function hello() { 
  4.             echo "hello drive\n"
  5.         } 
  6.         public function driving() { 
  7.             echo "driving from drive\n"
  8.         } 
  9.     } 
  10.     class Person { 
  11.         public function hello() { 
  12.             echo "hello person\n"
  13.         } 
  14.         public function driving() { 
  15.             echo "driving from person\n"
  16.         } 
  17.     } 
  18.     class Student extends Person { 
  19.         use Drive; 
  20.         public function hello() { 
  21.             echo "hello student\n"
  22.         } 
  23.     } 
  24.     $student = new Student(); 
  25.     $student->hello(); 
  26.     $student->driving(); 
  27. //輸出結果如下: 
  28. hello student 
  29. driving from drive 

因此得出結論:當方法或屬性同名時,當前類中的方法會覆蓋 trait的 方法,而 trait 的方法又覆蓋了基類中的方法.

如果要組合多個Trait,通過逗號分隔 Trait名稱:use Trait1, Trait2;

如果多個Trait中包含同名方法或者屬性時,會怎樣呢?答案是當組合的多個Trait包含同名屬性或者方法時,需要明確聲明解決沖突,否則會產生一個致命錯誤.

  1. <?php 
  2. trait Trait1 { 
  3.     public function hello() { 
  4.         echo "Trait1::hello\n"
  5.     } 
  6.     public function hi() { 
  7.         echo "Trait1::hi\n"
  8.     } 
  9. trait Trait2 { 
  10.     public function hello() { 
  11.         echo "Trait2::hello\n"
  12.     } 
  13.     public function hi() { 
  14.         echo "Trait2::hi\n"
  15.     } 
  16. class Class1 { 
  17.     use Trait1, Trait2; 
  18. //輸出結果如下: 
  19. PHP Fatal error:  Trait method hello has not been applied, because there are collisions with other trait methods on Class1 in ~/php54/trait_3.php on line 20 

使用insteadof和as操作符來解決沖突,insteadof是使用某個方法替代另一個,而as是給方法取一個別名,具體用法請看代碼:

  1. <?php 
  2. trait Trait1 { 
  3.     public function hello() { 
  4.         echo "Trait1::hello\n"
  5.     } 
  6.     public function hi() { 
  7.         echo "Trait1::hi\n"
  8.     } 
  9. trait Trait2 { 
  10.     public function hello() { 
  11.         echo "Trait2::hello\n"
  12.     } 
  13.     public function hi() { 
  14.         echo "Trait2::hi\n"
  15.     } 
  16. class Class1 { 
  17.     use Trait1, Trait2 { 
  18.         Trait2::hello insteadof Trait1; 
  19.         Trait1::hi insteadof Trait2; 
  20.     } 
  21. class Class2 { 
  22.     use Trait1, Trait2 { 
  23.         Trait2::hello insteadof Trait1; 
  24.         Trait1::hi insteadof Trait2; 
  25.         Trait2::hi as hei; 
  26.         Trait1::hello as hehe; 
  27.     } 
  28. $Obj1 = new Class1(); 
  29. $Obj1->hello(); 
  30. $Obj1->hi(); 
  31. echo "\n"
  32. $Obj2 = new Class2(); 
  33. $Obj2->hello(); 
  34. $Obj2->hi(); 
  35. $Obj2->hei(); 
  36. $Obj2->hehe(); 
  37. //輸出結果如下: 
  38. Trait2::hello 
  39. Trait1::hi 
  40. Trait2::hello 
  41. Trait1::hi 
  42. Trait2::hi 
  43. Trait1::hello 

as關鍵詞還有另外一個用途,那就是修改方法的訪問控制:

  1. <?php 
  2.     trait Hello { 
  3.         public function hello() { 
  4.             echo "hello,trait\n"
  5.         } 
  6.     } 
  7.     class Class1 { 
  8.         use Hello { 
  9.             hello as protected
  10.         } 
  11.     } 
  12.     class Class2 { 
  13.         use Hello { 
  14.             Hello::hello as private hi; 
  15.         } 
  16.     } 
  17.     $Obj1 = new Class1(); 
  18.     $Obj1->hello(); # 報致命錯誤,因為hello方法被修改成受保護的 
  19.     $Obj2 = new Class2(); 
  20.     $Obj2->hello(); # 原來的hello方法仍然是公共的 
  21.     $Obj2->hi();  # 報致命錯誤,因為別名hi方法被修改成私有的 
  22. ?> 

Trait 也能組合Trait,Trait中支持抽象方法、靜態屬性及靜態方法,測試代碼如下:

  1. <?php 
  2. trait Hello { 
  3.     public function sayHello() { 
  4.         echo "Hello\n"
  5.     } 
  6. trait World { 
  7.     use Hello; 
  8.     public function sayWorld() { 
  9.         echo "World\n"
  10.     } 
  11.     abstract public function getWorld(); 
  12.     public function inc() { 
  13.         static $c = 0; 
  14.         $c = $c + 1; 
  15.         echo "$c\n"
  16.     } 
  17.     public static function doSomething() { 
  18.         echo "Doing something\n"
  19.     } 
  20. class HelloWorld { 
  21.     use World; 
  22.     public function getWorld() { 
  23.         return 'get World'
  24.     } 
  25. $Obj = new HelloWorld(); 
  26. $Obj->sayHello(); 
  27. $Obj->sayWorld(); 
  28. echo $Obj->getWorld() . "\n"
  29. HelloWorld::doSomething(); 
  30. $Obj->inc(); 
  31. $Obj->inc(); 
  32. //輸出結果如下: 
  33. Hello 
  34. World 
  35. get World 
  36. Doing something 
  37. ?>

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩精品福利网站| 成人福利在线观看| 精品国产一区二区三区久久| 中文字幕精品在线| 欧美国产精品人人做人人爱| 国产欧美日韩专区发布| 福利二区91精品bt7086| 欧美亚洲另类视频| 欧美在线视频观看免费网站| 久久精品99久久久香蕉| 欧美激情性做爰免费视频| 在线看日韩欧美| 国产综合久久久久| 久久免费精品日本久久中文字幕| 国产精品久久久久免费a∨大胸| 国产丝袜一区视频在线观看| 亚洲人成在线观看| 亚洲一区二区自拍| 欧美在线视频播放| 国产日韩精品入口| 1769国内精品视频在线播放| 欧美国产第二页| 亚洲天堂开心观看| 青青在线视频一区二区三区| 国产视频久久久| 国产日韩中文在线| 91免费在线视频网站| 久久精品国产精品亚洲| 日韩精品视频在线播放| 日韩美女免费视频| 亚洲一区二区中文字幕| 精品国产乱码久久久久酒店| 欧美午夜性色大片在线观看| 国产精品久久久久久av福利| 亚洲爱爱爱爱爱| 九九精品视频在线| 精品久久久久久久久久久久久| 亚洲午夜未删减在线观看| 日韩美女视频免费在线观看| 欧美人交a欧美精品| 欧美午夜视频在线观看| 国产精品露脸av在线| 中文字幕不卡在线视频极品| 国产成人福利视频| 91老司机在线| 精品视频在线播放免| 国产成人精品一区| 欧美午夜精品久久久久久浪潮| 国产精品亚洲网站| 日韩女优人人人人射在线视频| 黄网站色欧美视频| 精品国产网站地址| 精品一区精品二区| 久久精品中文字幕免费mv| 色噜噜亚洲精品中文字幕| 成人写真福利网| 欧美在线亚洲在线| 川上优av一区二区线观看| 亚洲男人的天堂网站| 欧美成人免费全部观看天天性色| 国产精品久久精品| 欧美精品日韩www.p站| 不卡av电影在线观看| 日韩精品免费综合视频在线播放| 久久久久久高潮国产精品视| 国产伦精品免费视频| 久久综合电影一区| 国产成人av在线播放| 欧美激情视频在线观看| 中文字幕在线看视频国产欧美在线看完整| 亚洲娇小xxxx欧美娇小| 久久福利视频导航| 91久久国产精品| 大胆人体色综合| 亚洲最大成人在线| 中文字幕一区二区精品| 亚洲人成亚洲人成在线观看| 亚洲欧洲视频在线| 欧美日韩国产一区中文午夜| 在线观看精品国产视频| 成人乱人伦精品视频在线观看| 成人福利网站在线观看| 久久综合88中文色鬼| 欧美黑人xxxⅹ高潮交| 亚洲国产一区二区三区四区| 色婷婷成人综合| 日韩在线视频免费观看高清中文| 国产日韩欧美夫妻视频在线观看| 日本午夜人人精品| 尤物精品国产第一福利三区| 欧美人与性动交a欧美精品| 欧美日产国产成人免费图片| 欧美日韩亚洲国产一区| 91免费高清视频| 91网站在线免费观看| 91夜夜揉人人捏人人添红杏| 1769国内精品视频在线播放| 米奇精品一区二区三区在线观看| 欧美激情视频在线观看| 亚洲国产小视频| 色综合色综合网色综合| 国产精品国产三级国产专播精品人| 97精品在线观看| 久久久噜久噜久久综合| 亚洲欧美三级在线| 中文字幕亚洲一区二区三区五十路| 中文字幕精品影院| 欧美一级大片在线观看| 日本国产欧美一区二区三区| 午夜精品福利电影| 久久免费观看视频| 亚洲精品中文字幕av| 国内精品模特av私拍在线观看| 91国产视频在线| 国产午夜精品免费一区二区三区| 精品无人区太爽高潮在线播放| 国产最新精品视频| 国产视频999| 自拍偷拍亚洲欧美| 97香蕉超级碰碰久久免费软件| 日本精品va在线观看| 中文字幕一精品亚洲无线一区| 欧美黄色三级网站| 亚洲国内精品在线| 国产精品露脸av在线| 国产啪精品视频| 亚洲天堂精品在线| 欧美黄色成人网| 欧美日韩一区二区三区在线免费观看| 日韩在线视频二区| 在线播放日韩欧美| www.日韩.com| 欧美怡春院一区二区三区| 91超碰中文字幕久久精品| 欧美在线视频免费播放| 亚洲性日韩精品一区二区| 精品人伦一区二区三区蜜桃网站| 国产精品aaaa| 国产久一一精品| 色综合色综合久久综合频道88| 欧美电影免费看| 欧美亚洲国产另类| 亚洲国产精品久久久| 国产精品激情av电影在线观看| 俺也去精品视频在线观看| 国产精品盗摄久久久| 国产午夜精品麻豆| 视频在线观看99| 激情成人中文字幕| 色综合天天综合网国产成人网| 精品视频在线播放免| 国产日韩欧美视频| 91系列在线观看| 黑人巨大精品欧美一区二区| 久久久久九九九九| 亚洲欧美日韩国产精品| 国外色69视频在线观看| 亚洲成人动漫在线播放| 成人精品视频99在线观看免费| 亚洲国产97在线精品一区| 欧美性xxxxx极品| 欧美日韩加勒比精品一区| 伊人久久久久久久久久| 欧美激情在线观看视频|