国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【modernPHP專題(5)】類多繼承的替代方案Traits

imtianx / 589人閱讀

摘要:概述是新進入的特性,其目的就是解決的類不能多繼承的問題。可以理解為一組能被不同的類都能調用到的方法集合。只需要在類中使用關鍵詞引入即可,可引入多個,用隔開。為了解決多個在同一個類中的命名沖突,需要使用操作符來明確指定使用沖突方法中的哪一個。

概述

traits是PHP5.4新進入的特性,其目的就是解決PHP的類不能多繼承的問題。Traits不是類!不能被實例化。可以理解為一組能被不同的類都能調用到的方法集合。只需要在類中使用關鍵詞use引入即可,可引入多個Traits,用","隔開。

簡單使用
trait myTrait{

    public $traitPublic = "public";
    protected $traitProtected = "protected";

    function traitMethod1()
    {
        echo __METHOD__,PHP_EOL;
    }

    function traitMethod2()
    {
        echo __METHOD__,PHP_EOL;
    }
}

class myClass{
    use myTrait;
}

$obj = new myClass();
$obj->traitMethod1();
$obj->traitMethod2();

// ↓↓ 只能調用public的屬性和方法; protected以及private只供在traits內部自己調用;
echo $obj->traitPublic;
優先級問題

Trait會覆蓋繼承的方法,當前類會覆蓋Trait方法。即 繼承的方法 < Traits方法 < 當前類方法,

trait A{
    public $var1 = "test";

    public function test()
    {
        echo "A::test()";
    }

    public function test1()
    {
        echo "A::test1()";
    }
}

class B{
    public function test()
    {
        echo "B::test()";
    }

    public function test1()
    {
        echo "B::test1()";
    }
}

class C extends B{
    use A;

    public function test()
    {
        echo "c::test()";
    }
}

$c = new C();
$c->test(); //c::test() Traits方法 < 當前類方法
$c->test1(); //A::test1() 繼承的方法 < Traits方法
多個Trait沖突問題

如果兩個 trait 都插入了一個同名的方法,如果沒有明確解決沖突將會產生一個致命錯誤。

為了解決多個 trait 在同一個類中的命名沖突,需要使用 insteadof 操作符來明確指定使用沖突方法中的哪一個。

可用as操作符將其中一個沖突方法另起名;

trait A{
    public function test()
    {
        echo "A::test()";
    }
}

trait B{
    public function test()
    {
        echo "B::test()";
    }
}

class C{
    use A , B {
        B::test insteadof A; //明確B替代A
        B::test as t; //或者另起一個名字
    }
}

$c = new C();
$c->test(); //B::test()
$c->t(); //B::test()   可以用as另起名
as可用來修改方法訪問控制
trait  HelloWorld{
    public function sayHello()
    {
        echo "Hello World!";
    }
}

// 修改 sayHello 的訪問控制
class  A{
    use  HelloWorld {
        sayHello as protected;
    }
}

// 給方法一個改變了訪問控制的別名
// 原版 sayHello 的訪問控制則沒有發生變化
class  B{
    use  HelloWorld {
        sayHello as private myPrivateHello;
    }
}

$a = new A();
$a->sayHello(); //Fatal error: Call to protected method A::sayHello() from context ""; 改變了sayHello的訪問規則;

$b = new B();
$b->sayHello(); //Hello World!
Trait中使用Trait
trait Hello{
    public function sayHello()
    {
        echo "Hello ";
    }
}

trait World{
    public function sayWorld()
    {
        echo "World!";
    }
}

trait HelloWorld{
    use Hello , World;
}

class MyHelloWorld{
    use HelloWorld;
}

$o = new MyHelloWorld();
$o->sayHello();
$o->sayWorld(); // Hello World!
Trait中抽象成員

為了對使用的類施加強制要求,trait 支持抽象方法的使用。

trait Hello{
    public function sayHelloWorld()
    {
        echo "Hello" . $this->getWorld();
    }

    abstract public function getWorld();
}

class MyHelloWorld{
    private $world;
    use Hello;

    // 必須要實現trait里面的抽象方法,否則Fatal error: Class MyHelloWorld contains 1 abstract method and must therefore be declared abstract or implement the remaining methods
    public function getWorld()
    {
        return $this->world;
    }

    public function setWorld($val)
    {
        $this->world = $val;
    }
}

