深入理解Java的方法调用二(多态性)
2013-05-13 08:18
295 查看
Java的多态性表现在2个方面,1方法的覆盖、2方法的重载。
运行结果
say Human!
say Human!
Man say!
Woman say!
从输出结果来看,方法的覆盖和重载表现的不太一致。方法的覆盖安照预期的结果调用了子类的say方法;但方法的重载视乎超预期没有调用相应的子类参数的方法。在方法重载的选择中,为什么会选择形参类型为Human的重载呢?在解决这个问题前,我们先按照如下代码定义两个重要的概念:
Human man = new Man();
我们把上面的代码中“Human”称为变量的静态类型或者外观类型,后面的“Man”则称为变量的实际类型。静态类型编译期可知,实际类型运行时才可确定。
在上面main方法的代码中刻意定义了2个静态类型相同、实际类型不同的变量,但虚拟机(准确地说编译器)在重载时是通过参数的静态类型而不是实际类型作为判定的依据的。并且静态类型是编译期可知的,所以在编译阶段,Javac就根据参数的静态类型决定使用哪个重载版本,所以选择了say(Human)作为调用目标。
对于方法覆盖所表现出来的多态的输出结果,大家并不奇怪,它是在运行期根据实际类型来确定的。
/** * @ClassName Polymorphic * @author derick * @date 2013-5-13 * @Description */ public class PolymorphicTest { public static class Human{ public void say(){ System.out.println("Human say!"); } } public static class Man extends Human{ public void say(){ System.out.println("Man say!"); } } public static class Woman extends Human{ public void say(){ System.out.println("Woman say!"); } } public static void say(Human h){ System.out.println("say Human!"); } public static void say(Man h){ System.out.println("say Man!"); } public static void say(Woman h){ System.out.println("say Woman!"); } public static void main(String[] args) { Human man = new Man(); Human woman = new Woman(); //重载 say(man); say(woman); //覆盖 man.say(); woman.say(); } }
运行结果
say Human!
say Human!
Man say!
Woman say!
从输出结果来看,方法的覆盖和重载表现的不太一致。方法的覆盖安照预期的结果调用了子类的say方法;但方法的重载视乎超预期没有调用相应的子类参数的方法。在方法重载的选择中,为什么会选择形参类型为Human的重载呢?在解决这个问题前,我们先按照如下代码定义两个重要的概念:
Human man = new Man();
我们把上面的代码中“Human”称为变量的静态类型或者外观类型,后面的“Man”则称为变量的实际类型。静态类型编译期可知,实际类型运行时才可确定。
在上面main方法的代码中刻意定义了2个静态类型相同、实际类型不同的变量,但虚拟机(准确地说编译器)在重载时是通过参数的静态类型而不是实际类型作为判定的依据的。并且静态类型是编译期可知的,所以在编译阶段,Javac就根据参数的静态类型决定使用哪个重载版本,所以选择了say(Human)作为调用目标。
对于方法覆盖所表现出来的多态的输出结果,大家并不奇怪,它是在运行期根据实际类型来确定的。
相关文章推荐
- 深入理解Java虚拟机笔记---方法调用http://www.tuicool.com/articles/vQVzIje
- 深入理解Java方法调用的参数传递
- 深入理解Java虚拟机笔记---方法调用
- 深入理解Java的方法调用
- 深入理解java方法调用时的参数传递
- 深入理解Java的方法调用一(值传递和引用传递)
- [深入理解Java虚拟机]第八章 字节码执行引擎-方法调用
- 深入理解Java多态性
- 深入理解Java 中hashcode() 和equals()方法
- 深入理解为什么Java中方法内定义的内部类可以访问方法中的局部变量
- Java方法参数- 值调用的理解
- 深入学习理解java:CompletionService解决ExecutorService的submit方法的缺点
- 深入理解Java多态性(写的太棒了)
- 深入理解java的多态性
- Java中关于Arrays.asList方法的深入学习与理解
- 深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)
- Java 集合深入理解(16):HashMap 主要特点和关键方法源码解读
- 深入理解JVM方法调用的内部机制
- 深入理解为什么Java中方法内定义的内部类可以访问方法中的局部变量(转)
- Java hashCode() 方法深入理解