国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 網站 > 建站經驗 > 正文

詳解PHP中的Traits

2024-04-25 20:40:21
字體:
來源:轉載
供稿:網友

PHP是單繼承的語言,在PHP 5.4 Traits出現之前,PHP的類無法同時從兩個基類繼承屬性或方法。php的Traits和Go語言的組合功能類似,通過在類中使用use關鍵字聲明要組合的Trait名稱,而具體某個Trait的聲明使用trait關鍵詞,Trait不能直接實例化。具體用法請看下面的代碼:

<?php

trait Drive {

public $carName = 'trait';

public function driving() {

echo "driving {$this->carName}/n";

}

}

class Person {

public function eat() {

echo "eat/n";

}

}

class Student extends Person {

use Drive;

public function study() {

echo "study/n";

}

}

$student = new Student();

$student->study();

$student->eat();

$student->driving();

輸出結果如下:

study

eat

driving trait

上面的例子中,Student類通過繼承Person,有了eat方法,通過組合Drive,有了driving方法和屬性carName。

如果Trait、基類和本類中都存在某個同名的屬性或者方法,最終會保留哪一個呢?通過下面的代碼測試一下:

<?php

trait Drive {

public function hello() {

echo "hello drive/n";

}

public function driving() {

echo "driving from drive/n";

}

}

class Person {

public function hello() {

echo "hello person/n";

}

public function driving() {

echo "driving from person/n";

}

}

class Student extends Person {

use Drive;

public function hello() {

echo "hello student/n";

}

}

$student = new Student();

$student->hello();

$student->driving();

輸出結果如下:

hello student

driving from drive

因此得出結論:當方法或屬性同名時,當前類中的方法會覆蓋 trait的 方法,而 trait 的方法又覆蓋了基類中的方法。

如果要組合多個Trait,通過逗號分隔 Trait名稱:

use Trait1, Trait2;

如果多個Trait中包含同名方法或者屬性時,會怎樣呢?答案是當組合的多個Trait包含同名屬性或者方法時,需要明確聲明解決沖突,否則會產生一個致命錯誤。

<?php

trait Trait1 {

public function hello() {

echo "Trait1::hello/n";

}

public function hi() {

echo "Trait1::hi/n";

}

}

trait Trait2 {

public function hello() {

echo "Trait2::hello/n";

}

public function hi() {

echo "Trait2::hi/n";

}

}

class Class1 {

use Trait1, Trait2;

}

輸出結果如下:

PHP Fatal error: Trait method hello has not been applied, because there are collisions with other trait methods on Class1 in ~/php54/trait_3.php on line 20

使用insteadof和as操作符來解決沖突,insteadof是使用某個方法替代另一個,而as是給方法取一個別名,具體用法請看代碼:

<?php

trait Trait1 {

public function hello() {

echo "Trait1::hello/n";

}

public function hi() {

echo "Trait1::hi/n";

}

}

trait Trait2 {

public function hello() {

echo "Trait2::hello/n";

}

public function hi() {

echo "Trait2::hi/n";

}

}

class Class1 {

use Trait1, Trait2 {

Trait2::hello insteadof Trait1;

Trait1::hi insteadof Trait2;

}

}

class Class2 {

use Trait1, Trait2 {

Trait2::hello insteadof Trait1;

Trait1::hi insteadof Trait2;

Trait2::hi as hei;

Trait1::hello as hehe;

}

}

$Obj1 = new Class1();

$Obj1->hello();

$Obj1->hi();

echo "/n";

$Obj2 = new Class2();

$Obj2->hello();

$Obj2->hi();

$Obj2->hei();

$Obj2->hehe();

輸出結果如下:

Trait2::hello

Trait1::hi

Trait2::hello

Trait1::hi

Trait2::hi

Trait1::hello

as關鍵詞還有另外一個用途,那就是修改方法的訪問控制:

<?php

trait Hello {

public function hello() {

echo "hello,trait/n";

}

}

class Class1 {

use Hello {

hello as protected;

}

}

class Class2 {

use Hello {

Hello::hello as private hi;

}

}

$Obj1 = new Class1();

$Obj1->hello(); # 報致命錯誤,因為hello方法被修改成受保護的

$Obj2 = new Class2();

$Obj2->hello(); # 原來的hello方法仍然是公共的

$Obj2->hi(); # 報致命錯誤,因為別名hi方法被修改成私有的

Trait 也能組合Trait,Trait中支持抽象方法、靜態屬性及靜態方法,測試代碼如下:

<?php

trait Hello {

public function sayHello() {

echo "Hello/n";

}

}

trait World {

use Hello;

public function sayWorld() {

echo "World/n";

}

abstract public function getWorld();

public function inc() {

static $c = 0;

$c = $c + 1;

echo "$c/n";

}

public static function doSomething() {

echo "Doing something/n";

}

}

class HelloWorld {

use World;

public function getWorld() {

return 'get World';

}

}

$Obj = new HelloWorld();

$Obj->sayHello();

$Obj->sayWorld();

echo $Obj->getWorld() . "/n";

HelloWorld::doSomething();

$Obj->inc();

$Obj->inc();

輸出結果如下:

Hello

World

get World

Doing something

以上就是本文的全部內容,希望對大家的學習有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 徐水县| 石河子市| 济阳县| 临江市| 韩城市| 巴彦淖尔市| 枣庄市| 永川市| 扶风县| 靖远县| 德令哈市| 洛阳市| 辽阳县| 长岭县| 新密市| 马鞍山市| 麻栗坡县| 开阳县| 阿克陶县| 开原市| 淮阳县| 天津市| 溧阳市| 仁布县| 麻栗坡县| 溧阳市| 都安| 新乡市| 望城县| 五河县| 沧州市| 策勒县| 栾城县| 东辽县| 南安市| 大冶市| 旌德县| 全州县| 明光市| 土默特右旗| 瑞安市|