## 什么是多态:
多态不但能够改善代码的组织结构和可读性,还能够创建可扩展的程序。在Java中,所有的方法都是通过动态绑定实现多态的。将一个方法调用同一个方法主体关联起来被称作绑定。动态绑定的含义是在运行时根据对象的类型进行绑定。动态绑定也叫作后期绑定或运行时绑定。Java中除了static方法和final方法(private方法属于final方法)之外,其他所有的方法都是后期绑定。这意味着通常情况下,我们不必判定是否应该进行后期绑定——它会自动发生。也就是说,在Java中,只有普通的方法是多态的,static方法、private方法、final方法以及成员变量都不是多态的,都属于编译期绑定。
## 注意事项一:“覆盖”私有方法
例子:
~~~
public class PrivateOverride {
private void f(){
System.out.println("private f()");
}
public static void main(String[] args){
PrivateOverride po = new Derived();
po.f();
}
}
class Derived extends PrivateOverride{
public void f(){
System.out.println("public f()");
}
}
~~~
输出:
~~~
private f()
~~~
说明:对于private方法来说,它默认是final的,不允许被更改,导出类看不到private方法,不能被继承,也就没有“覆盖(override)”这一说。当导出类有一个同名的符合覆盖规则的方法时,其实导出类中的该方法是一个全新的方法。但是当我们试图对私有方法进行覆盖并使用多态时,虽然编译器不会报错,但私有方法不支持多态,最终调用的是基类中的方法。
## 注意事项二:域与静态方法不支持多态
例子:
~~~
class Super{
public int field = 0;
public int getField(){
return field;
}
public static String say(){
return "Super static function.";
}
}
class Sub extends Super{
public int field = 1;
public int getField(){
return field;
}
public int getSuperField(){
return super.field;
}
public static String say(){
return "Sub static function.";
}
}
public class FieldAccess{
public static void main(String[] args){
Super sup = new Sub();
System.out.println("sup.field = " + sup.field + ", sup.getField() = " + sup.getField());
System.out.println("sup.say = " + sup.say());
Sub sub = new Sub();
System.out.println("sub.field = " + sub.field + ", sub.getField() = " + sub.getField() + ", sub.getSuperField() = " + sub.getSuperField());
System.out.println("sub.say = " + sub.say());
}
}
~~~
输出:
~~~
sup.field = 0, sup.getField() = 1
sup.say = Super static function.
sub.field = 1, sub.getField() = 1, sub.getSuperField() = 0
sub.say = Sub static function.
~~~
说明:对于域和静态方法,是不支持多态的,他们都属于前期绑定,即在编译期实现的绑定。故域和静态方法只能绑定到基类的域和方法,不支持动态绑定。
(以上代码来自Java编程思想第四版,说明来自Java编程思想第四版中关于多态的章节的整理,仅用于学习和交流)