今天学了多态,对这个概念一直不是很懂,于是上网翻阅各种资料,最后终于有了点小研究,现将自己的理解列出如下:
/**
详细解析Java的多态机制
*多态:在Java中的解释就是同一个对象有不同的表现形式,一般都是应用在超类引用指向子类对象.如 Father f = new Son();
*java 中实现多态的原因是因为Java程序在调用方法时默认的是动态绑定(也称为 Run - time binding运行时绑定),即除非显示
的规定方法的修饰符为static ,final,pravite时会采用静态绑定;
*Java多态的实现依赖的是在类加载进方法区中就存在的方法表(Method Table),多态的具体实现流程:是当一个程序调用某个
方法时,jvm会先在常量池索引中找到该方法的符号引用,然后通过这个符号引用查找调用这个方法的类引用的方法表来确定
偏移量(offset),然后通过this得到这个方法的直接调用者,最后在这个直接调用者的Method Table中通过刚刚的偏移量找到该
方法的地址,通过该地址将方法的代码压入栈执行
*/
class Father {
public void show() {
System.out.println("我是父类");
}
}
class Son extends Father {
public void show() {
System.out.println("我是子类");
}
}
class test {
public static void main(String[] args) {
Father f = new Son();
f.show();
}
}
/*
在这个例子中,我们知道最后的结果是输出"我是子类";现在我们先假设f.show()在test常量池索引的
索引为#1(这个便可以认为是该方法的符号索引),那jvm就会先通过这个索引查看常量池,然后找到要
调用的方法是Father的show()方法,那接下来虚拟机就会去Father的Method Table查看得到这个方法在
方法表中的偏移量;而当jvm执行真正的方法时候,invokevirtual调用的参数是this(这个关键字指向的是
当前实例对象),那jvm就会到这个实例对象的类(也就是Son)的方法表中根据偏移量找到这个方法的真
正代码而执行.从而解释了为什么编译看左边(那是因为先要通过类引用找到这个方法的偏移量),运行
看右边(因为this参数指向的当前实例对象的引用)
*/
|
|