1. 向上转型(upcast)
一个ext class的object可以用base class的reference来指向,即ext class的object reference可以升级为base class的object reference。
如:Base b = new Ext();
2. 动态绑定(dynamic binding)
一般说来,将一个方法调用和一个方法主体关联起来叫做绑定。也可以理解为将方法名和方法body(方法代码段)关联起来叫做绑定。除了static方法和final方法(final包含private)外,Java对其他所有的方法都采用dynamic binding(3月27日补充:请正确理解这句话;more details see [#0x000C]),即直到调用方法的那个时刻才开始绑定。
多态即是利用了动态绑定这一特点。举个例子来说,Base类有个work()方法,Base类的两个子类Ext1和Ext2都覆写了work()方法,现在有一个Base b,它可能是一个new Base(),也可能是一个new Ext1()或是new Ext2()(向上转型允许),若此时调用b.work(),编译器会判断究竟是调用Base类的work()还是Ext1类的work()或是Ext2类的work()。从这个角度来说,动态绑定更像是动态确定reference指向的object,即这个reference到底是指向Base object还是Ext1 object或是Ext2 object。
注意,Ext1和Ext2必须是都覆写了work()方法,如果不是覆写就没有动态绑定的意义了,因为只有覆写才能造成Base、Ext1、Ext2中各有一个同签名不同方法body的work()方法。
p.s. 不存在平行转型(horizontal-cast),即Ext1 e = new Ext2()。
3. field和static方法没有动态绑定
意味着b.field和b.staticFunction()完全看b的声明类型。若是声明了Ext b,则是Ext的field和staticFunction();若是声明了Base b,则是Base的field和staticFunction(),就算有Base b = new Ext()也是如此。
4. 利用多态的一个例子
如在某方法中,不管传进来的参数是Ext1 object还是Ext2 object,都要求执行work()方法,这是可以写成:
return-type xxx(..., Base b, ...)
{
...;
b.work();
...;
}
这就相当于把类型判断交给编译器去执行了。