首頁 >後端開發 >php教程 >PHP中Trait的特性及作用分享

PHP中Trait的特性及作用分享

小云云
小云云原創
2018-03-02 09:42:251388瀏覽

Traits 是一種為類似 PHP 的單繼承語言而準備的程式碼多用機制。 Trait 為了減少單繼承語言的限制,使開發人員能夠自由地在不同層次結構內獨立的類別中復用方法集。

自 PHP 5.4.0 起,PHP 實作了程式碼重複使用的一個方法,稱為 traits。

Traits 是一種為類似 PHP 的單繼承語言而準備的程式碼重複使用機制。 Trait 為了減少單繼承語言的限制,使開發人員能夠自由地在不同層次結構內獨立的類別中復用方法集。 Traits 和類別組合的語義是定義了一種方式來減少複雜性,避免與傳統多繼承和混入類別(Mixin)相關的典型問題。

Trait 和一個類別相似,但僅僅旨在用細粒度和一致的方式來組合功能。 Trait 不能透過它本身來實例化。它為傳統繼承增加了水平特性的組合;也就是說,應用類別的成員不需要繼承。

Trait是在PHP5.4中加入的,它既不是介面也不是類別。主要是為了解決單一繼承語言的限制。是PHP多重繼承的解決方案。例如,需要同時繼承兩個 Abstract Class, 這將會是件很麻煩的事情,Trait 就是為了解決這個問題。它能被加入到一個或多個已經存在的類別中。它聲明了類別能做什麼(顯示了其介面特性),同時也包含了具體實作(顯示了其類別特性)

簡單使用

##首先,當然是宣告個Trait,PHP5.4 增加了trait 關鍵字

?

##1

#2

3

4


##trait first_trait {

function#first_method() { /* 此處程式碼*/ }

