Java动态特性

Java有三大特性:封装、继承以及多态。很久以前,对于多态这一特性,我所了解的就是由方法的重载、重写所引起的。当一个对象调用一个方法时,我们会产生疑问,程序实际运行时调用的是哪一个方法?调用的是父类中的方法,还是子类本身的方法?如果一个类中有好几个重载方法,那么还涉及到选择调用哪一个重载方法版本。

现在从较深层次来理解Java的多态。

1、静态类型与实际类型

看下面的代码示例:

package xmh0511;

public class Test {

	public static void main(String[] args) {
		Test test = new Test();
		Human man = new Man();
		Human woman = new Woman();
		test.sayHello(man);
		test.sayHello(woman);
	}

	public void sayHello(Human human) {
		System.out.println("I'm a Human");
	}

	public void sayHello(Man man) {
		System.out.println("I'm a man");
	}

	public void sayHello(Woman woman) {
		System.out.println("I'm a woman");
	}

}

class Human {

}

class Man extends Human {

}

class Woman extends Human {

}
 

其中man的静态类型是Human,实际类型是Manwoman的静态类型是Human,实际类型是Woman。静态类型可以说是一个变量的声明类型,实际类型就是对象实例化时的具体类型。

2、重载方法版本的选择探讨

上面代码的执行结果是什么?程序是根据静态类型来匹配重载方法的版本,还是根据对象的实际类型来选择方法执行版本?

上面代码的执行结果是:

I'm a Human

I'm a Human

可见,它是根据静态类型来匹配的,即将实际参数(上面的man对象和woman对象)的静态类型(都是Human类型)与方法的参数类型进行匹配,所以该程序在调用sayHello方法时,选择执行的是sayHello(Human human)方法。

3、再想一个问题:重载方法版本的选择是在什么时候发生的?是在程序编译期(将源程序文件编译成字节码文件),还是在程序运行期(程序已经在虚拟机中处于运行状态)?

事实上,在编译器(如:Sun公司的javac编译器)编译源文件的时候,编译器能够事先确定实际参数的静态类型(如上面代码中,编译器能在编译的时候确定manwoman的静态类型就是Human),在编译成字节码文件的时候,就已经确定了要调用哪一个重载版本。重载方法版本的选择,是在编译期实现的。在字节码文件里,就已经确定了是调用哪一个重载方法。

4、重写方法版本的选择

4.1看下面的代码

public class DynanicTest {
	public static void main(String[] args) {
		DynanicTest dt = new DynanicTest();
		Father father = new Father();
		Father son = new Son();
		father.sayHello();
		son.sayHello();
	}

}

class Father {
	public void sayHello() {
		System.out.println("Father sayHello()");
	}
}
 

能看出,Son类继承了Father类,同时Son重写了父类中的sayHello()方法。

很容易就知道程序的执行结果是:

Father sayHello()

Son sayHello()

分析:

重写方法版本的选择过程大致如下:

首先得到该对象的Class对象,判断该对象的实际类型;

根据该类的继承关系,由下往上寻找与方法名和参数类型匹配的方法;

将这个方法调用的符号引用改为直接引用。

在上面的例子中:son对象调用sayHello()方法,首先从Son类中寻找是否存在sayHello()方法,如果找到了,则执行该方法,否则,到父类或者实现的接口中寻找是否存在sayHello()方法。

重写方法版本的选择是在程序运行时动态确定的,因为事先不知道一个对象的实际类型是什么,只有在程序运行时,才能确定一个对象真实的实际类型。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值