您的位置:首页 > 编程语言 > Java开发

深入理解Java的方法调用二(多态性)

2013-05-13 08:18 295 查看
Java的多态性表现在2个方面,1方法的覆盖、2方法的重载。

/**
* @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)作为调用目标。

对于方法覆盖所表现出来的多态的输出结果,大家并不奇怪,它是在运行期根据实际类型来确定的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: