什么是多态:
多态不但能够改善代码的组织结构和可读性,还能够创建可扩展的程序。在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编程思想第四版中关于多态的章节的整理,仅用于学习和交流)