【JAVA学习】继承中函数调用机制

  类(类的对象)在调用函数时,究竟哪一个函数被调用,是存在特定的机制的,现在我们来梳理下其步骤。

  步骤一:当其调用一个函数的时候,编译器根据其声明的变量类型和调用的函数名字找到所有此“类”和其父类中具有同名的函数

  Class A{     
    public void getName(int a){
    System.out.println("This is Class A and integer is " + a);
    }  
}


Class B extends A{
            
    public void getName(int a){
    System.out.println("This is Class B and integer  is " + a);     
    }   

    public void getName(double a){
    System.out.println("This is Class B and float number is " + a);     
    }  

    public static void main(String[] args){
        B b = new B();
        b.getName(3.14); 
        A a = new B();
        a.getName(3.14); 
    } } 

  首先,根据步骤一,变量b声明的类型为B,其中与b调用函数同名的函数有两个,分别为getName(int a)和 getName(double a),同时A作为B的父类,有一个访问修饰符为public,既子类可以访问且与变量b同名的函数getName(int a)。此时,经过步骤一筛选之后,变量b所调用函数的候选者有如下几个:

A:
getName(int a)

B:
getName(int a)
getName(double a)

  步骤二:编译器根据传入参数类型选择最合适的函数。所以b最合适的函数为public void getName(double a)

  步骤三:值得留意的是,如果此函数前有private , static ,final修饰或者方法是构造函数,根据静态绑定(static binding)原则,根据其显示声明的变量类型可以直接确定所调用的函数。与之相对的是动态绑定(dynamic binding),意思即是当程序运行时,程序会

找到变量指向的实际对象,获取其实际类型。再确定其调用的函数。
  

  一个程序中,一般都会存在大量的函数调用,如果每一次调用都从零开始搜索,无疑会消耗大量的时间。因此,JVM会预先计算出每一个类的函数调用表(method table),如下所示

A:
getName(int ) -> A.getName(int)

B:
getName(int ) -> B.getName(int)
getName(double ) -> B.getName(int)

  此表包含了每一个类可以调用的函数(无论其是自己的函数还是父类的函数,只要调用都需要纳入此表)。当JVM确定了函数实际类型时,按此表用以上步骤进行查找调用。

 

posted @ 2019-08-20 09:30  LinM狂想曲  阅读(472)  评论(0)    收藏  举报