Java动静态绑定(与C/C++的区别)

引言

在处理类型的层次结构时,经常想把一个对象不当作它所属的特定类型来对待,而是将其当作其基类的对象来对待。这使得人们可以编写出不依赖于特定类型的代码。在“几何形”的例子中,方法操作的都是泛化(generic)的形状,而不关心它们是圆形、正方形、三角形还是其他什么尚未定义的形状。所有的几何形状都可以被绘制、擦除和移动,所以这些方法都是直接对一个几何形对象发送消息;它们不用担心对象将如何处理消息。

但是编译器无法了解哪一段代码将会被执行,那么它该怎么办呢?

绑定的概念:

  1. 程序绑定是指一个方法的调用与方法所在的类(方法主体)关联起来。

  2. 静态绑定:在程序执行前已经被绑定,此时由编译器或其它连接程序实现。
    动态绑定:在运行时根据具体对象的类型进行绑定。

答案

这个问题的答案,也是面向对象程序设计的最重要的妙诀:编译器不可能产生传统意义上的函数调用。 非面向对象编程(如C语言)的编译器产生的函数调用会引起静态绑定,

这么做意味着编译器将产生对一个具体函数名字的调用,而运行时将这个调用解析到将要被执行的代码的绝对地址。

然而在OOP中,程序直到运行时在知道确定代码的位置,所以当消息发送给一个泛化对象时,必须采用其他机制——动态绑定

为执行动态绑定,面向对象程序设计语言(Java)使用一小段特殊的代码来替代绝对地址的调用。这段代码使用在对象中存储的信息来计算方法提的地址。当对象发送消息时,被调用的代码直到运行时才能确定。编译器确保被调用方法的存在,并对调用参数和返回值执行类型检查(无法提供此类保证的语言被称为时弱类型的),但是并不知道被执行的确切代码。

Java与C++关于这点的区别在于:
Java中final,static,private和构造方法都是静态绑定的特殊案例,而在c++中必须明确地声明某个方法具备后期绑定属性所带来的灵活性(即用virtual关键字)。相比于c++,Java中动态绑定是默认行为,不需要添加额外的关键字来实现多态。

关于final,static,private和构造方法是前期绑定的理解

针对static方法和final方法,并不是因其不能被继承,而是由于其不能被子类覆盖重写,因此在编译时就可以确定他们的值,他们是属于静态绑定的,而private声明的方法和成员变量由于不能被子类继承,并且隐式继承final,所以也是静态绑定的,构造方法实际上也是静态方法。

由上面我们可以得出结论,如果一个方法不可被继承或者继承后不可被覆盖,那么这个方法就采用的静态绑定。

补充:static方法可以被子类继承,但是不能被子类重写(覆盖),可以被子类隐藏。(这里意思是当子类对象上转型为父类对象时,不论子类中有没有定义这个静态方法,该对象都会使用父类中的静态方法。因此这里说static方法可以被隐藏而不能被覆盖。这与子类隐藏父类中的成员变量是一样的。隐藏和覆盖的区别在于,子类对象转换成父类对象后,能够访问父类被隐藏的变量和方法,而不能访问父类被覆盖的方法
final方法虽然可以被继承,但不能被重写(覆盖),虽然子类对象可以调用,但是调用的都是父类中所定义的那个final方法,(由此我们可以知道将方法声明为final类型,一是为了防止方法被覆盖,二是为了有效地关闭java中的动态绑定)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拥抱白熊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值