JAVA中的多态:
举例:
class A{
public void test(){
System.out.println("this is the A's method");
}
}
class B extends A{
public void test(){
System.out.println("this is the B's method");
}
}
public class TestMulti{
public static void main(String args[]){
A a = new B();
a.test();
}
}
在A a = new B()时用a指向了B对象的引用,在程序运行时调用test()方法时,如果类B中存在这个方法,则调用类B的
test()方法,如果类B中没有这个test()方法,则调用其父类的test()方法.
请问程序在运行时,它是怎么用调用这个方法呢,它是通过java的反射机制去判断吗?首先查询子类中是否有这个方法如果有的话则调用invoke()方法来执行这个方法,如果没有的话,则去父类中去找再调用invoke()方法来执行这个test()方法.还有一个问题:在java多态中有个一概念:上溯造型,请问何为上溯造型?是怎样实现的呢?请问手们帮我详细解释一下~!谢谢了~~!
在线等~!~!
举例:
class A{
public void test(){
System.out.println("this is the A's method");
}
}
class B extends A{
public void test(){
System.out.println("this is the B's method");
}
}
public class TestMulti{
public static void main(String args[]){
A a = new B();
a.test();
}
}
在A a = new B()时用a指向了B对象的引用,在程序运行时调用test()方法时,如果类B中存在这个方法,则调用类B的
test()方法,如果类B中没有这个test()方法,则调用其父类的test()方法.
请问程序在运行时,它是怎么用调用这个方法呢,它是通过java的反射机制去判断吗?首先查询子类中是否有这个方法如果有的话则调用invoke()方法来执行这个方法,如果没有的话,则去父类中去找再调用invoke()方法来执行这个test()方法.还有一个问题:在java多态中有个一概念:上溯造型,请问何为上溯造型?是怎样实现的呢?请问手们帮我详细解释一下~!谢谢了~~!
在线等~!~!
之所以叫作这个名字,除了有一定的历史原因外,也是由于在传统意义上,类继承图的画法是根位于最顶
部,再逐渐向下扩展(当然,可根据自己的习惯用任何方法描绘这种图)。因素,Wind.java的继承图就象
下面这个样子:
由于造型的方向是从衍生类到基础类,箭头朝上,所以通常把它叫作“上溯造型”,即Upcasting。上溯造
型肯定是安全的,因为我们是从一个更特殊的类型到一个更常规的类型。换言之,衍生类是基础类的一个超
集。它可以包含比基础类更多的方法,但它至少包含了基础类的方法。进行上溯造型的时候,类接口可能出
现的唯一一个问题是它可能丢失方法,而不是赢得这些方法。这便是在没有任何明确的造型或者其他特殊标
注的情况下,编译器为什么允许上溯造型的原因所在。
虚拟机会给每一个类创建一个方法列表,在楼主说的例子来说,虚拟机给类A创建了一个方法表如下形式:
A :
test() ---A.test()
hassCode()----Object.hashCode()
.....省略了其他继承自Object的方法列表B
A :
test() ---B.test()
test() ---A.test()
hassCode()----Object.hashCode()
.....省略了其他继承自Object的方法列表以上步骤在类加载器加载完成一个类之后就会在方法栈中保存的信息;
在实际运行的过程中,虚拟机会提取A的实际类型的方法表,也就是B的方法表,寻找test()方法
找到B.test(),因此执行B。test(),但是B中没有定义test()方法或者,则只有找到A.test(),执行A.test()
不要看引用
这个a是B对象,所以就执行B的方法
但是,如果你在方法前面加了static的话,也就是说,方法变成了静态的
那调用的就是父类的方法了,因为静态方法不能被重写,你就这么简单记忆好了
当程序运行的时候,虚拟机总是会优先找A所引用对象的实际类型的那个最合适的方法。所以即使B的方法表中有A.test(),B.test(),还是找优先调用B.test()
a.test();因为父类的test()被重写,所以有限调用了子类里的test().没被重写就调用父类的test().