PHP 代碼複用的方式

什麼是 Trait?php

自 PHP 5.4.0 起,PHP 實現了一種代碼複用的方法,稱爲 Trait。
  • Trait 是爲了單繼承語言而準備的一種代碼複用機制。
  • Trait 和 Class 類似,它爲傳統的繼承增長了水平的特性的組合,多個無關的 Class 之間不須要互相繼承
  • Trait 使得無關的 Class 能夠使用相同的屬性和方法。
簡單使用
<?php

trait Test
{
    public function echoHello()
    {
        echo 'Hello Trait';
    }
}

class Base
{
    public function index()
    {
        echo 'index';
    }
}

class One extends Base
{
    use Test;
}

class Two extends Base
{
    use Test;
}

$one = new One();
$two = new Two();

echo $one->echoHello();
echo $one->index();
echo $two->echoHello();

結果輸出 Hello Trait index Hello Traitcode

從基類繼承的成員會被 Trait 插入的成員所覆蓋。優先順序是來自當前類的成員覆蓋了 Trait 的方法,而 Trait 則覆蓋了被繼承的方法。
<?php

trait Test
{
    public function echoHello()
    {
        echo 'Hello Trait';
    }
}

class Base
{
    use Test;

    public function echoHello()
    {
        echo 'Hello Base';
    }
}

class One extends Base
{
    use Test;

    public function echoHello()
    {
        echo 'Hello One';
    }
}

class Two extends Base
{
    use Test;
}

$one = new One();
$two = new Two();
$base = new Base();

echo $one->echoHello();

echo $two->echoHello();

echo $base->echoHello();

結果輸出 Hello One Hello Trait Hello Base繼承

  • class one 示例覆蓋基類和 Trait Test,說明當前類的方法優先級高於他們。
  • class Two 示例覆蓋基類,Trait 的有優先級高於繼承的基類。
  • class Base 示例覆蓋 Trait Test,說明當前類的方法優先級高於 Trait。
經過逗號分隔,在 use 聲明列出多個 trait,能夠都插入到一個類中。
<?php

trait Test
{
    public function echoHello()
    {
        echo 'Hello ';
    }
}

trait TestTwo
{
    public function echoWord()
    {
        echo 'word !';
    }
}


class One
{
    use Test,TestTwo;
}

$one  = new One();

echo $one->echoHello();
echo $one->echoWord();

結果輸出 Hello word !get

若是兩個 Trait 都插入了一個同名的方法,若是沒有明確解決衝突將會產生一個致命錯誤。
<?php

trait Test
{
    public function echoHello()
    {
        echo 'Hello Test';
    }

    public function echoWord()
    {
        echo 'word Test';
    }
}

trait TestTwo
{
    public function echoHello()
    {
        echo 'Hello TestTwo ';
    }

    public function echoWord()
    {
        echo 'word TestTwo';
    }
}

class One
{
    use Test, TestTwo {
        Test::echoHello as echoTest;
        Test::echoWord insteadof TestTwo;
        TestTwo::echoHello insteadof Test;
    }
}

$one = new One();

echo $one->echoTest();
echo $one->echoWord();
echo $one->echoHello();

輸出結果:Hello Test word Test Hello TestTwoit

  • 使用 as 做爲別名,即 Test::echoHello as echoTest; 輸出 Trait Test 中的 echoHello.
  • 使用 insteadof 操做符用來排除掉其餘 Trait,即 Test::echoWord insteadof TestTwo; 輸出的是 word Test,使用 Trait Test 中的 echoWord
修改 方法的控制權限
<?php

trait Test
{
    public function echoHello()
    {
        echo 'Hello';
    }

    public function echoWord()
    {
        echo 'word';
    }
}

trait TestTwo
{
    public function echoHello()
    {
        echo 'Hello TestTwo ';
    }

    public function echoWord()
    {
        echo 'word TestTwo';
    }
}

class One
{
    use Test {
        echoHello as private;
    }
}

class Two
{
    use Test {
        echoHello as private echoTwo;
    }
}

$one = new One();
$two = new Two();

echo $two->echoHello();
  • 輸出結果 Hello
  • class one 中使用 asechoHello 設爲私有,則經過 class one 不能訪問 echoHello
  • class two 中使用 as 先將其從新命名,而後將新命名方法設置爲私有,原 Trait 中的方法能夠正常訪問。

Trait 中還能夠像類同樣定義屬性。就是很好用的啦!io

轉載地址 PHP 代碼複用的方式function

相關文章
相關標籤/搜索