基础知识点-Java的动态绑定与静态绑定(深入理解多态)

一个Java程序的执行要经过编译和执行这两个步骤,同时Java又是面向对象的编程语言。当子类和父类同时存在同一个方法,子类重写父类该方法,程序在运行时调用的方法是调用父类的方法还是子类的重写方法呢。首先我们将确定这种调用何种方法实现或者变量的操作叫做绑定。

方法调用

方法调用过程详细描述如下:

  1. 编译器查看对象的声明类型和方法名。编译器会一一列举这个对象的类中的方法名相同的方法和超类中访问属性为public且方法名相同的方法。
  2. 编译器将查看调用方法时提供的参数类型。如果在所有的方法中存在一个与提供的参数类型完全匹配,就选择该方法,这个过程被称为重载解析。
  3. 如果是private方法,static方法,final方法或者构造器,那么编译器将可以准确地知道应该调用哪个方法(下面有详细讲解)。
  4. 当程序运行时,并且采用动态绑定调用方法时,虚拟机一定调用与该引用对象实际类型最适合类的方法。虚拟机预先为每个类创建了一个方法表,其中列出了所有方法的签名和实际调用的方法。调用方法时,直接查询该表就可以了。

将一个方法调用同一个方法主体关联起来称为绑定。对于Java来说,绑定分为静态绑定和动态绑定,也称为前期绑定和后期绑定。

前期绑定(静态绑定)

若在程序执行前进行绑定(如果有的话,由编译器和连接程序实现),叫做前期绑定。Java当中的方private和法只有final,statci,private和构造方法是前期绑定的。

  • 关于private方法,最重要的一点是不能被继承,因为不能被继承所以不能通过子类的对象进行调用,只能通过这个类本身的对象进行调用,因此说private方法和定义这个方法的类绑定在一起。
  • 关于final方法,虽然可以被继承,但是不能被重写。虽然子类对象可以调用,但是调用的是父类中所定义的final方法。(将方法声明为fina,一方面是防止其他人覆盖该方法,一方面是有效“关闭”动态绑定。)
  • 构造方法是不能被继承的,因此编译时也知道构造方法属于哪个类。
  • 关于static方法,可以被子类继承,但是不能被子类重写(覆盖),可以被子类隐藏。(如果父类中有一个static方法,它的子类中没有对应的方法,那么当子类对象调用这个方法时就会使用父类中的方法。如果子类定义了相同的方法,则会调用子类的方法。唯一不同的是,当子类对象转型为父类对象时,不论子类中有没有定义这个静态方法,都会调用父类中的静态方法。因此说静态方法可以被隐藏而不能被重写。隐藏和覆盖的区别在于,子类对象转为父类对象后,能够访问父类被隐藏的变量和方法,不能访问父类被覆盖的方法)。

如果一个方法不能被继承或继承后不可被覆盖,那么这个方法采用的就是静态绑定。

后期绑定(动态绑定)

在运行时根据对象的类型进行绑定,叫做后期绑定。

如果一种语言想实现后期绑定,就必须具有某种机制,以便在运行时能够判断对象的类型,从而调用恰当的方法。也就是说,编译器一直不知道对象的类型,但是方法调用机制能够找到正确的方法体,并加以调用。

动态绑定的过程:

  • 首先,虚拟机提取对象的实际类型的方法表。
  • 虚拟机搜索方法签名。
  • 虚拟机调用方法。

对于java当中的方法而言,除了final,static,private和构造方法是前期绑定外,其他的方法全部为动态绑定。而动态绑定的典型发生在父类和子类的转换声明之下。

JAVA 虚拟机调用一个类方法时(静态方法),它会基于对象引用的类型(通常在编译时可知)来选择所调用的方法。相反,当虚拟机调用一个实例方法时,它会基于对象实际的类型(只能在运行时得知)来选择所调用的方法,这就是动态绑定,是多态的一种(多态就是指一个对象变量可以指示多种实际类型的现象)Java当中的向上转型或者说多态是借助于动态绑定实现的,所以理解了动态绑定,也就搞定了向上转型和多态。动态绑定为解决实际的业务问题提供了很大的灵活性,是一种非常优美的机制。

属性的绑定

与方法不同,在处理java类中的成员变量(实例变量和类变量)时,并不是采用运行时绑定,而是一般意义上的静态绑定。所以在向上转型的情况下,对象的方法可以找到子类,而对象的属性(成员变量)还是父类的属性(子类对父类成员变量的隐藏)。

子类的对象(由父类的引用handle)调用到的是父类的成员变量。所以必须明确,运行时(动态)绑定针对的范畴只是对象的方法。

 

参考:

https://blog.csdn.net/zhangjk1993/article/details/24066085

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值