摘要:概述是新進(jìn)入的特性,其目的就是解決的類不能多繼承的問(wèn)題。可以理解為一組能被不同的類都能調(diào)用到的方法集合。只需要在類中使用關(guān)鍵詞引入即可,可引入多個(gè),用隔開(kāi)。為了解決多個(gè)在同一個(gè)類中的命名沖突,需要使用操作符來(lái)明確指定使用沖突方法中的哪一個(gè)。
概述
traits是PHP5.4新進(jìn)入的特性,其目的就是解決PHP的類不能多繼承的問(wèn)題。Traits不是類!不能被實(shí)例化。可以理解為一組能被不同的類都能調(diào)用到的方法集合。只需要在類中使用關(guān)鍵詞use引入即可,可引入多個(gè)Traits,用","隔開(kāi)。
簡(jiǎn)單使用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(); // ↓↓ 只能調(diào)用public的屬性和方法; protected以及private只供在traits內(nèi)部自己調(diào)用; echo $obj->traitPublic;優(yōu)先級(jí)問(wèn)題
Trait會(huì)覆蓋繼承的方法,當(dāng)前類會(huì)覆蓋Trait方法。即 繼承的方法 < Traits方法 < 當(dāng)前類方法,
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方法 < 當(dāng)前類方法 $c->test1(); //A::test1() 繼承的方法 < Traits方法多個(gè)Trait沖突問(wèn)題
如果兩個(gè) trait 都插入了一個(gè)同名的方法,如果沒(méi)有明確解決沖突將會(huì)產(chǎn)生一個(gè)致命錯(cuò)誤。
為了解決多個(gè) trait 在同一個(gè)類中的命名沖突,需要使用 insteadof 操作符來(lái)明確指定使用沖突方法中的哪一個(gè)。
可用as操作符將其中一個(gè)沖突方法另起名;
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; //或者另起一個(gè)名字 } } $c = new C(); $c->test(); //B::test() $c->t(); //B::test() 可以用as另起名as可用來(lái)修改方法訪問(wèn)控制
trait HelloWorld{ public function sayHello() { echo "Hello World!"; } } // 修改 sayHello 的訪問(wèn)控制 class A{ use HelloWorld { sayHello as protected; } } // 給方法一個(gè)改變了訪問(wèn)控制的別名 // 原版 sayHello 的訪問(wèn)控制則沒(méi)有發(fā)生變化 class B{ use HelloWorld { sayHello as private myPrivateHello; } } $a = new A(); $a->sayHello(); //Fatal error: Call to protected method A::sayHello() from context ""; 改變了sayHello的訪問(wèn)規(guī)則; $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中抽象成員
為了對(duì)使用的類施加強(qiáng)制要求,trait 支持抽象方法的使用。
trait Hello{ public function sayHelloWorld() { echo "Hello" . $this->getWorld(); } abstract public function getWorld(); } class MyHelloWorld{ private $world; use Hello; // 必須要實(shí)現(xiàn)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中靜態(tài)成員
Traits 可以被靜態(tài)成員靜態(tài)方法定義,不可以直接定義靜態(tài)變量,但靜態(tài)變量可被trait方法引用.
# 靜態(tài)屬性; 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 # 靜態(tài)方法 trait StaticExample { public static function doSomething() { echo "Doing something"; } } class Example { use StaticExample; } Example::doSomething(); // Doing somethingTrait中屬性
trait PropertiesTrait{ public $x = 1; } class PropertiesExample{ use PropertiesTrait; } $example = new PropertiesExample; echo $example->x; // 1
如果 trait 定義了一個(gè)屬性,那類將不能定義同樣名稱的屬性,否則會(huì)產(chǎn)生一個(gè)錯(cuò)誤。如果該屬性在類中的定義與在 trait 中的定義兼容(同樣的可見(jiàn)性和初始值)則錯(cuò)誤的級(jí)別是 E_STRICT,否則是一個(gè)致命錯(cuò)誤。
trait PropertiesTrait { public $same = true; public $different = false; } class PropertiesExample { use PropertiesTrait; public $same = true; // Strict Standards public $different = true; // 致命錯(cuò)誤 }
參考鏈接:
http://www.php.net/manual/zh/...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/31373.html
摘要:抽象類支持抽象類和抽象方法。接口是一種特殊的抽象類,這種抽象類中只包含抽象方法和靜態(tài)常量。對(duì)抽象類的使用是通過(guò)關(guān)鍵字。抽象類中可以聲明各種類型成員變量,實(shí)現(xiàn)數(shù)據(jù)的封裝。一個(gè)類可以同時(shí)實(shí)現(xiàn)多個(gè)接口,但一個(gè)類只能繼承于一個(gè)抽象類。 抽象類 php5支持抽象類和抽象方法。類前加 abstract, 此類就成為抽象類,無(wú)法被實(shí)例化,此類天生就是用來(lái)被繼承的,給子類提供了一個(gè)類的模板;類方法前加...
摘要:簡(jiǎn)介是才有的新功能,它是用來(lái)導(dǎo)出或提取出關(guān)于類方法屬性參數(shù)等的詳細(xì)信息,包括注釋。 簡(jiǎn)介 PHP Reflection API是PHP5才有的新功能,它是用來(lái)導(dǎo)出或提取出關(guān)于類、方法、屬性、參數(shù)等的詳細(xì)信息,包括注釋。 class Reflection { } interface Reflector { } class ReflectionException extends Exce...
摘要:復(fù)制當(dāng)前閉包對(duì)象,綁定指定的對(duì)象和類作用域。類作用域,可以是對(duì)象,也可以是實(shí)例名稱什么是匿名類先理解以下三個(gè)例子例閉包函數(shù)都是繼承類返回匿名函數(shù)返回匿名函數(shù),也就是閉包函數(shù),所有閉包函數(shù)都是繼承類輸出例將一個(gè)匿名函數(shù)綁定到一個(gè)類中。 類結(jié)構(gòu) Closure { /* 方法 */ // 用于禁止實(shí)例化的構(gòu)造函數(shù) __construct ( void ) ...
摘要:而依賴倒置原則的思想是,上層不應(yīng)該依賴下層,應(yīng)依賴接口。上面通過(guò)構(gòu)造函數(shù)注入對(duì)象的方式,就是最簡(jiǎn)單的依賴注入當(dāng)然注入不僅可以通過(guò)構(gòu)造函數(shù)注入,也可以通過(guò)屬性注入,上面你可以通過(guò)一個(gè)來(lái)動(dòng)態(tài)為這個(gè)屬性賦值。 依賴倒置和控制反轉(zhuǎn)是一種編程思想,而依賴注入就是通過(guò)服務(wù)容器實(shí)現(xiàn)這種面向接口或者是面向抽象編程的思想 概念理解 依賴倒置原則 依賴倒置是一種軟件設(shè)計(jì)思想,在傳統(tǒng)軟件中,上層代碼依賴于下...
摘要:它使得在生產(chǎn)環(huán)境中啟用斷言為零成本,并且提供當(dāng)斷言失敗時(shí)拋出特定異常的能力。錯(cuò)誤和異常改變了大多數(shù)錯(cuò)誤的報(bào)告方式。不同于傳統(tǒng)的錯(cuò)誤報(bào)告機(jī)制,現(xiàn)在大多數(shù)錯(cuò)誤被作為異常拋出。 PHP7性能 7最大的亮點(diǎn),應(yīng)該就是性能提高了兩倍,某些測(cè)試環(huán)境下甚至提高到三到五倍,具體可以了解以下鏈接: PHP7 VS HHVM (WordPress) HHVM vs PHP 7 – The Competit...
閱讀 3968·2021-09-23 11:32
閱讀 2647·2021-09-06 15:01
閱讀 1713·2021-08-18 10:24
閱讀 3607·2019-12-27 11:44
閱讀 3679·2019-08-30 15:52
閱讀 2586·2019-08-30 11:11
閱讀 818·2019-08-29 17:27
閱讀 671·2019-08-29 16:22