java-多态和动态绑定

耗尽温柔 提交于 2019-12-05 04:00:23

一、什么是多态

  一个对象变量可以指示多种实际类型。当程序运行时,才能确定该变量引用的哪个类的对象,从而虚拟机自动选择调用哪个方法,这也被称为动态绑定。

、理解方法的调用过程

  我们以x.f(args)为例,A x = new B()。

1.编译器查看对象变量的声明类型和方法名

  x声明为A类,编译器将列举A类及其父类中可以被继承的所有名为 f 的方法。由于可能存在重载,名为 f 但参数列表不同的方法可能有多个。

  至此编译器获得了所有可能被调用的候选方法。

2.编译器查看调用该方法时提供的参数列表,进行重载解析

  如果在候选方法中有与提供的参数列表完全匹配的方法,则选择该方法;

  如果没有完全匹配的方法,进行隐式类型转换( 如int可转为double,低精度向高精度转;Son可转为Father,向上转型)可以匹配,则选择该方法。

  如果没有一个方法与提供的参数列表匹配,或转型后有多个匹配,都会报错。

  至此,编译器获得了需要调用的方法名和参数列表。

 

3.当程序运行时,动态绑定调用方法。

  查找x引用的对象的实际类型,这里为B类。

  首先查找x的实际类型B类中有没有具有该参数列表的方法,若有,直接调用该方法。

  否则查找其父类A类中查找,以此类推。

  为了节约开销,虚拟机预先为每个类创建了一个方法表,只需要查找这个方法表即可。

  对于static、private、final方法,可以准确的知道它调用的哪个类,所以采用的是静态绑定。(思考一下为什么)

4.拿段代码感受一下

 

 1 class A {
 2     public String show(D obj){
 3         return ("A and D");
 4     }
 5 
 6     public String show(A obj){
 7         return ("A and A");
 8     }
 9 
10 }
11 
12 class B extends A{
13     public String show(B obj){
14         return ("B and B");
15     }
16 
17     public String show(A obj){
18         return ("B and A");
19     }
20 
21 }
22 
23 class C extends B{}
24 class D extends B{}
25 
26 public class E{
27     public static void main(String [] args){
28         A a1 = new A();
29         A a2 = new B();
30         B b = new B();
31         C c = new C();
32         D d = new D();
33         System.out.println(a1.show(b));   //①
34         System.out.println(a1.show(c));   //②
35         System.out.println(a1.show(d));   //③
36         System.out.println(a2.show(b));   //④
37         System.out.println(a2.show(c));   //⑤
38         System.out.println(a2.show(d));  // ⑥
39         System.out.println(b.show(b));    //⑦
40         System.out.println(b.show(c));    //⑧
41         System.out.println(b.show(d));    //⑨
42     }
43 }

 

 

  这段代码挺有意思,值得好好体会。在网上看到有的朋友写到,多态的三个条件:继承,重写,父类变量引用子类对象,且多态总伴随着动态绑定。我个人体会这是动态绑定的三个条件,多态也不一定会伴随动态绑定,倒是动态绑定一直伴随着多态。

 

 

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!