深入理解Java中的多态
一.什么是多态?
多态指同一个实体同时具有多种形式。它是面向对象程序设计(OOP)的一个重要特征。如果一个语言只支持类而不支持多态,只能说明它是基于对象的,而不是面向对象的。
二.多态是如何实现的?
在了解多态是如何实现的之前,我们先来了解一下两个概念。
前期绑定:在编译期就完成的绑定,与对象无关,与类相关,比如最常见的static方法和static的方法块。
后期绑定:也就是运行时期的绑定,而多态就是在这个阶段实现的。
在Java中所有的方法除了static方法和final方法(将private方法归于final方法他们二者在继承里都是无法被子类继承的详见我的另外一篇文章http://www.cnblogs.com/SAM-CJM/p/9359397.html)都是在后期实现绑定的。
那么也就是说static访法是无法实现多态的。
例子如下:
package com.cjm.polymorphic; /** * 静态方法的多态测试 * * @author 小明 * */ public class StaticFunText { public static void main(String[] args) { A a=new B(); a.f(); a.f1(); } } class A { public void f() { System.out.println("A类的非静态方法,多态机制可以实现"); } public static void f1() { System.out.println("A类的静态方法,多态机制无法实现"); } } class B extends A { public void f() { System.out.println("子类的非static方法是可以被调用的!!"); } public static void f1() { System.out.println("子类的stati方法是不可以被重写的!!"); } }
结果:
可以发现我们的子类静态方法没有被调用。
静态方法与类相关联,而多态是面向对象的,所以从这个方向来思考,也就不难理解为什么静态方法不能实现多态了。
三.域与多态
由于任何的域都将由编译器解析,所以域不是多态的。
例子如下:
package com.cjm.polymorphic; /** * 域与多态的关系 * @author 小明 * */ public class VariableText { public static void main(String[] args) { C c=new D(); System.out.println(c.num);//没有实现多态的得到的是父类的域 System.out.println(c.getNum());//通过方法实现了多态 } } class C{ int num=0; public int getNum() { return num; } } class D extends C{ int num=1; public int getNum() { return num; } public int getCNum() { System.out.println(super.getNum());//显示调用出现父类的值 return super.num; } }
结果如下:
四.构造器、清理与多态
对于继承时的构造器的调用序数:首先调用父类的构造器,直到最底层的父类,然后再是导出类,直到最实现类。
清理正好与构造相反,先要消除子类的部分再来消除父类的部分