function second_method() { /* 此處程式碼 * / }

}

#

同時,如果要在Class 中使用該Trait,那麼使用use 關鍵字

#?

Trait 之間的巢狀

同時,Trait 之間也可以互相的巢狀,例如

##?

## 1

2

3

4

5

##6

7

#8

class first_class {

// 注意這行,宣告使用first_trait

#use first_trait;

}

#

$obj#= new first_class();

// 執行來自的方法特質

$obj->first_method(); ######// 有效的######<p class="line number8 index7 alt1" style="line-height:15.4px;margin:0px;padding:0px 1em;background-image:none;border:0px;float:none;vertical-align:baseline;min-height:auto;white-space:pre;"><code class="php variable" style="margin:3px auto 0px;padding:0px 0px 0px 5px;background:rgb(255,255,255);border-left:3px solid rgb(108,226,108);font-size:14px;clear:both;border-top:0px;border-right:0px;border-bottom:0px;float:none;vertical-align:baseline;font-family:Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;min-height:auto;color:rgb(170,119,0);">$obj->second_method(); ######// 有效的#######<p style="margin-bottom:0px;padding-top:5px;padding-bottom:5px;font-size:14px;line-height:30px;"><strong>使用多個Trait<br></strong></p> <p style="margin-bottom:0px;padding-top:5px;padding-bottom:5px;font-size:14px;line-height:30px;">在同一個Class 中可以使用多個Trait</p> <p class="toolbar" style="line-height:13.2px;margin:0px;padding:0px;background:rgb(108,226,108);border:none;float:none;vertical-align:baseline;font-family:Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;min-height:auto;color:#FFFFFF;"><span style="line-height:25.2px;">?</span></p> <table border="0" style="border-spacing:0px;border:1px solid rgb(204,204,204);margin-top:.54em;text-align:center;clear:both;background:none;float:none;line-height:1.1em;margin-right:0px;margin-bottom:0px;margin-left:0px;padding:0px;vertical-align:baseline;font-family:Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;font-size:1em;min-height:auto;"> <tbody style="background:none;float:none;line-height:1.1em;margin:0px;padding:0px;text-align:left;vertical-align:baseline;font-size:1em;min-height:auto;"><tr style="background:none;border-top:0px;float:none;line-height:1.1em;margin:0px;padding:0px;vertical-align:baseline;font-size:1em;min-height:auto;" class="firstRow"> <td class="gutter" style="padding:.2em .46em;border-color:rgb(204,204,204);margin:0px;background:none;float:none;line-height:1.1em;vertical-align:baseline;font-family:Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;font-size:1em;min-height:auto;color:rgb(175,175,175);"> <p class="line number1 index0 alt2" style="line-height:15.4px;margin:0px;padding:0px .5em 0px 1em;background-image:none;border-width:0px 3px 0px 0px;border-right-style:solid;border-right-color:rgb(108,226,108);float:none;text-align:right;vertical-align:baseline;min-height:auto;white-space:pre;">1</p> <p class="line number2 index1 alt1" style="line-height:15.4px;margin:0px;padding:0px .5em 0px 1em;background-image:none;border-width:0px 3px 0px 0px;border-right-style:solid;border-right-color:rgb(108,226,108);float:none;text-align:right;vertical-align:baseline;min-height:auto;white-space:pre;">2</p> <p class="line number3 index2 alt2" style="line-height:15.4px;margin:0px;padding:0px .5em 0px 1em;background-image:none;border-width:0px 3px 0px 0px;border-right-style:solid;border-right-color:rgb(108,226,108);float:none;text-align:right;vertical-align:baseline;min-height:auto;white-space:pre;">3</p> <p class="line number4 index3 alt1" style="line-height:15.4px;margin:0px;padding:0px .5em 0px 1em;background-image:none;border-width:0px 3px 0px 0px;border-right-style:solid;border-right-color:rgb(108,226,108);float:none;text-align:right;vertical-align:baseline;min-height:auto;white-space:pre;">4</p> <p class="line number5 index4 alt2" style="line-height:15.4px;margin:0px;padding:0px .5em 0px 1em;background-image:none;border-width:0px 3px 0px 0px;border-right-style:solid;border-right-color:rgb(108,226,108);float:none;text-align:right;vertical-align:baseline;min-height:auto;white-space:pre;">#5</p> <p class="line number6 index5 alt1" style="line-height:15.4px;margin:0px;padding:0px .5em 0px 1em;background-image:none;border-width:0px 3px 0px 0px;border-right-style:solid;border-right-color:rgb(108,226,108);float:none;text-align:right;vertical-align:baseline;min-height:auto;white-space:pre;">6</p> <p class="line number7 index6 alt2" style="line-height:15.4px;margin:0px;padding:0px .5em 0px 1em;background-image:none;border-width:0px 3px 0px 0px;border-right-style:solid;border-right-color:rgb(108,226,108);float:none;text-align:right;vertical-align:baseline;min-height:auto;white-space:pre;">7</p> <p class="line number8 index7 alt1" style="line-height:15.4px;margin:0px;padding:0px .5em 0px 1em;background-image:none;border-width:0px 3px 0px 0px;border-right-style:solid;border-right-color:rgb(108,226,108);float:none;text-align:right;vertical-align:baseline;min-height:auto;white-space:pre;">8</p> <p class="line number9 index8 alt2" style="line-height:15.4px;margin:0px;padding:0px .5em 0px 1em;background-image:none;border-width:0px 3px 0px 0px;border-right-style:solid;border-right-color:rgb(108,226,108);float:none;text-align:right;vertical-align:baseline;min-height:auto;white-space:pre;">9</p> <p class="line number10 index9 alt1" style="line-height:15.4px;margin:0px;padding:0px .5em 0px 1em;background-image:none;border-width:0px 3px 0px 0px;border-right-style:solid;border-right-color:rgb(108,226,108);float:none;text-align:right;vertical-align:baseline;min-height:auto;white-space:pre;">10</p> <p class="line number11 index10 alt2" style="line-height:15.4px;margin:0px;padding:0px .5em 0px 1em;background-image:none;border-width:0px 3px 0px 0px;border-right-style:solid;border-right-color:rgb(108,226,108);float:none;text-align:right;vertical-align:baseline;min-height:auto;white-space:pre;">#11</p> <p class="line number12 index11 alt1" style="line-height:15.4px;margin:0px;padding:0px .5em 0px 1em;background-image:none;border-width:0px 3px 0px 0px;border-right-style:solid;border-right-color:rgb(108,226,108);float:none;text-align:right;vertical-align:baseline;min-height:auto;white-space:pre;">12</p> <p class="line number13 index12 alt2" style="line-height:15.4px;margin:0px;padding:0px .5em 0px 1em;background-image:none;border-width:0px 3px 0px 0px;border-right-style:solid;border-right-color:rgb(108,226,108);float:none;text-align:right;vertical-align:baseline;min-height:auto;white-space:pre;">13</p> <p class="line number14 index13 alt1" style="line-height:15.4px;margin:0px;padding:0px .5em 0px 1em;background-image:none;border-width:0px 3px 0px 0px;border-right-style:solid;border-right-color:rgb(108,226,108);float:none;text-align:right;vertical-align:baseline;min-height:auto;white-space:pre;">14</p> <p class="line number15 index14 alt2" style="line-height:15.4px;margin:0px;padding:0px .5em 0px 1em;background-image:none;border-width:0px 3px 0px 0px;border-right-style:solid;border-right-color:rgb(108,226,108);float:none;text-align:right;vertical-align:baseline;min-height:auto;white-space:pre;">15</p> <p class="line number16 index15 alt1" style="line-height:15.4px;margin:0px;padding:0px .5em 0px 1em;background-image:none;border-width:0px 3px 0px 0px;border-right-style:solid;border-right-color:rgb(108,226,108);float:none;text-align:right;vertical-align:baseline;min-height:auto;white-space:pre;">16</p> </td> <td class="code" style="padding:.2em .46em;border-color:rgb(204,204,204);margin:0px;background:none;float:none;line-height:1.1em;vertical-align:baseline;font-family:Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;font-size:1em;min-height:auto;"> <p class="container" style="line-height:15.4px;margin:0px;padding:0px;background:none;border:0px;float:none;vertical-align:baseline;min-height:auto;"><br></p> <p class="line number1 index0 alt2" style="line-height:15.4px;margin:0px;padding:0px 1em;background-image:none;border:0px;float:none;vertical-align:baseline;min-height:auto;white-space:pre;">##特質first_trait<code class="php plain" style="margin:3px auto 0px;padding:0px 0px 0px 5px;background:rgb(255,255,255);border-left:3px solid rgb(108,226,108);font-size:14px;clear:both;border-top:0px;border-right:0px;border-bottom:0px;float:none;vertical-align:baseline;font-family:Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;min-height:auto;color:#000000;">

{#

function#first_method() { echo#"方法"#; }

}

特質 secondary_trait {

#

function#second_method() { echo#"方法"; }

}

first_class {

## // 現在使用多個特質

##use#first_trait, secondary_trait;

#}

##$obj

= new#first_class();

# // 有效

<p class="line number14 index13 alt1" style="line-height:15.4px;margin:0px;padding:0px 1em;background-image:none;border:0px;float:none;vertical-align:baseline;min-height:auto;white-space:pre;"><code class="php variable" style="margin:3px auto 0px;padding:0px 0px 0px 5px;background:rgb(255,255,255);border-left:3px solid rgb(108,226,108);font-size:14px;clear:both;border-top:0px;border-right:0px;border-bottom:0px;float:none;vertical-align:baseline;font-family:Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;min-height:auto;color:rgb(170,119,0);">$obj->first_method(); //列印:method

//有效

#$obj##->second_method ( ); //列印:方法

Trait 的抽象方法(Abstract Method)

我們可以在Trait 中宣告需要實作的抽象方法,這樣能讓使用它的Class 必須實作它

?

1

2

#3

4

5

6

7

8

9

#10

11

12

13

14

15

16


##trait first_trait {

function#first_method() { echo "method"; }

}

trait secondary_trait {

use first_trait;

function#second_method() { echo#"method"

###; }######

}

class#first_class {

// 現在使用

##use#second_trait;

#}

$obj= new first_class();

// Valid

<p class="line number14 index13 alt1" style="line-height:15.4px;margin:0px;padding:0px 1em;background-image:none;border:0px;float:none;vertical-align:baseline;min-height:auto;white-space:pre;"><code class="php variable" style="margin:3px auto 0px;padding:0px 0px 0px 5px;background:rgb(255,255,255);border-left:3px solid rgb(108,226,108);font-size:14px;clear:both;border-top:0px;border-right:0px;border-bottom:0px;float:none;vertical-align:baseline;font-family:Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;min-height:auto;color:rgb(170,119,0);">$obj->first_method(); //列印:method

//有效

#$obj##->second_method ( ); //列印:方法

1

2

3

# 4

5

6

7

8

9

10

11


trait first_trait {

function first_method() { echo "method"#; }

// 這裡可以加入修飾符,說明調用類別必須實作它

abstract#public#function#second_method();

##}

##類別

#first_method {

#use

#first_trait;#<p class="line number8 index7 alt1" style="line-height:15.4px;margin:0px;padding:0px 1em;background-image:none;border:0px;float:none;vertical-align:baseline;min-height:auto;white-space:pre;"><code class="php keyword" style="margin:3px auto 0px;padding:0px 0px 0px 5px;background:rgb(255,255,255);border-left:3px solid rgb(108,226,108);font-size:14px;clear:both;font-weight:bold;border-top:0px;border-right:0px;border-bottom:0px;float:none;vertical-align:baseline;font-family:Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;min-height:auto;color:rgb(0,102,153);">function#second_method() {

#/* 此處程式碼*/

}

}

