這次帶給大家程式碼重複使用Trait使用步奏詳解,程式碼複用Trait使用步的注意事項有哪些,下面就是實戰案例,一起來看一下。
從PHP的5.4.0版本開始,PHP提供了一種全新的程式碼重複使用的概念,那就是Trait。 Trait其字面意思是"特性"、"特點",我們可以理解為,使用Trait關鍵字,可以為PHP中的類別添加新的特性。
熟悉物件導向的都知道,軟體開發中常用的程式碼複用有繼承和多型兩種方式。在PHP中,只能實現單一繼承。而Trait則避免了這一點。下面透過簡單的額例子來進行比較說明。
1. 繼承 VS 多型 VS Trait
現在有Publish.php和Answer.php這兩個類別。若要在其中新增LOG功能,記錄類別內部的動作。有以下幾種方案:
繼承
多態
Trait
1.1. 繼承
程式碼結構如下:
// Log.php<?phpClass Log{ publicfunctionstartLog() { // echo ... } publicfunctionendLog() { // echo ... }} // Publish.php<?phpClass PublishextendsLog{} // Answer.php<?phpClass AnswerextendsLog{}
1.2. 多態
實作程式碼:
#// Log.php<?phpInterface Log{ publicfunctionstartLog(); publicfunctionendLog();} // Publish.php<?phpClass PublishimplementsLog{ publicfunctionstartLog() { // TODO: Implement startLog() method. } publicfunctionendLog() { // TODO: Implement endLog() method. }} // Answer.php<?phpClass AnswerimplementsLog{ publicfunctionstartLog() { // TODO: Implement startLog() method. } publicfunctionendLog() { // TODO: Implement endLog() method. }}
1.3. Trait
實作程式碼如下:
// Log.php<?phptrait Log{ publicfunctionstartLog() { // echo .. } publicfunctionendLog() { // echo .. }} // Publish.php<?phpclassPublish { useLog;}$publish=newPublish();$publish->startLog();$publish->endLog(); // Answer.php<?phpclassAnswer { useLog;}$answer=newAnswer();$answer->startLog();$answer->endLog();
1.4. 結論
繼承的方式雖然也能解決問題,但其思路違背了物件導向的原則,顯得很粗暴;多態方式也可行,但不符合軟體開發中的DRY原則,增加了維護成本。而Trait方式則避免了上述的不足之處,相對優雅的實現了代碼的複用。
2. Trait的作用域
了解了Trait的好處,我們還需要了解其實現中的規則,先來說一下作用域。這個比較好證明,實作程式碼如下:
<?phpclassPublish { useLog; publicfunctiondoPublish() { $this->publicF(); $this->protectF(); $this->privateF(); }} $publish=newPublish();$publish->doPublish(); publicfunctionprotectedfunctionprivatefunction
可以發現,Trait的作用域在引用該Trait類別的內部是都可見的。可以理解為use關鍵字將Trait的實作程式碼Copy了一份到引用該Trait的類別中。 |
3. Trait中屬性的優先權
說到優先級,就必須要有一個對比的參照物,這裡的參照對象時引用Trait的類及其父類。
透過以下的程式碼來證明Trait應用程式中的屬性的優先權:
<?phptrait Log{ publicfunctionpublicF() { echoMETHOD.' public function'. PHP_EOL; } protectedfunctionprotectF() { echoMETHOD.' protected function'. PHP_EOL; }}classQuestion{ publicfunctionpublicF() { echoMETHOD.' public function'. PHP_EOL; } protectedfunctionprotectF() { echoMETHOD.' protected function'. PHP_EOL; }}classPublishextendsQuestion{ useLog; publicfunctionpublicF() { echoMETHOD.' public function'. PHP_EOL; } publicfunctiondoPublish() { $this->publicF(); $this->protectF(); }} $publish=newPublish();$publish->doPublish(); 上述代码的输出结果如下: Publish::publicFpublicfunctionLog::protectFprotectedfunction
來自目前類別的成員覆寫了trait 的方法
trait 覆寫了被繼承的方法
類別成員優先權為:當前類別>Trait>父類別
就如字面意思一般,insteadof關鍵字用前者取代了後者,as關鍵字給被取代的方法起了一個別名。
在引用Trait時,使用了use關鍵字,use關鍵字也用來引用命名空間。兩者的差別在於,引用Trait時是在class內部使用的。
相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!
推薦閱讀:
以上是程式碼複用Trait使用步奏詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!