物件導向(六)Trait特性

2021-09-14 08:43:30 字數 3510 閱讀 9785

自 php 5.4.0 起,php 實現了一種**復用的方法,稱為 trait。

1、類中的一般的特性trait都可以實現。但是要混入類中,而不是代替類

2、trait是為了減少單繼承語言的限制,例如需要同時繼承兩個抽象類,這是php語言不支援的功能,trait就是為了解決這個問題

在繼承類鏈中隔離了子類繼承父類的某些特性,相當於要用父類特性的時候,如果有trait在就優先呼叫trait的成員

一、trait的宣告

1、使用trait關鍵字。支援final,static和abstract等修飾詞,所以trait也就支援抽象方法的使用、類定義靜態方法,也可以定義屬性。

2、但trait無法如類一樣new例項化,因為trait就是用來混入類中使用的,不能單獨使用。如果拿inte***ce和trait模擬,trait會有更多方便的地方。

二、優先順序

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

class base 

}trait sayworld

}class myhelloworld extends base

$o = new myhelloworld();

$o->sayhello();//hello world!

三、多個trait

1、通過逗號分隔,在 use 宣告列出多個 trait,可以都插入到乙個類中。

trait hello 

}trait world

}class myhelloworld

}$o = new myhelloworld();

$o->sayhello();//hello

$o->sayworld();//world

$o->sayexclamationmark();//!

2、衝突的解決

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

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

以上方式僅允許排除掉其它方法,as 操作符可以 為某個方法引入別名。 注意,as 操作符不會對方法進行重新命名,也不會影響其方法。

trait a 

public function bigtalk()

}trait b

public function bigtalk() }/*

在本例中 talker 使用了 trait a 和 b。由於 a 和 b 有衝突的方法,其定義了使用 trait b 中的 smalltalk 以及

trait a 中的 bigtalk。

*/class talker

}//aliased_talker 使用了 as 操作符來定義了 talk 來作為 b 的 bigtalk 的別名。

class aliased_talker

}$talker = new talker;

echo $talker->smalltalk();//b

echo $talker->bigtalk();//a

$aliased_talker = new aliased_talker;

echo $aliased_talker-> smalltalk();//b

echo $aliased_talker-> bigtalk();//a

echo $aliased_talker-> talk();//b

3、修改方法的訪問控制

使用 as 語法還可以用來調整方法的訪問控制。

trait helloworld 

}// 修改 sayhello 的訪問控制

class myclass1

}// 給方法乙個改變了訪問控制的別名

// 原版 sayhello 的訪問控制則沒有發生變化

class myclass2

}

四、從 trait 來組成 trait

正如 class 能夠使用 trait 一樣,其它 trait 也能夠使用 trait。在 trait 定義時通過使用乙個或多個 trait,能夠組合其它 trait 中的部分或全部成員。

trait hello 

}trait world

}trait helloworld

class myhelloworld

$o = new myhelloworld();

$o->sayhello();//hello

$o->sayworld();//world

五、trait 的抽象成員

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

trait hello 

abstract public function getworld();

}class myhelloworld

public function setworld($val)

}$myhelloworld = new myhelloworld;

$myhelloworld->setworld('america');

echo $myhelloworld->sayhelloworld();//hello america

六、trait 的靜態成員

traits 可以被靜態成員靜態方法定義。

trait counter 

}class c1

class c2

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

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

trait staticexample 

}class example

example::dosomething();

七、屬性

trait 定義了乙個屬性後,類就不能定義同樣名稱的屬性,否則會產生 fatal error。 有種情況例外:屬性是相容的(同樣的訪問可見度、初始預設值)。 但在 php 7.0 之前,即使屬性是相容的,也會有 e_strict 的提醒。

trait propertiestrait 

class propertie***ample

$example = new propertie***ample;

$example->x;

trait propertiestrait 

class propertie***ample

物件導向特性

三大特性 封裝 繼承 多型 封裝封裝屬性 1,私有化成員變數 2,提供get,set方法 3,在方法的內容加入控制語句 static靜態 修飾 成員屬性 方法 塊 static成員屬性 靜態變數,全域性變數 static成員 塊 用於初始化靜態變數 static成員方法 靜態方法 同一類中,在靜態方...

10 scala物件導向程式設計之Trait

1 將trait作為介面使用 2 trait中定義具體方法 3 trait定義具體字段 4 trait中定義抽象字段 5 為例項物件混入trait 6 trait呼叫鏈 7 在trait中覆蓋抽象方法 8 混合使用trait的具體方法和抽象方法 9 trait的構造機制 10 trait field...

物件導向特性 繼承

1 子類繼承父類的方法和字段 class computer 子類,膝上型電腦類 class notecomputer extends computer 2 不需要父類的字段和方法,那麼可以採用重寫的方法覆蓋掉父類的方法。class computer 子類,膝上型電腦類 class notecompu...