PHP5.3中引入了延遲靜態繫結的概念。該特性最明顯的標誌就是新關鍵字static。static類似於self,但它指的是被呼叫的類而不是包含類。在本例中,它的意思是呼叫Document::create()將生成一個新的Document物件,而不是試圖例項化一個DomainObject物件。
因此,現在在靜態上下文中使用繼承關係。
abstract class DomainObject{ public static function create(){ return new static(); } } class User extends DomainObject{ } class Document extends DomainObject{ } print_r(Document::create());
------------------------------------
Document Object
(
)
-------------------------------------
static 關鍵字不僅僅可以用於例項化。和self和parent一樣,static還可以作為靜態方法呼叫的識別符號,甚至是從非靜態上下文中呼叫。假設我想為DomainObject引入組的概念。預設情況下,所有類都屬於default類別,但我想能為繼承層次結構的某些分支重寫類別。
abstract class DomainObject{ private $group; public function __construct(){ $this->group = static::getGroup(); } public static function create(){ return new static(); } static function getGroup(){ return "default"; } } class User extends DomainObject{ } class Document extends DomainObject{ static function getGroup(){ return "document"; } } class SpreadSheet extends Document{ } print_r(User::create()); print_r(SpreadSheet::create());
在DomainObject類中定義了建構函式。該建構函式使用static關鍵字呼叫靜態方法getGroup()。DomainObject提供了預設實現,但Document將其覆蓋了。我還建立了一個新類SpreadSheet,該類擴充套件了Document類。下面是輸出:
---------------------------------------
User Object
(
[group:DomainObject:private] => default
)
SpreadSheet Object
(
[group:DomainObject:private] => document
)
---------------------------------------
User類不需要實現太多功能。DomainObject建構函式呼叫了getGroup()類,並在本地進行查詢。對於SpreadSheet,雖然搜尋從被呼叫的類SpreadSheet本身開始,但它沒有提供任何實現,因此呼叫類Document中的getGroup()方法。PHP5.3以前未引入延遲靜態繫結,self關鍵字只查詢DomainObject類中的getGroup(),因此遇到self關鍵字的時候我無計可施。