面向对象编程之Java多态
我相信从学习计算机面向对象编程起就很多人背下了继承、封装、多态三个特性,可是多态并不是那么好理解的。通常做几道题,背下几次多态的动态绑定规律,可是依旧在一段时间后忘记了多态的存在,为什么要多态,这个程序为何会产生这样的结果呢?
先看多态的两个必要条件:继承、重写。
thinking in java 中对继承有提到:通过继承而产生的类型等价是理解面向对象程序设计方法的重要门槛,他们有相同的基础接口,而对应的接口也必然有某些具体的实现,因为继承是产生了新的类型,如果新类型没有什么不同的行为,那继承就没有什么意义。对外来说,如果要做到不同的行为实现,那就要进行接口的重写,使得消息传递到该对象的时候,能产生不同的行为。而选择不同行为的过程,其实就是我们常说的动态绑定,其实在内存来说,就是jvm到底要跑哪一部分代码块。
本文不打算说编译时多态。
那么运行时多态到底如何设置绑定规则呢?其实是从问题空间来的,我们知道,继承要有意义,而且是的代码具有拓展性,必然要符合问题空间,具体来说可以是基础设施,也可以是领域模型;因此我们泛化一个类型的时候,总是希望利用基类型用作统一处理所有业务,然后让不同的实现类去做具体的事情,因此有如下的规则:
1、先从声明类型(基类)入手,寻找所有其向上型(父类,超类)的接口实现,寻找对应可绑定代码,保证泛化类型行为的正确性(也就是这样找才可以保证类型等价),如果2不成立,则根绝消息参数执行对应的接口实现(这里的要根据消息参数是因为消息参数也有向上转型情况)。
2、如果该接口被重写,那么执行被重写的方法,原因很简单,任何时候this指针是指向实际类型的,也就是问题空间中继承出的新类型,已经重新定义了该行为,所以必须绑定重写的行为。这一点是多态的意义所在。
其实以上两点和提到的继承重写可以引申到里氏替换原则(不要问我为什么要符合里氏替换),为符合重写的规则,本身java就保证了前置条件和后置条件,即继承并且覆盖超类方法的时候,子类中的方法的可见性必须等于或者大于超类中的方法的可见性,子类中的方法所抛出的受检异常只能是超类中对应方法所抛出的受检异常的子类,但是要维持is-a关系,使得抽象类型是符合开闭原则的,本身就要求多态是不能瞎用的,所以多态也要记住一个原则:
3、里氏替换原则。
第二点充分说明了一个问题,在你向上转型的时候,完全不用担心你子类重写的行为会消失,基类只保证类型,而子类优先行为。
下面给出个具体例子。。。。。。
面向对象编程之Java多态的更多相关文章
- PHP面向对象编程之深入理解方法重载与方法覆盖(多态)
这篇文章主要介绍了PHP面向对象编程之深入理解方法重载与方法覆盖(多态)的相关资料,需要的朋友可以参考下: 什么是多态? 多态(Polymorphism)按字面的意思就是"多种状态" ...
- python基础-面向对象编程之多态
面向对象编程之多态以及继承.抽象类和鸭子类型三种表现形式 多态 定义:同一种类型的事物,不同的形态 作用: 多态也称之为"多态性".用于在不知道对象具体类型的情况下,统一对象调用方 ...
- 深入理解JavaScript系列(17):面向对象编程之概论
介绍 在本篇文章,我们考虑在ECMAScript中的面向对象编程的各个方面(虽然以前在许多文章中已经讨论过这个话题).我们将更多地从理论方面看这些问题. 特别是,我们会考虑对象的创建算法,对象(包括基 ...
- Java 多态——与C++的比较
学习了Java和C++之后,由于长期不使用C++,而java的基础知识掌握不牢,现在已经搞不清java多态了.现在先来谈谈java多态,稍后有时间再更新C++的多态,并进行比较~ 一. Java的多态 ...
- C++和java多态的区别
C++和java多态的区别 分类: Java2015-06-04 21:38 2人阅读 评论(0) 收藏 举报 转载自:http://www.cnblogs.com/plmnko/archive ...
- 深入理解Java多态机制
从字节码层面来看,Java中的所有方法调用,最终无外乎转换为如下几条调用指令. invokestatic: 调用静态方法. invokespecial: 调用实例构造器<init>方法,私 ...
- Java 多态 父类和子类方法的访问控制权限
Java 多态 父类和子类方法的访问控制权限 @author ixenos 父类和子类方法的访问控制权限 继承是为了扩展类的功能,而这种扩展显然就是对一个原始类的扩展,目的还是向上转型来调用,所以这就 ...
- Java多态(二)
public class ExtendsTest { public static void main(String[] args) { A a1 = new A(); A a2 = new B(); ...
- 从JVM角度看Java多态
首先,明确一下,Java多态的三个必要条件: 1. 继承 2. 子类重写父类方法 3. 父类引用指向子类对象 然后看一个例子 package test.xing; class Father{ prot ...
随机推荐
- HBuilder的扩展插件开发暴露了一个事实:其实不能实现写一次代码实现跨平台App生成
HBuilder的扩展插件开发,原来并不能生成单独的插件jar,而是以源码 - 类的形式进行开发,这其实就要求必须使用离线打包. 事实上,开发顺序应该是:先弄好离线打包框架,然后在AS里进行扩展插件开 ...
- Linux出现Read-only file system错误的解决方法
造成这个问题的解决办法大多数是由于非正常关机后导致文件系统受损引起的,在系统重新启动之后,受损分区就会被Linux自己主动挂载为仅仅读.解决办法是通过fsck来修复文件系统,然后重新启动就可以,下面是 ...
- Translate Angular >=4 with ngx-translate and multiple modules
原文:https://medium.com/@lopesgon/translate-angular-4-with-ngx-translate-and-multiple-modules-7d9f0252 ...
- Deep Learning.ai学习笔记_第五门课_序列模型
目录 第一周 循环序列模型 第二周 自然语言处理与词嵌入 第三周 序列模型和注意力机制 第一周 循环序列模型 在进行语音识别时,给定一个输入音频片段X,并要求输出对应的文字记录Y,这个例子中输入和输出 ...
- Ubuntu 16.04 升级git
To update git on Ubuntu 12.04 just follow this line of commands: sudo apt-get install python-softwar ...
- 微信小程序+微信管理后台+微信用户前台
代码地址如下:http://www.demodashi.com/demo/15043.html #### 微信小程序+微信管理后台+微信用户前台 #### 产品介绍 基础功能开发:景区微信地图导游.天 ...
- numpy中的方差、协方差、相关系数
一.np.var 数学上学过方差:$$ D(X)=\sum_{i\in [0,n)} ({x-\bar{x}})^2 $$ np.var()实际上是均方差,均方差的意义就是将方差进行了平均化,从而使得 ...
- Linux(CentOS)安装Node.JS和npm的两种方式(yum安装和源码安装)
yum安装 yum安装是将yum源中的rpm包下载到本地,安装这个rpm包.这个rpm包是别人编译安装好的二进制包.这种方式方便快捷,特别是不用考虑包依赖. 0.了解linux版本 通过 uname ...
- Python的虚拟机安装已经如何配置Scrapy for Mac
时间:2018年2月21日 因为时间问题,以下笔记就粗略记录.仅作为个人笔记为用 安装virtualenv和virtualenvwrapper 如何安装的细节下面这篇也有介绍,包括如何使用切换虚拟机也 ...
- Mac上安装mysqlclient的报错
[背景] 今天我把算把自己的python基础平台从python-3.6.2升级到python-3.7.2,在我安装完python-3.7.2之后,打算在此基础之上安装 mysqlclient的时候报错 ...