码迷,mamicode.com
首页 > 其他好文 > 详细

函数绑定

时间:2019-10-19 13:25:39      阅读:108      评论:0      收藏:0      [点我收藏+]

标签:重载   nal   show   运行   dash   成员变量   文件   常量   工程   

一,函数绑定

         函数绑定分为动态绑定和静态绑定。(绑定指的是调用)

    当写完代码后,可使用javap  -c  java文件.class,来查看java编译器为我们生成的字节码。(反汇编过程)

    具体操作:1,先在程序编辑界面,右击鼠标,然后选择 show in Explorer 就会将该代码生成的文件所在

                       目录呈现出来。

                      2,点击地址栏中的工程名,找到 out文件,打开并找工程名。

      3,找到该类的字节码文件,将地址栏中的地址删除,输入cmd回车,就会出现命令编辑器。

                      4,输入   Javap -c 文件名.class   回车就会出现字节码文件。

               技术图片

 

    在这段字节码中,第6行invokespecia指令代表调用构造函数

                                第10行invokestatic指令就是在以静态绑定的方法,调用函数

                                第14行 invokevirtual指令就是在以动态绑定的方法,调用函数

  ♥ static方法都是静态绑定调用,实例方法都是动态绑定调用

   ♥ 静态绑定,指的是编译时期的绑定,编译阶段,这个方法的调用就是确定好的,永不不会再改变

 

      动态绑定,指的是运行时期的绑定,就是在编译阶段,此处调用哪个函数,是不确定的。

 

 

 1 class A{
 2     protected int a;
 3     private String str;
 4     private Integer data;
 5 
 6     public A(int val){        //构造函数
 7         System.out.println("A()");
 8         this.a = val;
 9     }
10 
11     public static void show(){     //静态方法
12         System.out.println("static A.show");
13     }
14 
15        public void func(){        //实例方法 
16         System.out.println("instance A.func");
17     }
18     //此方法是对上面方法的重载
19     public void func(int data){    //因为方法名相同,返回类型相同,仅参数列表不同
20         System.out.println("instance A.func data");
21     }
22 }
23 
24 class B extends A{
25 
26     public B(int val) {
27         super(val);
28     }
29 
30     public static void show(){
31         System.out.println("static B.show");
32     }
33 
34     // 就构成重写(覆盖)的关系
35     public void func(){     //返回值类型,方法名,参数列表相同,仅作用域不同
36         System.out.println("instance B.func");
37     }
38 }
39 
40 
41 
42 public class 函数绑定 {
43     public static void main(String[] args) {
44         //B b = new B(20); // invokespecial 构造函数
45         //B.show(); // invokestatic 静态方法
46         //b.func(); // invokevirtual 实例方法
47         A a = new B(20);
48         A.show(); // 静态绑定A.show
49         a.func(); //  动态绑定A.func   instance B.func
50     }

 运行结果:

  技术图片

 

代码分析:

     第一行是因为在新new一个对象时,JVM会自动调用该对象的构造函数。

     第二行 A.show( )为静态绑定,在编译阶段,就确定好了调用那个方法,所以此处运行后,哪个类调用方法,就直接调用哪个类的静态方法show( )。

     第三行 a.func( )为动态绑定,在运行时才能确定调用哪个方法。A a = new B(20);此句是说新定义了一个A型变量a,然后又新new了一个B型对象,

    并将该对象的引用赋给变量a,而此处a.func( )运行后,机器识别出func()方法为动态方法,需要动态绑定,然后通过 a 找到在栈上的对象B,

    然后通过对象B的地址末尾的方法表地址又找到B类型的方法表,在里面查找,发现 在B类中继承的A类 中的func() 方法的地址已被重写。所以

    此时访问到的func( )方法就是被B类重写后的方法。所以打印出来就是B类中的。

 技术图片

 

 

 

注意

1.

———————图一———————————————————————————————

技术图片   

 

 ———————图二———————————————————————————————

技术图片

 

—————————————————————————————————————— 

   图一说明:基类引用可以引用派生类对象

   图二说明:派生类引用不能引用基类对象

(形象理解:将人类比作基类,将教授比作派生类,A a = new B(20);说明此处需要一个人,所以将教授派去完全可以。

                   B b = new A(20);而这句报错是因为,此处需要一个教授,而你给的是一个人,这个人可能只是一个学生,

     并不能满足需求。)

 

 

2.把基类和派生类的继承结构,也经常称作从上到下的继承结构继承结构中的类型,只支持从下到上的转换,

   不支持从上到下的转换。(也就是说派生类[教授]可以转换为基类[人],但基类[人]不一定能转换成派生类[教授]。)

 扩充:

        1, final的应用场景有三个:

               1.final int data = 10; 可以用来定义常量

               2.final可以修饰类称作密封类,不能再被继承

       3.final可以修饰类的实例方法,称作密封方法,表示该方法不能再派生类中重写(覆盖)

 

        2,继承结构中,基类和派生类的方法通常有两种关系:重载和重写

            重载:在一个类作用域中,函数名相同,参数列表不同

            重写:作用域不同,在基类和派生类中,返回值相同,函数名相同,参数列表也相同

                  ( 重写指的是派生类方法表中,派生类提供的重写方法,把基类相应的方法的地址给重写了(覆盖了))

        3,当父类中的成员变量的访问权限为private时,说明子类不能访问该变量,但此时该变量仍会被子类继承

       下来,只是不能访问它。对于被继承下来的方法和变量,可直接用     对象 . 方法  或 对象 . 变量  来掉用。

函数绑定

标签:重载   nal   show   运行   dash   成员变量   文件   常量   工程   

原文地址:https://www.cnblogs.com/ljl150/p/11694429.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!