$obj = new MyHelloWorld();
echo $obj->setWorld();
Trait中靜態成員

Traits 可以被靜態成員靜態方法定義,不可以直接定義靜態變量,但靜態變量可被trait方法引用.

# 靜態屬性;
trait Counter {
    public function inc() {
        static $c = 0;
        $c = $c + 1;
        echo "$c
";
    }
}

class C1 {
    use Counter;
}

class C2 {
    use Counter;
}

$o = new C1();
$o->inc(); // echo 1
$o->inc(); // echo 2;

$p = new C2();
$p->inc(); // echo 1

# 靜態方法
trait StaticExample {
    public static function doSomething() {
        echo "Doing something";
    }
}

class Example {
    use StaticExample;
}

Example::doSomething(); // Doing something
Trait中屬性
trait PropertiesTrait{
    public $x = 1;
}

class PropertiesExample{
    use PropertiesTrait;
}

$example = new PropertiesExample;
echo $example->x; // 1

如果 trait 定義了一個屬性,那類將不能定義同樣名稱的屬性,否則會產生一個錯誤。如果該屬性在類中的定義與在 trait 中的定義兼容(同樣的可見性和初始值)則錯誤的級別是 E_STRICT,否則是一個致命錯誤。

trait PropertiesTrait {
    public $same = true;
    public $different = false;
}

class PropertiesExample {
    use PropertiesTrait;
    public $same = true; // Strict Standards
    public $different = true; // 致命錯誤
}

參考鏈接:

http://www.php.net/manual/zh/...

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/31373.html

相關文章

  • modernPHP專題(4)】抽象類與接口

    摘要:抽象類支持抽象類和抽象方法。接口是一種特殊的抽象類,這種抽象類中只包含抽象方法和靜態常量。對抽象類的使用是通過關鍵字。抽象類中可以聲明各種類型成員變量,實現數據的封裝。一個類可以同時實現多個接口,但一個類只能繼承于一個抽象類。 抽象類 php5支持抽象類和抽象方法。類前加 abstract, 此類就成為抽象類,無法被實例化,此類天生就是用來被繼承的,給子類提供了一個類的模板;類方法前加...

    Keven 評論0 收藏0
  • modernPHP專題(2)】反射機制Reflection

    摘要:簡介是才有的新功能,它是用來導出或提取出關于類方法屬性參數等的詳細信息,包括注釋。 簡介 PHP Reflection API是PHP5才有的新功能,它是用來導出或提取出關于類、方法、屬性、參數等的詳細信息,包括注釋。 class Reflection { } interface Reflector { } class ReflectionException extends Exce...

    mrli2016 評論0 收藏0
  • modernPHP專題(9)】匿名類

    摘要:復制當前閉包對象,綁定指定的對象和類作用域。類作用域,可以是對象,也可以是實例名稱什么是匿名類先理解以下三個例子例閉包函數都是繼承類返回匿名函數返回匿名函數,也就是閉包函數,所有閉包函數都是繼承類輸出例將一個匿名函數綁定到一個類中。 類結構 Closure { /* 方法 */ // 用于禁止實例化的構造函數 __construct ( void ) ...

    ninefive 評論0 收藏0
  • modernPHP專題(3)】依賴注入與服務容器

    摘要:而依賴倒置原則的思想是,上層不應該依賴下層,應依賴接口。上面通過構造函數注入對象的方式,就是最簡單的依賴注入當然注入不僅可以通過構造函數注入,也可以通過屬性注入,上面你可以通過一個來動態為這個屬性賦值。 依賴倒置和控制反轉是一種編程思想,而依賴注入就是通過服務容器實現這種面向接口或者是面向抽象編程的思想 概念理解 依賴倒置原則 依賴倒置是一種軟件設計思想,在傳統軟件中,上層代碼依賴于下...

    terro 評論0 收藏0
  • modernPHP專題(1)】php7常用特性整理

    摘要:它使得在生產環境中啟用斷言為零成本,并且提供當斷言失敗時拋出特定異常的能力。錯誤和異常改變了大多數錯誤的報告方式。不同于傳統的錯誤報告機制,現在大多數錯誤被作為異常拋出。 PHP7性能 7最大的亮點,應該就是性能提高了兩倍,某些測試環境下甚至提高到三到五倍,具體可以了解以下鏈接: PHP7 VS HHVM (WordPress) HHVM vs PHP 7 – The Competit...

    Render 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<