首先是這樣一組代碼:
abstract class User{}class Admin extends User{ private $group; public static function create(){ return new Admin(); } public static function getGroup(){ return "admin"; } //.......其他更多函數。。}
class NormalUser extends User{ private $group; public static function create(){ return new NormalUser(); } public static function getGroup(){ return "normaluser"; } //其他函數。}
首先是定義了一個抽象的類,然後建立了兩個子類admin和normalUser,並且這兩個類中都包含了兩個靜態方法create和getgroup.這樣的代碼幾乎沒有什麼問題,然而卻有很多的冗餘。現在只有兩個子類,如果子類增多的話,就需要增加與之類似的代碼。這樣我們不得不思考,如果把這段通用的代碼提取放到父類中是不是可以呢。
很多人可能都想到了用self關鍵字。廢話少說,我們開始行動。
abstract class User{ public static function create(){ return new self(); } public static function getGroup(){ return self::getGroup(); }}class Admin extends User{}class NormalUser extends User{}Admin :: create();
代碼看起來規整了許多。然而不幸的是,運行這段代碼,給出了這樣的錯誤提示:
--------------------------------------------------------------PHP Fatal error: Cannot instance abstract class User in...--------------------------------------------------------------
出現這段錯誤的原因是什麼呢?原因就是:self被解析為定義create的Object對象(User),而不是解析為調用self的Object對象(Admin).因此,self的方法是不可行的。
sigh....
不過不用氣餒,php 5.3引入了延遲靜態繫結的概念,用static關鍵字標明,它與self關鍵字類似,不同的是,static會被解析為被調用的類而不是被定義的類。現在代碼變成這樣:
abstract class User{ public static function create(){ return new static(); } public static function getGroup(){ return static::getGroup();}}
是不是方便了許多呢?
。。。。。