看例子6.10. 这段代码输出” Hey! I am Son.” 因为当PHP调用getSalutation, 是一个Son的实例,是将Father中的salutation覆写而来. 如果salutation是public的,PHP将产生相同的结果. 覆写方法的操作很类似.在Son中,对于identify的调用绑定到那个方法.
Listing 6.10 Dynamic binding 动态绑定
class Father { protected $salutation = "Hello there!"; file://问候
public function getSalutation() { print("$this->salutationn"); $this->identify(); }
protected function identify() { print("I am Father. n"); } };
class Son extends Father { protected $salutation = "Hey!"; file://父类中的protected $salutation 被覆写
protected function identify() file://父类中的protected identify() 被覆写 { print("I am Son. n"); } };
$obj = new Son(); $obj->getSalutation(); file://输出Hey! I am Son. ?>
//注: 在子类中没有覆写getSalutation(),但实际上仍然存在一个getSalutation().这个类中的$salutation和identify() //与Son子类的实例中的getSalutation()方法动态绑定,所以调用Son的实例的getSalutation()方法, //将调用Son类中的成员salutation及identify(),而不是父类中的成员salutation及identify().
Private成员只存在于它们所在的类内部. 不像public和protected成员那样,PHP模拟静态绑定. 看例子6.11. 它输出”Hello there! I am Father.”,尽管子类覆写了salutation的值. 脚本将this->salutation和当前类Father绑定. 类似的原则应用于private方法identify().
Listing 6.11 Binding and private members
class Father { private $salutation = "Hello there!";
public function getSalutation() { print("$this->salutationn"); $this->identify(); }
private function identify() { print("I am Father. n"); } }
class Son extends Father { private $salutation = "Hey!"; private function identify() { print("I am Son. n"); } }
$obj = new Son(); $obj->getSalutation(); file://输出Hello there! I am Father. ?>动态绑定的好处是允许继承类来改变父类的行为,同时可以保持父类的接口和功能. 看例子6.12. 由于使用了动态绑定,在deleteUser中被调用的isAuthorized的version 可以由对象的类型来确定. 如果是一个普通的user,PHP调用User::isAuthorized会返回FALSE.如果是一个AuthorizedUser的实例,PHP调用AuthorizedUser::isAuthorized,将允许deleteUser顺利执行.