多态通过分离做什么和怎么做,从另一个角度将接口和实现分离开来。多态不但能够改善代码的组织结构和可读性,还能够创建可扩展的程序。
多态通过动态绑定实现。
8.1 动态绑定
方法调用绑定:将一个方法调用同一个方法主体关联起来被称作绑定。前期绑定由编译器和链接器实现。后期绑定又称动态绑定或运行时绑定,对象中安置某种类型信息,编译器并不知道对象的具体类型,但是方法调用机制能找到正确的方法体,并加以调用。
java中除了static 和 final 方法(private 方法属于final 方法)之外,其他所有方法都是后期绑定。
8.2 构造器内部的多态方法行为
如果调用构造器内部的一个动态绑定方法,就要用到那个方法的被覆盖后的定义。然而这可能会造成一些难以发现的隐藏错误,因为被覆盖的方法在对象被完全构造之前就被调用。
例子:
class Glyph{
void draw(){ print ("Glyph.draw()"); }
Glyph(){
print("Glyph() before draw()");
draw();
print ("Glyph() after draw()");
}
}
class RoundGlphy extends Glphy{
private int radius=1;
RoundGlphy(int r){
radius=r;
print("RoundGlphy(),radiuse="+radius);
}
void draw(){
print("RoundGlphy.draw(),radius="+radius);
}
}
public class PolyConstructors{
public static void main(String[] args){
new RoundGlphy(5);
}
}
输出:
Glyph() before draw()
RoundGlphy.draw(),radius=0
Glyph() after draw()
RoundGlphy(),radiuse=5
初始化的实际过程:
(1)在其他任何事物发生前,初始化对象的存储空间并初始化为二进制的零。
(2)调用基类构造器。
(3)按照声明顺序调用成员的初始化方法。
(4)调用导出类的构造器主体。
因此,编写构造器有一条有效的准则:尽可能用简单的方法使对象进入正常状态;如果可以的话,避免调用其它方法。在构造器中唯一能够安全调用的那些方法是基类中的final方法(也适用于private方法,它们属于自动final方法)。
8.3 协变返回类型
Java SE5中添加了协变返回类型,它表示在导出类的重写方法可以返回基类方法返回类型的某种导出类型。