什么是多态,JAVA 中多态的实现机制
什么是多态,JAVA 中多态的实现机制
首先声明啊,这里的多态不是生物学和物理学上的多态性,这个是指编程语言中的多态。
官方说明:
- 多态(英语:polymorphism)指为不同数据类型的实体提供统一的接口.
- 多态是允许你将父对象设置成为一个或更多的他的子对象相等的技术。
- 我们在程序中定义的引用变量所指向的具体类型和通过该引用变量的方法调用在编程的时候并不确定,当处于运行期间才确定。就是这个引用变量究竟指向哪一个实例对象,在编译期间是不确定的,只有运行期才能确定,这样不用修改源码就可以把变量绑定到不同的类实例上,让程序拥有了多个运行状态,这就是多态。
看完是不是很懵逼?
说人话就是:
允许将子类类型的指针赋值给父类类型的指针,把不同的子类对象都当作父类来看。就比如你在一个京剧世家,有人邀请你们家出个人来唱一出戏,邀请函上写的是你父亲的名字,但很不凑巧你父亲病了,你只能穿上你父亲的戏服,装作你父亲去登台唱戏。台下的人只知道是你们家的人登台,可能你父亲,也可能是你家人代替你父亲。你为了不被发现是代替你父亲,你就要隐藏起来其他技能。这就是多态。
多态又分为 编译时多态和运行时多态:
- 编译时多态(静态):重载
- 运行时多态(动态):重写
演示代码如下:
public class Father { //父类void sing (){System.out.println("我是爸爸,我会唱京剧" + "\n");}
}class Son extends Father{ //子类,继承父类void sing (){System.out.println("我是儿子,我会唱京剧" + "\n");}void kungFu (){System.out.println("我是儿子,我会武术" + "\n");}
}class test{ //测试类public static void main(String[] args) {Father father = new Son(); //多态的表现father.sing();}
}
在使用 “father.” 调用方法时能发现,弹出的方法里根本没有Son类的kungFu方法:
运行结果如下:
儿子:嘻嘻,没被发现,装父亲成功了!
扩展
1.多态的实现机制
术语版本:
我们将引入Java静态分派和动态分派这个概念。
- 静态分派:所有依赖静态类型来定位方法执行版本的分派动作。静态分派发生在编译阶段,因此确定静态分派的动作实际上不是由虚拟机来执行的,而是由编译器来完成。(编译时多态)
- 动态分派:在运行期根据实际类型确定方法执行版本的分派动作。(运行时多态)
简单版本:
原理也很简单,父类或者接口定义的引用变量可以指向子类或者具体实现类的实例对象,由于程序调用方法是在运行期才动态绑定的,那么引用变量所指向的具体实例对象在运行期才确定。所以这个对象的方法是运行期正在内存运行的这个对象的方法而不是引用变量的类型中定义的方法。
如果想深入的同学可以参考可以参考《深入理解Java虚拟机》。
2.里氏代换原则
里氏代换原则(LSP): 子类对象能够替换父类对象,而程序逻辑不变。
里氏替换原则有至少以下两种含义:
- 里氏替换原则是针对继承而言的,如果继承是为了实现代码重用,也就是为了共享方法,那么共享的父类方法就应该保持不变,不能被子类重新定义。子类只能通过新添加方法来扩展功能,父类和子类都可以实例化,而子类继承的方法和父类是一样的,父类调用方法的地方,子类也可以调用同一个继承得来的,逻辑和父类一致的方法,这时用子类对象将父类对象替换掉时,当然逻辑一致,相安无事。
- 如果继承的目的是为了多态,而多态的前提就是子类覆盖并重新定义父类的方法,为了符合LSP,我们应该将父类定义为抽象类,并定义抽象方法,让子类重新定义这些方法,当父类是抽象类时,父类就是不能实例化,所以也不存在可实例化的父类对象在程序里。也就不存在子类替换父类实例(根本不存在父类实例了)时逻辑不一致的可能。不符合LSP的最常见的情况是,父类和子类都是可实例化的非抽象类,且父类的方法被子类重新定义,这一类的实现继承会造成父类和子类间的强耦合,也就是实际上并不相关的属性和方法牵强附会在一起,不利于程序扩展和维护。
如何符合LSP?总结一句话 —— 就是尽量不要从可实例化的父类中继承,而是要使用基于抽象类和接口的继承。
如有问题欢迎指正
参考:
https://blog.csdn.net/sunxianghuang/article/details/52280002
https://www.zhihu.com/question/27191817/answer/145013324
什么是多态,JAVA 中多态的实现机制相关推荐
- Java中 多态的理解
** Java中 多态的理解 ** 多态官方定义为: 所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指 ...
- 深入Java核心 Java中多态的实现机制(1)
在疯狂java中,多态是这样解释的: 多态:相同类型的变量,调用同一个方法时,呈现出多中不同的行为特征, 这就是多态. 加上下面的解释:(多态四小类:强制的,重载的,参数的和包含的) 同时, 还用人这 ...
- java中多态_java之多态
1.多态的概述:是面向对象的三大特性之一,封装.继承.多态. ①一个具体的对象有多种形态,老虎既属于猫科动物(因为子父类是相对的,所以猫科动物也可以看做子类),又属于哺乳动物,所以老虎既可以拥有猫科动 ...
- JAVA中多态的理解
Java中多态的理解 JAVA中的多态可以简单的理解为一种事物的多种形态,当然多态是在继承的基础上有重写才存在. 标题如何理解一种事物的多种形态? 举个例子,拿人类.男人.女人来说.男人.女人.都分别 ...
- Java中多态的使用
1.面向对象的三大特性:封装.继承.多态.从一定角度来看,封装和继承几乎都是为多态而准备的.这是我们最后一个概念,也是最重要的知识点. 2.多态的定义:指允许不同类的对象对同一消息做出响应.即同一消息 ...
- Java中的等待/通知机制(wait/notify)
为什么80%的码农都做不了架构师?>>> 当一个线程修改了一个对象的值,另外一个线程需要感知到这个变化,并且做出相应的操作时,可以使用Java中的等待/通知机制去实现这个功能. ...
- Java中事件监听机制
Java中事件监听机制 一.事件监听机制的定义 要想了解Java中的事件监听机制,首先就要去了解一下在Java中事件是怎样去定义的呢!在使用Java编写好一个界面后,我们就会对界面进行一些操作,比如, ...
- Java中如何实现代理机制(JDK、CGLIB)
代理分为两种: 1.静态代理 2.动态代理 动态代理又分为两种:jdk 实现 :Cglib 实现 3.Java中如何实现代理机制(JDK.CGLIB) JDK动态代理:代理类和目标类实现了共同的接 ...
- Java基础-Java中常用的锁机制与使用
Java基础-Java中常用的锁机制与使用 锁lock或互斥mutex是一种同步机制,主要用于在存在多线程的环境中强制对资源进行访问限制.锁的主要作用为强制实施互斥排他以及并发控制策略.锁一般需要硬件 ...
最新文章
- 深度有趣 | 27 服饰关键点定位
- 计算机网络中的拓扑结构教案,计算机网络拓扑结构教案
- 数据结构源码笔记(C语言):二叉平衡树的相关操作算法
- 超图桌面版开发入门图解
- 集成学习(ensemble learning)(二)
- Win10下使用HDFView查看hdf5文件
- java的编译器怎么出来_怎样掌握ava编译器的使用,教程在这里,如何进行Java初级学习...
- 各平台安装Node.js
- 菜鸟的学习之路(10) — LinkedList类
- Eclipse发布Web项目
- [OHOS ERROR] clang not found, install it please
- jsp内置对象request
- Linux Redh9 下LumaQQ 2005的安装
- 微信群二维码活码生成管理系统源码
- php计算macd,macd计算公式?MACD指标的原理是什么
- 听比喻,懂原理(1)超五类双绞线和六类双绞线的区别
- 华为Mate S发布:余承东说要在圣诞季和三星、苹果正面开战---ESM
- 总结了Mybatis,原来知识点也没多少嘛
- (超)体素云连通性分割算法VCCS
- 自己对PID控制算法的一点见解