我相信从学习计算机面向对象编程起就很多人背下了继承、封装、多态三个特性,可是多态并不是那么好理解的。通常做几道题,背下几次多态的动态绑定规律,可是依旧在一段时间后忘记了多态的存在,为什么要多态,这个程序为何会产生这样的结果呢?

  先看多态的两个必要条件:继承、重写。

  thinking in java 中对继承有提到:通过继承而产生的类型等价是理解面向对象程序设计方法的重要门槛,他们有相同的基础接口,而对应的接口也必然有某些具体的实现,因为继承是产生了新的类型,如果新类型没有什么不同的行为,那继承就没有什么意义。对外来说,如果要做到不同的行为实现,那就要进行接口的重写,使得消息传递到该对象的时候,能产生不同的行为。而选择不同行为的过程,其实就是我们常说的动态绑定,其实在内存来说,就是jvm到底要跑哪一部分代码块。

  本文不打算说编译时多态。

  那么运行时多态到底如何设置绑定规则呢?其实是从问题空间来的,我们知道,继承要有意义,而且是的代码具有拓展性,必然要符合问题空间,具体来说可以是基础设施,也可以是领域模型;因此我们泛化一个类型的时候,总是希望利用基类型用作统一处理所有业务,然后让不同的实现类去做具体的事情,因此有如下的规则:

  1、先从声明类型(基类)入手,寻找所有其向上型(父类,超类)的接口实现,寻找对应可绑定代码,保证泛化类型行为的正确性(也就是这样找才可以保证类型等价),如果2不成立,则根绝消息参数执行对应的接口实现(这里的要根据消息参数是因为消息参数也有向上转型情况)。

  2、如果该接口被重写,那么执行被重写的方法,原因很简单,任何时候this指针是指向实际类型的,也就是问题空间中继承出的新类型,已经重新定义了该行为,所以必须绑定重写的行为。这一点是多态的意义所在。

  其实以上两点和提到的继承重写可以引申到里氏替换原则(不要问我为什么要符合里氏替换),为符合重写的规则,本身java就保证了前置条件和后置条件,即继承并且覆盖超类方法的时候,子类中的方法的可见性必须等于或者大于超类中的方法的可见性,子类中的方法所抛出的受检异常只能是超类中对应方法所抛出的受检异常的子类,但是要维持is-a关系,使得抽象类型是符合开闭原则的,本身就要求多态是不能瞎用的,所以多态也要记住一个原则:

  3、里氏替换原则。

  第二点充分说明了一个问题,在你向上转型的时候,完全不用担心你子类重写的行为会消失,基类只保证类型,而子类优先行为。

  下面给出个具体例子。。。。。。

面向对象编程之Java多态的更多相关文章

  1. PHP面向对象编程之深入理解方法重载与方法覆盖(多态)

    这篇文章主要介绍了PHP面向对象编程之深入理解方法重载与方法覆盖(多态)的相关资料,需要的朋友可以参考下: 什么是多态? 多态(Polymorphism)按字面的意思就是"多种状态" ...

  2. python基础-面向对象编程之多态

    面向对象编程之多态以及继承.抽象类和鸭子类型三种表现形式 多态 定义:同一种类型的事物,不同的形态 作用: 多态也称之为"多态性".用于在不知道对象具体类型的情况下,统一对象调用方 ...

  3. 深入理解JavaScript系列(17):面向对象编程之概论

    介绍 在本篇文章,我们考虑在ECMAScript中的面向对象编程的各个方面(虽然以前在许多文章中已经讨论过这个话题).我们将更多地从理论方面看这些问题. 特别是,我们会考虑对象的创建算法,对象(包括基 ...

  4. Java 多态——与C++的比较

    学习了Java和C++之后,由于长期不使用C++,而java的基础知识掌握不牢,现在已经搞不清java多态了.现在先来谈谈java多态,稍后有时间再更新C++的多态,并进行比较~ 一. Java的多态 ...

  5. C++和java多态的区别

    C++和java多态的区别 分类: Java2015-06-04 21:38 2人阅读 评论(0) 收藏 举报  转载自:http://www.cnblogs.com/plmnko/archive ...

  6. 深入理解Java多态机制

    从字节码层面来看,Java中的所有方法调用,最终无外乎转换为如下几条调用指令. invokestatic: 调用静态方法. invokespecial: 调用实例构造器<init>方法,私 ...

  7. Java 多态 父类和子类方法的访问控制权限

    Java 多态 父类和子类方法的访问控制权限 @author ixenos 父类和子类方法的访问控制权限 继承是为了扩展类的功能,而这种扩展显然就是对一个原始类的扩展,目的还是向上转型来调用,所以这就 ...

  8. Java多态(二)

    public class ExtendsTest { public static void main(String[] args) { A a1 = new A(); A a2 = new B(); ...

  9. 从JVM角度看Java多态

    首先,明确一下,Java多态的三个必要条件: 1. 继承 2. 子类重写父类方法 3. 父类引用指向子类对象 然后看一个例子 package test.xing; class Father{ prot ...

随机推荐

  1. Javascript 字符串(二)常用操作整理

    一.js获取字符串的字节数 这个好使--- function getBytesLength(str) { // 在GBK编码里,除了ASCII字符,其它都占两个字符宽 return str.repla ...

  2. OpenCV3 for python3 学习笔记3-----用OpenCV3处理图像一

    本文的内容都与图像处理有关,这时需要修改图像,比如要使用具有艺术性的滤镜.外插(extrapolate)某些部分.分割.粘贴或其他需要的操作. 1.不同色彩空间的的转换 OpenCV有数百种关于在不同 ...

  3. NLP 第7章 文本向量化

  4. Docker 管理工具 Portainer部署

    Docker 管理工具 Portainer部署 一.官网 官网:http://www.portainer.io 演示地址:http://demo.portainer.io 用户名:admin 密码:t ...

  5. chrome插件离线包下载和安装

    添加扩展一般会有个url https://chrome.google.com/webstore/detail/axure-rp-extension-for-ch/dogkpdfcklifaemcdfb ...

  6. html5学习笔记——基础

    一:Canvas <canvas> 标签只是图形容器,图形的绘制需要用JS来定义. 1:绘制与填充 stroke():绘制,空心. fillXX():填充,实心. 2:绘制线条 var c ...

  7. windows下查看特定端口被什么程序占用

    我电脑上因为命令: netstat -ano 列出的太多了,所以不好看. 以下是其他方式: 查看8088端口占用情况: 开始---->运行---->cmd,或者是window+R组合键,调 ...

  8. Python之基础练习代码

    代码1: # -*- coding: utf-8 -*- def function(*numbers): sum = 0 for num in numbers: sum = sum + num*num ...

  9. Effective Java 第三版——71. 避免不必要地使用检查异常

    Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...

  10. 小米Pro 安装苹果系统

    参考 http://www.miui.com/thread-11363672-1-1.html http://www.miui.com/thread-7601066-1-1.html https:// ...