background image

PHP 静态绑定与动态绑定

除了限制访问,访问方式也决定哪个方法将被子类调用或哪个属性将被子类访问. 函数调
用与函数本身的关联,以及成员访问与变量内存地址间的关系,称为绑定.
在计算机语言中有两种主要的绑定方式?静态绑定和动态绑定. 静态绑定发生于数据结构
和数据结构间,程序执行之前. 静态绑定发生于编译期, 因此不能利用任何运行期的信息. 
它针对函数调用与函数的主体,或变量与内存中的区块. 因为 PHP 是一种动态语言,它不使
用静态绑定. 但是可以模拟静态绑定.
动态绑定则针对运行期产生的访问请求,只用到运行期的可用信息. 在面向对象的代码中,
动态绑定意味着决定哪个方法被调用或哪个属性被访问,将基于这个类本身而不基于访问
范围.
Public 和 protected 成员的动作类似于 PHP 的前几个版本中函数的动作,使用动态绑定. 这意
味着如果一个方法访问一个在子类中被覆写的类成员,并是一个子类的实例,子类的成员将
被访问(而不是访问父类中的成员).
看图 1. 

” 

这段代码输出 Hey! I am Son.” 因为当 PHP 调用 getSalutation, 是一个 Son 的实例,

是将 Father 中的 salutation 覆写而来. 如果 salutation 是 public 的,PHP 将产生相同的结果. 覆
写方法的操作很类似.在 Son 中,对于 identify 的调用绑定到那个方法.
即使在子类中访问方式被从 protected 削弱成 public, 动态绑定仍然会发生. 按照访问方式
使用的原则,增强对于类成员的访问限制是不可能的. 所以把访问方式从 public 改变成
protected 不可能进行.
动态绑定
<?php
   class Father
   {
       protected $salutation = "Hello there!"; //问候
       public function getSalutation()
       {
           print("$this->salutation\n");
           $this->identify();
       }
       protected function identify()
       {
           print("I am Father.\n");
       }
   };
   class Son extends Father
   {
       protected $salutation = "Hey!";  //父类中的 protected $salutation 被覆写
       protected function identify()    //父类中的 protected identify() 被覆写
       {
           print("I am Son.\n");
       }
   };
   $obj = new Son();