PHP中Trait的使用總結

reggie發表於2021-07-25

在Laravel中有好多 Trait的使用 感覺很有意思,由於php是單繼承的語言 無法同時繼承多個基類 但是可以使用 Trait 透過 Trait 可以很方便的實現程式碼的複用 類似繼承的效果。
注意:Trait 不能例項化

示例一

<?php
    trait MyTime{
        public $is_flag=123;
        protected $is_show=0;
        private $is_now=233;
        /**
         * 比如簡單的定義一個方法就是獲取當前時間一天後的
         */
        public function getTime(){
            return date('Y-m-d H:i:s',time()+3600*24);
        }
    }

    class HelpTime{
        //使用use關鍵字
        use MyTime;
        public function test(){
            echo $this->is_show."<br/>";
            echo $this->is_flag."<br/>";
            echo $this->is_now."<br/>";
            echo $this->getTime();
        }
    }

    $help=new HelpTime();
    $help->test();
>

以上輸出結果

123
0
233
2016-10-21 16:41:22

從上面結果可以看出如果使用use 關鍵字引入了一個trait 就會擁有它裡面的所有屬性和方法 包括私有 保護的 可以直接使用

如果需要引入多個Trait可以使用逗號隔開

use Trait1,Trait2;

示例二

<?php
    trait Human{
        public function eat(){
            echo "human eating";
        }
        public function sleep(){
            echo "human sleep";
        }
    }
    class Father{
        public function eat(){
            echo "father eating";
        }
        public function sleep(){
            echo "father sleep";
        }
    }
    class Son extends Father{
        use Human;
        public function eat(){
            echo "son eating";
        }
    }
    $son=new Son();
    $son->eat();
    $son->sleep();
>

輸出結果

son eating
human sleep

這個比較有意思了,當類中和基類和trait中存在同名的方法時候 當前類的方法會覆蓋基類覆蓋 Trait,而同時Trait中的會覆蓋基類 這種情況同樣適用於變數

示例三

<?php
    trait Test1{
        public function sayHello(){
            echo "test1 say hello";
        }
    }
    trait Test2{
        public function sayHello(){
            echo "test2 say hello";
        }
    }
    class Test3{
        use Test1,Test2;
    }
?>

當適用的多個Trait中含有重名的方法時候會報錯

Fatal error: Trait method sayHello has not been applied, because there are collisions with other trait methods on Test3

網上給出的解決辦法 適用 insteadofas 來解決 insteadof的作用是使用前面的方法代替後面另外一個方法 而as的作用是給方法取個別名

<?php
    trait Test1{
        public function sayHello(){
            echo "test1 say hello";
        }
    }
    trait Test2{
        public function sayHello(){
            echo "test2 say hello";
        }
    }
    class Test3{
        use Test1,Test2 {
            Test1::sayHello insteadof Test2;
            Test2::sayHello as test2sayhello;
        }
    }
    $test3=new Test3();
    $test3->sayHello();
    $test3->test2sayhello();
>

上面這個輸出結果

insteadof 那一句的作用就是使用Test1中的sayHello方法替代Test裡的sayHello方法
as 那一句的作用就是直接給Test2中的sayHello方法取了個別名叫 test2sayhello
test1 say hello
test2 say hello
本作品採用《CC 協議》,轉載必須註明作者和本文連結
微信公眾號:碼咚沒 ( ID: codingdongmei )

相關文章