<dl id="opymh"></dl>

<div id="opymh"></div>
      <div id="opymh"><tr id="opymh"></tr></div>

        <em id="opymh"><ins id="opymh"><mark id="opymh"></mark></ins></em><sup id="opymh"><menu id="opymh"></menu></sup>

        <em id="opymh"></em>

        <em id="opymh"><ol id="opymh"></ol></em>

              頻道欄目
              首頁 > 程序開發 > Web開發 > php > 正文
              PHP5.4以后新增的trait功能使用介紹
              2018-07-19 11:23:02         來源:qq_29735775的博客  
              收藏   我要投稿

              trait是php5.4以后新增加的一個功能,可以將多個類中,共用的一些屬性和方法提取出來做來公共trait類,就像是裝配汽車的配件,如果你的類中要用到這些配件,就直接用use導入就可以了,相當于把trait中的代碼復制到當前類中.

              因為trait不是類,所以不能有靜態成員,類常量,當然也不可能被實例化。

              其實一個類中的代碼,可以分為二大部分:一是我們自己寫的代碼,暫且叫私有代碼吧,還有一部分就是公共代碼了,之前主要是由父類代碼組成。現在你的類中的公共代碼又多一個新成員:trait類代碼。

              如果說:繼承可以縱向擴展一個類,那么trait就是橫向擴展一個類功能

              下面以實例進行演示:
              //1創建一個trait類Test1

              hello1(); //訪問trait類Test1中的hello1()
              echo '

              '; echo $obj->name; //訪問ttrait類Test1中的$name屬性 echo '
              '; echo $obj->hello2(); //訪問ttrait類Test1中的hello2()

              trait可以互相嵌套,一個trait類中可以用use導入另一個trait類,理解成代碼復制就可以了.

              例如本例中,在Test2中要用到Test1中的代碼,我們只要改動二個地方就可以了。

              一是在Test2中用use Test1;導入Test1中的代碼,

              二是在Demo1類中的,去掉對Test1的引用,只保留對Test2的引用,想想這是為什么?給大家當作一個思考題吧~

              修改后的代碼如下:

              //1創建一個trait類Test1

              name;
              }
              }
              //3.創建Demo1類
              class Demo1
              {
              // use Test1, Test2;
              use Test2;
              }
              //進行測試
              $obj = new Demo1;
              echo $obj->hello1(); //訪問trait類Test1中的hello1()
              echo '

              '; echo $obj->name; //訪問ttrait類Test1中的$name屬性 echo '


              '; echo $obj->hello2(); //訪問ttrait類Test1中的hello2()

              剛才說過,類中導入的公共代碼,除了trait方法集,還可以有父類,如果在子類中訪問父類中的成員,大家應該很熟悉了,現在一個類除了可以從父類繼承成員,還可以從trait類中繼承,那么有一個問題就不可避免了,如果父類和trait類中的成員命名沖突怎么辦?說人話,就是重名了怎么辦?下面我們以方法重名來演示一下處理方案。

              再創建一個類Demo,做為Demo1類的父類。

              //3.創建父類Demo

              class Demo
              {
              //在父類中創建一個與Test2重名的方法hello2()
              public function hello2()
              {
              return '父類Demo::hello2()';
              }
              }

              代碼如下:

              //1創建一個trait類Test1
              trait Test1
              {
              public $name = 'PHP中文網'; //trait類中可以用屬性
              public function hello1() //trait類中主要成員是方法
              {
              return 'Test1::hello1()';
              }
              }
              //2.創建triat類Test2
              trait Test2
              {
              use Test1;
              function hello2()
              {
              //在Test2中訪問Test1中的屬性name,注意語法與普通類是一樣的
              return 'Test2::hello2()'.$this->name;
              }
              }
              //3.創建父類Demo
              class Demo
              {
              public function hello2()
              {
              return '父類Demo::hello2()';
              }
              }
              //4.創建Demo1類
              class Demo1 extends Demo
              {
              // use Test1, Test2;
              use Test2;
              }
              //進行測試
              $obj = new Demo1;
              echo $obj->hello1(); //訪問trait類Test1中的hello1()
              echo '

              '; echo $obj->name; //訪問ttrait類Test1中的$name屬性 echo '


              '; echo $obj->hello2(); //訪問ttrait類Test1中的hello2()

              再次訪問,會發現,結果與之前完全一樣沒有任何變化,父類Demo中的hello2方法好像隱身了,壓根不存在一樣的。事實上,父類Demo中的hello2方法當然是存在的,只是被trat類Test2中的同名方法hello2覆蓋掉了,原因就是:trait類中的同名方法,訪問優先級大于父類的同名方法。

              如果我們就想訪問父類中的hello2方法,怎么辦呢?只有一個辦法,要么父類方法改名,要么Test2中的方法改名,我們把Test2中的hello2方法改成hello3,再次訪問,就可以看到父類的執行結果了。

              那么,我們再進一點想一下,如果在子類也有一個hello2方法呢?那么結果會是什么樣?

              我們來試一下,在Demo1類中添加如下代碼:

              //4.創建Demo1類
              class Demo1 extends Demo
              {
              // use Test1, Test2;
              use Test2;
              //在Demo1類中創建與Test2和父類Demo中同名的方法hello2()
              public function hello2()
              {
              return 'Demo1::hello()';
              }
              }

              瀏覽器再次方法,果然不出所料,子類Demo1中的hello2方法的執行結果覆蓋掉了Test2中的同名方法

              現在我們總結一下在同一個類中,同名方法的優先級:子類>Trait類>父類,與就是說,誰離調用者越近,誰的優先級就越高。

              下面我們再討論最后一個問題:如果trait類中方法重名了,怎么辦?如果是trait類中被所有類共享的方法集,重名的可能性是非常大的。

              下面我們修改一下代碼,刪除一些用不到代碼:

              //1創建一個trait類Test1
              trait Test1
              {
              public function hello()
              {
              return 'Test1::hello()';
              }
              }
              //2.創建triat類Test2
              trait Test2
              {
              function hello()
              {
              return 'Test2::hello()';
              }
              }
              //3.創建類Demo
              class Demo
              {
              use Test1, Test2{
              //用Test1中的hello()方法替代Test2中的同名方法
              Test1::hello insteadof Test2;
              //Test2中的hello()方法用別名訪問
              Test2::hello as test2Hello;
              } //這里千萬不要加分號 ;
              }
              
              //進行測試
              $obj = new Demo;
              echo $obj->hello(); //訪問Test1中的hello()
              echo '

              '; echo $obj->test2Hello();//別名訪問Test2中的hello()

              點擊復制鏈接 與好友分享!回本站首頁
              上一篇:PHP 身份證驗證功能代碼實現
              下一篇:在php里判斷手機號的代碼教程
              相關文章
              圖文推薦
              點擊排行

              關于我們 | 聯系我們 | 廣告服務 | 投資合作 | 版權申明 | 在線幫助 | 網站地圖 | 作品發布 | Vip技術培訓 | 舉報中心

              版權所有: 紅黑聯盟--致力于做實用的IT技術學習網站

              极速飞艇好假
              <dl id="opymh"></dl>

              <div id="opymh"></div>
                  <div id="opymh"><tr id="opymh"></tr></div>

                    <em id="opymh"><ins id="opymh"><mark id="opymh"></mark></ins></em><sup id="opymh"><menu id="opymh"></menu></sup>

                    <em id="opymh"></em>

                    <em id="opymh"><ol id="opymh"></ol></em>

                          <dl id="opymh"></dl>

                          <div id="opymh"></div>
                              <div id="opymh"><tr id="opymh"></tr></div>

                                <em id="opymh"><ins id="opymh"><mark id="opymh"></mark></ins></em><sup id="opymh"><menu id="opymh"></menu></sup>

                                <em id="opymh"></em>

                                <em id="opymh"><ol id="opymh"></ol></em>