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关键字的时候我无计可施。