Java多态、静态绑定、动态绑定

多态

什么是多态呢?
我们知道引用变量是用来操作对象的。
eg:Dog dog = new Dog();
我们创建一个Dog类的对象,用dog这个引用变量来代表它,也可以把引用变量dog叫做对象的名字。
那么!!当引用变量可以引用多种实际类型的对象时,这种现象就叫多态!
什么叫做多种实际类型的对象?
也就是说一个引用变量,它可以引用这个类和该类的所有子类对象!
为什么可以这样的引用呢?
因为子类和父类之间是 ‘is-a’的关系,一个Dog肯定也是Animal,这也就是意味着子类对象可以当做父类对象来使用。
当父类引用变量引用子类对象时,规则就是,沿着继承的层次,从下往上,子类对象可以当做父类对象来使用。
在赋值时、参数传递时会用到。

//Animal类中方法:run()
//Dog类中方法:handshake()
Animal[] an = new Animal[3];
Dog dog = new Dog();
an[0]=dog;//此时会发生自动转换转换
an[0].run();//correct
an[0].handshake();//wrong

也就是此时父类引用变量只能调用父类中有的方法,不能调用父类中没有的方法。

绑定

既然知道了多态,那么引入一个问题:
在java方法调用过程中,JVM是如何知道调用的是哪个类的方法?JVM又是如何操作的?
也就是说,当父类引用变量调用了子类对象的某个方法时,这个方法可能被定义在父类中,也有可能在子类中被重写了。那么究竟应该调用哪个类的方法呢?
那么确定调用哪个方法的操作就叫做绑定!
绑定又分为动态绑定和静态绑定

静态绑定

在Java里,由private、final、static修饰的方法和构造方法都是静态绑定
为什么这么说呢?
因为由private修饰的方法是不能被继承的,因此也不存在子类对象调用该类方法的情况,也就是该类方法不会被重写。
final修饰的方法可以被继承,但是不能被重写。
static方法是类方法,不依赖对象存在。
构造方法也是不能被继承的。
因此,既然一个方法不会被重写,那么所有可能的方法都被定义在一个类中,这些方法只能通过这个类的引用变量来调用,不会涉及具体的实例对象,这种情况就叫做静态绑定,也叫作编译时期绑定。
具体来说,静态绑定就是程序运行之前,就已经知道了该方法所属的类,也就是在编译的过程中,只要到这个类的方法表中拿到这个方法在内存里的地址,就可以执行这个方法了。

静态绑定的特点

静态绑定在编译时期触发,可以提早知道代码的错误,提高代码运行的效率。

动态绑定

以上为静态绑定的过程
那么动态绑定就是程序执行时才能确定具体要调用哪个类的方法。在编译时期,编译器无法找到真正要调用的方法。
具体来说,动态绑定是通过方法表来实现的。当每个类被加载到虚拟机中时,会在方法区保存一个叫做方法表的东西,方法表中存放的是这个类的方法指针,指向具体的方法代码,当子类重写了该类的方法,那么指针会指向新的方法地址。
那么对于动态绑定来说,要等对象创建出来,去堆中根据实际对象所属的类型去搜索其方法表,匹配方法签名。(方法签名包括方法名字、参数数量和类型,不包括返回类型!)
那么父类引用是如何做到不能调用子类中新增方法的呢?
在编译的时候,编译器会根据引用变量的类型,在方法区查找该类型的方法表,这时候如果是子类的新增方法,肯定会编译报错,因为此时方法表中并没有子类的新增方法。

动态绑定(多态)的好处

无需修改现存代码就可以对程序进行扩展

public void method(Animal an){
	an.run();
}

例如说我们现在有一个方法method(),里面的参数是Animal类型的,当Animal类型有需要派生类时,那么我们无需修改代码,就可以让这些派生类对象也可以使用这个方法method()!
也就是说多态可以消除类型之间的耦合关系!Animal类的所有继承类都可以通过这一个统一的入口,也就是method()方法来实现相同的功能。

总结

静态绑定发生在编译时期,如果一个方法不可被继承或者不可被重写,这个方法就是静态绑定。静态绑定使用类信息。方法重载采用的是静态绑定。
动态绑定发生在程序执行时期,多态就是通过动态绑定来实现的!动态绑定使用对象信息。方法重写采用的动态绑定。

参考

https://www.cnblogs.com/xyz-star/p/10152676.html
https://www.cnblogs.com/ygj0930/p/6554103.html
https://www.cnblogs.com/ShaneZhang/p/4972550.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值