Java多态中动态绑定原理解析
作者:天乔巴夏丶 发布时间:2021-08-01 06:39:23
这篇文章主要介绍了Java多态中动态绑定原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
多态是面向对象程序设计非常重要的特性,它让程序拥有 更好的可读性和可扩展性。
发生在继承关系中。
需要子类重写父类的方法。
父类类型的引用指向子类类型的对象。
自始至终,多态都是对于方法而言,对于类中的成员变量,没有多态的说法。
一个基类的引用变量接收不同子类的对象将会调用子类对应的方法,这其实就是动态绑定的过程。在理解动态绑定之前,先补充一些概念。
引用变量的类型
引用类型的变量具有两种类型:编译时类型和运行时类型。(也分别叫做声明类型和实际类型)举个简单的例子:
//假设Student类是Person类的子类
Person p = new Student();
编译时类型
也叫声明类型,即由声明变量时的类型所决定。
上式的Person即为引用变量p的编译时类型。
运行时类型
也叫实际类型,即由指向对象的实际类型所决定。
上式的Student即为引用变量p的运行时类型。
方法绑定
将方法调用同方法主体关联起来被称为绑定。
静态绑定
在程序执行前进行绑定,叫做静态绑定,也称作前期绑定。在面向过程的语言中是默认的绑定方式。
在Java中,用private、static和final修饰的方法(static和final之后会做出总结)或构造器能够准确地让编译器调用哪个方法,就是静态绑定(static binding)。
动态绑定
在运行时根据对象的运行时类型进行绑定,叫做动态绑定,也叫做后期绑定。当然在Java中,除了静态绑定的那些方法,其他方法的调用方式就是动态绑定啦。
public class DynamicBinding {
//Object是所有类的超类,根据向上转型,该方法可以接受任何类型的对象
public static void test(Object x) {
System.out.println(x.toString());
}
public static void main(String[] args) {
test(new PrimaryStudent());//Student
test(new Student());//Student
test(new Person());//Person
test(new Object());//java.lang.Object@1b6d3586
}
}
class Person extends Object {
@Override
public String toString() {
return "Person";
}
public void run(){}
public void count(int a){}
}
class Student extends Person {
@Override
public String toString() {
return "Student";
}
public void jump(){}
}
class PrimaryStudent extends Student {
}
四句调用方法的语句中的形参,编译时类型都是Object。注意:引用变量只能调用编译时类型所具有的方法。
它们运行时类型各不相同,所以解释运行器在运行时,会调用它们各自类型中重写的方法。
相同的类型的引用变量,在调用同一个方法时,表现出不同的行为特征,这就是多态最直观的体现吧。
方法表
我们还可以发现,test(new PrimaryStudent());的运行结果是Student,,结果很明显,因为PrimaryStudent类中并没有重写父类的方法,如果采用动态绑定的方式调用方法,虚拟机会首先在本类中寻找适合的方法,如果没有,会一直向父类寻找,直到找到为止。
那么,每次调用时都要向上寻找,时间开销必然会很大。为此虚拟机预先为每个类都创建了方法表,其中列出了所有的方法签名(返回值类型不算)和实际调用的方法,这样子的话,在调用方法时直接查表就可以了。(值得一提的是,如果用super限定调用父类方法,那么将直接在实际类型的父类的表中查找)
下面是Person类的方法表:
Person:
//下面省略Object方法签名
//xxx()-> Object.xxx()
//方法签名->实际调用的方法
toString()->Person.toString()
run()->Person.run()
count(int)->Person(int)
下面是Student类的方法表:
Student:
//下面省略Object方法签名
//xxx()-> Object.xxx()
//方法签名->实际调用的方法
toString()->Student.toString()
jump()->Student.jump()
run()->Person.run()
count(int)->Person(int)
下面是PrimaryStudent类的方法表(PrimaryStudent类为空,直接继承Student类):
PrimaryStudentt:
//下面省略Object方法签名
//xxx()-> Object.xxx()
//方法签名->实际调用的方法
toString()->Student.toString()
jump()->Student.jump()
run()->Person.run()
count(int)->Person(int)
因此,在执行test(new PrimaryStudent());语句时,虚拟机将会提取PrimaryStudent的方法表。
虚拟机将会在表中搜索定义toString签名的类。这时虚拟机已经知道需要调用Student类型的toString()方法。
最后,调用方法,完毕。
动态绑定大大提升了程序的可扩展性,比如,我现在要新增一个Teacher类,可以直接让Teacher类继承于Person类,再用
Object类的引用指向Teacher对象,而不用做其他的代码调整,动态绑定自动搞定,就相当舒服。
来源:https://www.cnblogs.com/summerday152/p/12049565.html
猜你喜欢
- 简要:EigenFace是基于PCA降维的人脸识别算法,PCA是使整体数据降维后的方差最大,没有考虑降维后类间的变化。 它是将图像
- 在某些业务场景中,我们只需要业务代码中定义相应的接口或者相应的注解,并不需要实现对应的逻辑。比如 mybatis和feign: 在 myba
- 本文实例讲述了Java定义泛型方法。分享给大家供大家参考,具体如下:一 点睛1 如果定义类、接口是没有使用类型形参,但定义方法时想自己定义类
- a)原理:每一趟从待排序的记录中选出最小的元素,顺序放在已排好序的序列最后,直到全部记录排序完毕。也就是:每一趟在n-i+1(i=1,2,…
- 前言好久没有更新博客了,今天和大家分享一个关于emoji表情持久化问题,相信做web开发的都遇到过这样的问题,因为我们知道mysql的utf
- java的jar是一个打包工具,用于将我们编译后的class文件打包起来,这里面主要是举一个例子用来说明这个工具的使用。在C盘下的temp文
- IntelliJ IDEA是广受Java开发者喜爱的工具,其商业版的价格十分昂贵,如下图:现在有机会免费获取IntelliJ IDEA的正版
- Controller @RequestMapping作用@RequestMapping是一个用来处理请求地址映射的注解,可用于类或者方法上。
- 前言这篇博客介绍Java环境的配置,主要是安装JDK,以及path、JAVA_hOME、CLASSPAT的配置,还会介绍配置这些的原因。一.
- 1. 父工程构建1.1 Maven项目搭建环境版本JDK1.8Maven3.6+Maven模板maven-archetype-size删除父
- 本文实例讲述了Java实现的不同图片居中剪裁生成同一尺寸缩略图功能。分享给大家供大家参考,具体如下:因为业务需要,写了这样一个简单类,希望能
- 前言现在是移动端产品疯狂的年代,随之,移动端支付也是热门小技能,最近本公司在做一个移动端,要接入微信支付和支付宝支付, * 惯,功能做完之后做
- 概况本文主要给大家介绍了通过JDK源码学习InputStream的相关内容,JDK 给我们提供了很多实用的输入流 xxxInputStrea
- Java中线程分为两种类型:用户线程和守护(服务)线程。通过Thread.setDaemon(false)设置为用户线程;通过Thread.
- 1.比较两个字符串时使用“==”还是equals()方法?当然是equals方法。“==”测试的是两个对象的引用是否相同,而equals()
- HttpServletRequest介绍HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HT
- 说明:本文记录如何在Idea下,利用Maven管理项目,并整合SSM(Spring + Spring MVC +Mybatis)框架,实现简
- IDEA创建一个传统JAVA WEB项目(不使用maven构建)方法一File --> NEW --> Project --&g
- Failed to execute goal org.apache.maven.plugins:maven-resources-plugin
- LeetCode54. 螺旋矩阵 java实现题目难度 中给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,