<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ## traits 詳解 >[info] traits 知識并不是ThinkPHP教學的內容,但軟刪除的模型中應用了這項新技術~~ * * * * * > 我們知道,PHP面向對象是單繼承的,無法同時從兩個或以上的基類繼承屬性或方法。從PHP 5.4起, Traits(構件類)技術出現,使多繼承成為現實! * * * * * >[warning] 注意: 1. Traits類的聲明使用trait關鍵詞, 2. 類中使用use關鍵字聲明要組合的Traits類名稱; 3. Traits類不能直接實例化 * * * * * #### 實例演示: ~~~ <?php //創建trait類:Test1 trait Test1 { public function demo1() { return 'Test1::demo1()<br />'; } } //創建基類(父類):Father class Father { public function demo1() { return 'Father::demo1<br />'; } } //創建自定義類:MyClass 是Father的派生類(子類) class MyClass extends Father { use Test1; public function demo1() { return 'MyClass::demo1<br />'; } } //創建自定義MyClass的對象 $obj = new MyClass; //訪問$obj對象的demo1()方法 echo $obj -> demo1(); ~~~ > 1. 現在我們已經有了三個類:trait類,基類Father和派生類MyClass; > 2. 每個類中都有一個demo1( )方法; > 3. $obj是MyClass實例化的對象,那么:`echo $obj -> demo1();`將會調用哪個類的demo1()方法呢? * 讓我們運行一下吧: ~~~ MyClass::demo1 ~~~ > 可見,實際調用的是MyClass類的demo1()方法。這符合繼承的原理,因為子復寫了父類同名方法。 > <font color="red">下面我們把MyClass類中的demo1()方法刪除</font> * 修改后的代碼如下: ~~~ <?php //創建trait類:Test1 trait Test1 { public function demo1() { return 'Test1::demo1()<br />'; } } //創建基類(父類):Father class Father { public function demo1() { return 'Father::demo1<br />'; } } //創建自定義類:MyClass 是Father的派生類(子類) class MyClass extends Father { use Test1; } //創建自定義MyClass的對象 $obj = new MyClass; //訪問$obj對象的demo1()方法 echo $obj -> demo1(); ~~~ > 按照之前知識,如果調用的方法,在子類中沒有定義,則調用父類中同名方法,真的是這樣的嗎?讓我們測試一下吧: * 這時運行結果如下: ~~~ Test1::demo1() ~~~ > 覺得奇怪嗎?為什么不是父類的輸出結果:`Father::demo1()`,而是:`Test1::demo1()`呢。這因為子類中,除了要繼承Father類,還要繼承trait類Test1,顯然,子類MyClass中的`use Test1` 的繼承優先級要高于原父類的Father,于是產生覆蓋效果。 > <span style="color:red;">trait類同名方法覆蓋了基類Father中的同名方法。</span> #### 那么我們屏蔽掉:`use Test1;`,會調用父類同名方法嗎? * 再次修改一下代碼: ~~~ <?php //創建trait類:Test1 trait Test1 { public function demo1() { return 'Test1::demo1()<br />'; } } //創建基類(父類):Father class Father { public function demo1() { return 'Father::demo1<br />'; } } //創建自定義類:MyClass 是Father的派生類(子類) class MyClass extends Father { } //創建自定義MyClass的對象 $obj = new MyClass; //訪問$obj對象的demo1()方法 echo $obj -> demo1(); ~~~ > 現在子類MyClass中已經沒有use Test1;trait類Test已失效。 * 現在執行結果,如不出意料,應該是父類的demo1()方法的結果: ~~~ Father::demo1 ~~~ >[info] 果然如此,調用是父類中的demo1()方法。 * * * * * >[info] 現在我們思考另一個問題:如果有二個trait類,都是一個demo1方法,怎么辦?這是個很常見的問題,必須得到解決。 * 我們再次修改代碼,增加一個trait類Test2: ~~~ <?php //創建trait類:Test1 trait Test1 { public function demo1() { return 'Test1::demo1()<br />'; } } //創建trait類:Test2 trait Test2 { public function demo1() { return 'Test2::demo1()<br />'; } } //創建基類(父類):Father class Father { public function demo1() { return 'Father::demo1<br />'; } } //創建自定義類:MyClass 是Father的派生類(子類) class MyClass extends Father { use Test1,Test2; } //創建自定義MyClass的對象 $obj = new MyClass; //訪問$obj對象的demo1()方法 echo $obj -> demo1(); ~~~ > 現在有二個trait類Test1和Test2,這二個類中都有demo1方法,`echo $obj -> demo1();`好糾結,應該調用哪個呢? * 運行結果,肯定是錯誤的: ~~~ //大意是trait中的方法demo1 沒有提交運行,因為有重復的定義 Fatal error: Trait method demo1 has not been applied, because there are collisions with other trait methods on MyClass in /Users/zhupeter/Documents/web/test/index.php on line 31 ~~~ >[info] 解決方案有二種: 1. 設置沖突時,調用哪一個方法:`insteadof;` 2. 給可能沖突的方法起一個別名:`as;` ~~~ <?php //創建trait類:Test1 trait Test1 { public function demo1() { return 'Test1::demo1()<br />'; } } //創建trait類:Test2 trait Test2 { public function demo1() { return 'Test2::demo1()<br />'; } } //創建基類(父類):Father class Father { public function demo1() { return 'Father::demo1<br />'; } } //創建自定義類:MyClass 是Father的派生類(子類) class MyClass extends Father { use Test1,Test2{ //方案1:Test2的demo1方法與Test1的demo1方法沖突時,調用Test2的demo1方法; Test2::demo1 insteadof Test1; //Test2中的demo1方法可以使用方法別名td2調用 Test2::demo1 as td2; } } //創建自定義MyClass的對象 $obj = new MyClass; //訪問$obj對象的demo1()方法 //根據use中設置的調用規則,現在調用的應該是Test2類中的demo1方法 echo $obj -> demo1(); //第二套解決方案:給可能沖突的該當起別名來規避 //現在調用的仍然是Test2類中的demo1方法 echo $obj -> td2(); ~~~ * 結過分析,運行結果也是可以預見的: ~~~ Test2::demo1() Test2::demo1() ~~~ #### 這種特殊類的聲明,學會了嗎?親們~~ * * * * * #### 總結: >[danger] ThinkPHP5中的軟刪除等很多特殊操作,都是通過trait類來實現的,簡而言之,traits 提供了實現多繼承的一種機制。一定要掌握這種新技術。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看