Java JVM 多态(动态绑定)
Java JVM 多态(动态绑定)
@author ixenos
摘要:绑定、动态绑定实现多态、多态的缺陷、纯继承与扩展接口、向下转型与RTTI
绑定
将一个方法的调用和一个方法的主体关联起来,称作(方法调用)绑定:
1.前期绑定:在程序执行前绑定(由编译器和连接程序实现);
2.后期绑定:在运行时根据对象的类型绑定(也称动态绑定或运行时绑定);
a) 实现条件:能在运行时判断对象的类型,从而关联对应主体,调用其方法
b) 编译器一直不知道真实对象类型,只将其认作引用变量的类型且知道有继承关系
c) Java中除了static方法和final方法(private方法相当于final方法)是前期绑定之外,其他所有的方法都是后期绑定
动态绑定实现多态
多态作用:
1.消除类型之间的耦合关系,使我们可以编写只与基类打交道的程序代码了(比如List<String> = new ArrayList<>();)
2.使程序有可扩展性,我们可从通用的基类继承出新的数据类型从而添加新的功能,而不需要改变对应接受参数的方法,只与基类接口通信
动态绑定:
1. 假设B extends A,若使A = new B()向上转型,则编译器认为这是合理的协变,编译通过!但此时编译器只知道B是A的子类,无法得知B的具体类型!
2. 运行时,Java的后期绑定机制判定该对象new B()的运行时类型为B,所以方法的调用策略是从B类中调用相应方法(static、final方法除外)
3. 动态绑定(后期绑定或运行时绑定)常被指称为多态
多态的缺陷
“覆盖”私有方法时:
public class Pri{
private void f(){ System.out.println("I'm private f()"); } public static void main(String[] args){
Pri pri = new Pub(); //向上转型,动态调用Pub类方法
pri.f();
}
} class Pub{
public void f(){ System.out.println("I'm public f()"); }
} ----------------------------------
输出: I'm private f()
我们期望输出是public f(),但private方法被认为是final方法,属于前期绑定,这对导出类(子类)是屏蔽的,因此没有重写!只是重载了但我们不知道
此时,Pub类中的f()方法就是一个全新的方法,两个方法存在不同类中
结论:虽然只有非private方法可以覆盖,但也要注意这种试图覆盖private方法的行为,毕竟编译器不会报错(因为根本就是创建一个新的方法)导致方法不按照初衷来执行
不适用多态的范围:域、静态方法与final方法
只有普通方法的调用可以是多态的
域:当Sub对象转型为Super引用时,任何域访问操作都由编译器解析,因此不是多态的;
而此时将为Super.field和Sub.field分配不同存储空间,此时Sub包含两个域,他自己的和从super得到的;
若Super.field是private的,那么Sub是看不到的;
若Super.field是public且子类域覆盖了父类域,Sub的默认域就是子类域,要调用父类域要用super.field(field替换为父类域引用变量)
静态方法:静态方法是与类相关联的而不是与对象
final方法:final阻止子类重写,但可重载
纯继承与扩展接口
纯继承:
导出类只覆盖基类的方法,导出类只具有和基类相同的接口,此时导出类可以完全代替基类,基类可以接受发送给导出类的任何信息,我们只需要从导出类向上转型,永远不需要知道正在处理的对象的确切类型,这是通过多态(动态绑定)处理的
Shape{
draw(){}
erase(){}
} Circle extends Shape{
draw(){}
erase(){}
} Square extends Shape{
draw(){}
erase(){}
} Triangle extends Shape{
draw(){}
erase(){}
}
扩展接口:
扩展导出类的功能,但是,导出类中接口的扩展部分不能被基类访问,因此,一旦扩展接口的导出类对象向上转型,就不能调用那些新方法
Useful{
draw(){}
erase(){}
} MoreUseful extends Useful{
draw(){}
erase(){} //扩展接口
freak(){}
flyme(){}
}
向下转型与RTTI
向上转型:
向上转型是安全的,因为基类不会具有大于导出类的接口
向下转型:
向下转型是不安全的,由“运行时类型识别”RTTI(Run-Time Type Identification)来确保向下转型正确性
Useful{
draw(){}
erase(){}
} MoreUseful extends Useful{
draw(){}
erase(){} //扩展接口
freak(){}
flyme(){}
} public class RTTI{
public static void mian(String[] args){
Useful[] x = { new Useful() , new MoreUseful() }; // ((MoreUseful)x[0]).freak(); //ERROR 向下转型失败,因为x[0]对象不具有MoreUseful类中的扩展接口 ((MoreUseful)x[1]).freak(); //向下转型成功/RTTI
RTTI行为示例
一个基类引用的对象,如果想访问特定导出类对象的扩展接口,就可以尝试向下转型,但是该基类对象本身必须是导出类类型或者其子类型,才能转型成功
Java JVM 多态(动态绑定)的更多相关文章
- [转帖]java基础学习总结——多态(动态绑定)
https://www.cnblogs.com/xdp-gacl/p/3644035.html 多态的概念 java基础学习总结——多态(动态绑定) 一.面向对象最核心的机制——动态绑定,也叫多态
- Java静态绑定与动态绑定
程序绑定的概念: 绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来.对java来说,绑定分为静态绑定和动态绑定:或者叫做前期绑定和后期绑定. 静态绑定: 在程序执行前方法已经被绑定(也就是说 ...
- Java静态绑定和动态绑定
程序绑定的概念: 绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来.对java来说,绑定分为静态绑定和动态绑定:或者叫做前期绑定和后期绑定 静态绑定(早绑定 编译器绑定): 在程序执行前方法 ...
- 关于java中多态的理解
java三大特性:封装,继承,多态. 多态是java的非常重要的一个特性: 那么问题来了:什么是多态呢? 定义:指允许不同类的对象对同一消息做出响应.即同一消息可以根据发送对象的不同而采用多种不同的行 ...
- 个人对Java中多态的一些简单理解
什么是多态 面向对象的三大特性:封装.继承.多态.从一定角度来看,封装和继承几乎都是为多态而准备的.这是我们最后一个概念,也是最重要的知识点. 多态的定义:指允许不同类的对象对同一消息做出响应.即同一 ...
- Java中多态的一些简单理解
什么是多态 .面向对象的三大特性:封装.继承.多态.从一定角度来看,封装和继承几乎都是为多态而准备的.这是我们最后一个概念,也是最重要的知识点. .多态的定义:指允许不同类的对象对同一消息做出响应.即 ...
- Java(15) 多态
一.多态 1.1 多态:一个事物的多种形态 1.2 多态的表现 行为(方法)多态:重写和重载. 引用多态(动态绑定):编译时的类型和运行时不一致的这种现象 例:父类 = 子类 Pet p = ne ...
- 从虚拟机指令执行的角度分析JAVA中多态的实现原理
从虚拟机指令执行的角度分析JAVA中多态的实现原理 前几天突然被一个"家伙"问了几个问题,其中一个是:JAVA中的多态的实现原理是什么? 我一想,这肯定不是从语法的角度来阐释多态吧 ...
- JAVA & C++ 多态
多态,也叫动态绑定. Java: class A { public void f1() { System.out.println("A:f1"); } public void f2 ...
随机推荐
- js实现购买数量加减效果
写在前面:当我们需要在多个页面都有操作数量的需求时的一种解决方案 结构: js代码: <script type="text/javascript"> function ...
- [一波低姿势的usaco除草记]
总共花了一个月左右 把一份usaco的总结刷了一遍 应该有一百四十多道题 在此纪念一下 总体来说 发现自己基础不是很稳 基本贪心和一些堆的做法还是有点弱鸡 一些dp还是有点弱 但是数据结构题几乎都可以 ...
- Java 并发 线程同步
Java 并发 线程同步 @author ixenos 同步 1.异步线程本身包含了执行时需要的数据和方法,不需要外部提供的资源和方法,在执行时也不关心与其并发执行的其他线程的状态和行为 2.然而,大 ...
- thinkphp判断是否为手机
一.问题: 近日准备给自己的网站做一个小升级,让用户在手机二维码扫描的时候显示适合手机端来展示的模版[我用的是ThinkPHP3.0],代码是参考别人的 二.实现方法: 这里先说下大概的一个思路 简单 ...
- PhpMyAdmin隐藏数据库设置同前缀失效的问题
用PhpMyAdmin默认会把所有数据库都显示出来,一些如 MySQL,information_schema之类的也会显示,这样既不安全看着也不爽,隐藏掉最好. 修改 config.inc.php 或 ...
- IOS常遇问题个人收藏网址指南
代码适配Masonry使用的详细介绍: http://blog.csdn.net/majiakun1/article/details/51160339 Masonry使用注意篇: http://www ...
- 关于Trie Tree简单实现
最近突然有兴致hiho一下了,实现了下trie tree,感觉而言,还是挺有意思的,个人觉得这货不光可以用来查单词吧,其实也可以用来替代Hash,反正查找,插入复杂度都挺低的,哈哈,啥都不懂,瞎扯.. ...
- @classmethod及@staticmethod方法浅析【python】
目前对于python中@classmethod 类方法和@staticmethod静态方法的有了一定的认识,之后有进一步的认识后继续记录. @classmethod :是和一个class类相关的方法, ...
- Cocoapod安装使用和常见问题(转载)
1.cocoapod的按照,cocoapod是运行在ruby环境下的,在ruby环境的 ,像cocoapod这样的开源项目时放在放在rubygems服务器上面的,但国内访问https://ruby ...
- PowerCmd(命令行增强工具) 2.2 免费版
软件名称: PowerCmd(命令行增强工具) 2.2 免费版 软件语言: 英文 授权方式: 免费软件 运行环境: Win7 / Vista / Win2003 / WinXP 软件大小: 1.8MB ...