
























































































































解说:test[1]声明为一个PolymorphicTest的变量,但是它可以refer to一个PolymorphicChild类型的对象(如child),当然它也肯定可以refer to一个PolymorphicTest类型的对象,因为它本身就是这个类型的,例如test[0]。为什么会这样呢?一般来说,一个对象变量可以指向(refer to)任意一个它自己所属类型及其子类型的对象,有一个有名的(is-a)规则,类似于我国古代的“白马非马”这个典故。它就是说,任何一个子类的对象都可以说成是其父类的一个对象,但是反之则不一定了,例如,我们可以说白马是马,但是不能说马是白马。这个规则的另外一个表示方法就是“替换”准则:凡是程序中需要用到父类对象的地方,我们都可以用其子类的对象来进行替换。
接下来,就产生了一个问题,我们调用test[1]的setName(String n)方法的时候,它调用的到底是PolymorphicTest类还是PolymorphicChild类的setName方法呢?这就涉及到动态绑定的问题了,对象如何自动的选择合适的方法来执行?
2. 动态绑定(Dynamic Binding)
以上一节中的test[1].setName(String n)为例,我们现在有语句test[1].setName(“zhukai”),
那么它的执行过程是什么样的呢?
第一步:查看test[1]声明的类型,即PolymorphicTest类,然后获得方法名setName,接着把PolymorphicTest类中的所有名字为setName的方法以及其父类中所有名字为setName的public方法列出来。若没有名为setName的方法,则调用失败,否则转第二步。
第二步:根据所调用方法的参数类型来对上一步所列出来的所有方法进行匹配,直到找到一个匹配的转第三步,如果没有匹配则调用失败。
第三步:若test[1]所指向(refer to)的对象的类型为其一个子类,则需查看子类有没有覆盖该方法,若有,则执行子类中的方法。
注1:如果这个方法是private或者static或者final类型的,就不用进行动态绑定了,因为编译器可以很准确的知道要调用哪个方法。
注2:查询匹配方法时,是按照继承树逐级向上查找,直到找到第一个匹配的。
以上就是动态绑定的过程。
上面的程序执行时,将会输出“在父类中”、在子类中A、在子类中B
&