#

Trait 衝突

多個 Trait 之間同時使用難免會衝突,這需要我們去解決。 PHP5.4 從語法方面帶入了相關的關鍵字語法:insteadof 以及as ,用法參見

#?

上面就是些 Trait 比較基本的使用了,更詳細的可以參考官方手冊。這裡總結下注意的幾點:

Trait 會覆寫呼叫類別繼承的父類別方法

Trait 無法如Class 一樣使用new 實例化

單一Trait 可由多個Trait 組成

在單一Class 中,可以使用多個Trait

Trait 支援修飾詞(modifiers),例如final、static、abstract

我們可以使用insteadof 以及as 操作符解決Trait 之間的衝突

相關推薦:

關於Trait在php中的詳解及其應用

關於PHP中的Trait問題

php中關於traits重複使用機制的使用詳解

##1

2

3

4

#5

##6

##7

#8

9

###10###

11

12

13

14

15

16

17

#18

19

20

21


##特質first_trait {

#

function first_function() {

#echo "From First Trait"#;

}

}

#trait second_trait {

// 這裡的名稱和first_trait 一樣,會有衝突

#<p class="line number8 index7 alt1" style="line-height:15.4px;margin:0px;padding:0px 1em;background-image:none;border:0px;float:none;vertical-align:baseline;min-height:auto;white-space:pre;"><code class="php keyword" style="margin:3px auto 0px;padding:0px 0px 0px 5px;background:rgb(255,255,255);border-left:3px solid rgb(108,226,108);font-size:14px;clear:both;font-weight:bold;border-top:0px;border-right:0px;border-bottom:0px;float:none;vertical-align:baseline;font-family:Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;min-height:auto;color:rgb(0,102,153);">function#first_function() {

#echo#"來自第二個特徵" #;

}

}

#class first_class {

use first_trait, second_trait {

// 在這裡宣告使用first_trait 的first_function 取代

#// second_trait 中宣告的

first_trait::first_function insteadof second_trait;

}

#}

##$obj#= new first_class();

// 輸出:從第一個開始Trait

$obj->first_function();

以上是PHP中Trait的特性及作用分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn