首頁  >  文章  >  後端開發  >  PHP怎麼用trait或組合模式實作多繼承

PHP怎麼用trait或組合模式實作多繼承

醉折花枝作酒筹
醉折花枝作酒筹轉載
2021-07-21 16:17:542289瀏覽

PHP的類別繼承只能是單繼承,不能多繼承,如果想要實現多繼承的話,可以使用介面的方式來多繼承,但是如果不想使用介面的方式來實現多繼承的話,可以考慮使用trait來實現,當然也可以使用組合模式來實現。

PHP怎麼用trait或組合模式實作多繼承

trait是PHP 5.4新增的程式碼重複使用的方法,Trait 是為類似 PHP 的單繼承語言而準備的一種程式碼重複使用機制。 Trait 為了減少單繼承語言的限制,使開發人員能夠自由地在不同層次結構內獨立的類別中重複使用 method。 Trait 和 Class 組合的語意定義了一種減少複雜性的方式,避免傳統多繼承和 Mixin 類別相關典型問題。

Trait 和 Class 相似,但只是旨在以細粒度和一致的方式來組合功能。無法透過 trait 自身來實例化。它為傳統繼承增加了水平特性的組合;也就是說,應用的幾個 Class 之間不需要繼承。

通常在類別中使用  use關鍵字宣告要組合的Trait名稱,而具體某個Trait的宣告使用trait關鍵字,Trait不能直接實例化。

程式碼如下:

<?php
/**
 * Traits可以多重继承,可以看做是一种加强型的接口
 */
trait Hello
{
    public function sayHello()
    {
        echo &#39;Hello &#39;;
    }
    public function aaa()
    {
        echo &#39;AAA&#39;;
    }
}
trait World
{
    public function sayWorld()
    {
        echo &#39;World&#39;;
    }
}
class MyHelloWorld
{
    use Hello, World;
    public function sayExclamationMark()
    {
        echo &#39;!&#39;;
    }
    // 会覆盖掉Hello中的aaa方法
    public function aaa()
    {
        echo &#39;AAAAA&#39;;
    }
}
$obj = new MyHelloWorld();
$obj->sayHello();
$obj->sayWorld();
$obj->sayExclamationMark();
$obj->aaa();
// 输出:
// Hello World!AAAAA

程式碼中使用兩個trait來實現了多重繼承。

注意:兩個trait中不能出現同樣的方法,如果有同名的方法時,會產生致命錯誤。

注意:且MyHelloWorld類別中也有aaa方法,會覆寫Hello trait中的aaa方法。

上面的程式碼也可以透過組合的模式來實現,程式碼如下:

<?php
/**
 * 使用组合的方式也可以达到 1_12_trait.php 的效果
 */

class Hello2
{
    public function sayHello()
    {
        echo &#39;Hello &#39;;
    }

    public function aaa()
    {
        echo &#39;AAA&#39;;
    }
}

class World2
{
    public function sayWorld()
    {
        echo &#39;World&#39;;
    }

    public function aaa()
    {
        echo &#39;AAAA&#39;;
    }
}

class MyHelloWorld2
{
    public $obj = [];

    public function __construct()
    {
        $this->obj[&#39;Hello2&#39;] = new Hello2();
        $this->obj[&#39;World2&#39;] = new World2();
    }

    public function sayExclamationMark()
    {
        echo &#39;!&#39;;
    }

    public function __call($name, $arguments)
    {
        foreach ($this->obj as $value) {
            if (method_exists($value, $name)) {
               return $value->$name();
                // 也可以用 return call_user_func([$value, $name]);
            }
        }

        if (!method_exists($this->obj[&#39;Hello2&#39;], $name) && !method_exists($this->obj[&#39;World2&#39;], $name)) {
            echo "\r\n不存在此方法";
        }

        return true;
    }

    // 会覆盖其他类的aaa方法
    public function aaa()
    {
        echo &#39;AAAAA&#39;;
    }
}

$obj = new MyHelloWorld2();
$obj->sayHello();
$obj->sayWorld();
$obj->saywhat();
$obj->aaa();
$obj->sayExclamationMark();

// 输出:
// Hello World!AAAAA

顯而易見,透過trait來實現的話程式碼量少得多且可讀性也要高得多。

推薦學習:php影片教學

以上是PHP怎麼用trait或組合模式實作多繼承的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除