PHP是一種支持面向對象編程的語言,而Trait是它的一種重要特性之一。作為一種代碼復用方式,Trait主要用于幫助我們避免寫出重復的代碼,簡化開發(fā)工作。不過,Trait有一個比較特殊的成員修飾符——private,它和類的private成員有些類似,但在使用的過程中有些不同。本文將重點探討Trait中private成員的使用。
那么,首先我們來看一下什么是Trait。在PHP中,Trait是一種代碼復用機制,它可以讓我們書寫出一些可重用的代碼段,然后將它們混入到類中。被混入的類可以直接使用Trait中的公共成員和方法(即使用了public修飾符的成員和方法),而不需要繼承。這就可以提高代碼的復用性,減少代碼冗余。
但是,Trait中的成員修飾符有著和類中不同的特點。Trait中的成員修飾符包括public、protected、private三種。其中,public成員可以在類中直接使用,protected成員只能在類及其子類中使用,而private成員只能在Trait中使用。
trait MyTrait{
private $att = 'I am in trait';
public function show() {
echo $this->att;
}
}
class MyClass{
use MyTrait;
}
$MyClassObj = new MyClass();
$MyClassObj->show();//這句會提示一個錯誤
就如上述代碼所示,我們把一個名為MyTrait的Trait中定義了一個私有成員$att,這個屬性只能在Trait中使用,然后通過一個名為show的public方法,將它輸出來。在MyClass類中引入這個Trait后,我們使用與普通類方法相同的方式來創(chuàng)建一個類實例,并調用它的show方法。但是,運行這段代碼的結果將提示下面的錯誤:
Fatal error: Uncaught Error: Cannot access private property MyTrait::$att in ...
這是因為,雖然我們在Trait中通過私有成員的方式將屬性att封裝起來,但是在類中調用Trait中的show方法,則屬于類的公開訪問權限范圍。因此,在show方法中,我們無法通過對象實例來訪問Trait中私有定義的att屬性。
那么,使用Trait中的private屬性有什么意義呢?私有屬性的存在,主要是為Trait中其他成員服務的。就比如上面的例子一樣,在Trait中定義了一個私有屬性,可以在Trait中的其他方法內部使用,然后通過這些方法,在類中直接使用。就拿上面的代碼舉例來說,我們可以將MyTrait中的show方法改造一下:
trait MyTrait{
private $att = 'I am in trait';
public function show() {
$this->showAtt();
}
private function showAtt() {
echo $this->att;
}
}
class MyClass{
use MyTrait;
}
$MyClassObj = new MyClass();
$MyClassObj->show();//輸出:I am in trait
這樣,在使用show方法的時候,我們實際上是調用了Trait中的私有成員showAtt方法。showAtt方法可以順利訪問到私有的att屬性,但同時,由于不是一個公開的方法,因此我們也無法在MyClass中直接使用它。這就實現(xiàn)了Trait的特化處理了。
綜上所述,使用Trait中的private屬性,主要是為了幫助Trait中的其他成員完成自己的任務,在類中直接使用是否能夠訪問到這些屬性,則與使用它的方法及成員所屬的范圍有關。如果我們只是想在Trait中定義一個私有屬性,并且讓類派生出來的對象可以直接訪問,那么應該使用protected修飾符。
最后要提醒的是,在 Trait 中使用 private 成員需要謹慎。如果 Trait 中定義了許多私有屬性,在使用者的角度來看,這些屬性可能會產生沖突,因為我們無法把 Trait 中的屬性寫到使用類中,進行覆蓋和處理。因此,在使用 Trait 的時候,建議只使用少量的 private 屬性,并在設計 Trait 時,盡可能地考慮到不同使用者之間的兼容性。