面向对象编程之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 ...
随机推荐
- SpringBoot无废话入门04:MyBatis整合
1.Parent引入及pom配置 首先,如果要支持mybatis,那么我们就应该引入mybatis的starter.同时,由于连接本身还需要用jdbc的connetor和连接池,所以一并需要引入这些依 ...
- JS 之 阻止事件冒泡,阻止默认事件,event.stopPropagation()和event.preventDefault(),return false的区别
在前端开发中,有时我们需要阻止冒泡和阻止默认事件的发生. 一.event.stopPropagation() 阻止事件的冒泡,不让事件向documen上蔓延,但是默认事件任然会执行,当调用这个方法的时 ...
- PHP判断一个JSON对象是否含有某一个属性的方法
property_exists比如:var json={"code":400,"msg":"User Err"} var rest=prop ...
- 【大话QT之十二】基于CTK Plugin Framework的插件版本号动态升级
应用需求: 某些场景下我们可能面临这种问题,在执行着的应用程序不能终止的情况下,升级某个功能(或添,或减.或改动).在不採用CTK Plugin Framework插件系统架构的情况下这将是非常困难的 ...
- 简单理解 RPC(转载)
原文地址:http://www.syyong.com/architecture/Simple-understanding-of-RPC.html RPC(Remote Procedure Call P ...
- mongodb 复杂查询之 本表 join
mongdb 的数据介绍: 系统有多个用户,contractId 代表用户Id,其中 serialno 也是一种 id,代表该客户登录系统的编号,该 contractId 每次登录系统都会产生不同 ...
- 双网卡双线路DNS解析分析
在企业网络维护过程中我们经常会遇到这样或那样的奇怪问题,而很多问题需要有深厚的理论知识才能解决.而随着网络的飞速发展越来越多的中小企业开始尝试通过多条线路来保证网络的畅通,一方面双网卡下的双线接入可以 ...
- Spring常用工具方法备忘录
1:加载配置文件 Resource resource = new ClassPathResource("log4j.properties"); Properties default ...
- SparkStreaming:关于checkpoint的弊端
当使用sparkstreaming处理流式数据的时候,它的数据源搭档大部分都是Kafka,尤其是在互联网公司颇为常见. 当他们集成的时候我们需要重点考虑就是如果程序发生故障,或者升级重启,或者集群宕机 ...
- Jet.com
Jet.com是一家电商startup,总部在最爱的小城市Hoboken.目前是类似Amazon的一个网站,后台用F#来做Micro Services,服务器都在Azure和AWS上.人员配置年轻聪明 ...