面向对象编程之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 ...
随机推荐
- 解决错误:Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package.
原因是代码直接放在默认包里边,比如src\main\java目录下 应该在src\main\java下建立子目录,比如src\main\java\com\test 这样的话,代码就在com.test这 ...
- 9款国内外垂直领域的在线作图工具:那些可以替代Visio的应用!【转】
http://www.csdn.net/article/2015-02-12/2823939 摘要:现在越来越多的创业公司都希望提升办公的效率,今天介绍的几款也能提升办公效率,不过它们都属于垂直领域的 ...
- C# Task ContinueWith的实现
看了上一篇C# Task 是什么?返回值如何实现? Wait如何实现 我们提到FinishContinuations方法中会调用TaskContinuation实例,那么我们的ContinueWith ...
- Canvas 旋转的图片
var image = new Image(), counter = 0; image.onload = function () { var CANVAS_WIDTH = 300, CANVAS_HE ...
- Device does not seem to be present [常见错误解决]
一.故障现象: [root@c1node01 ~]# service network restart Shutting down loopback insterface: ...
- [转]ThreadLocal使用
引言 ThreadLocal的官方API解释为: “该类提供了线程局部 (thread-local) 变量.这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线 ...
- SQL SERVER 批量生成编号
开始: 在testing中,为了模拟orders,有个要求给数据库dba,如何通过后台数据库脚本快速批量生成orders. 分析 站在数据库角度,批量生成orders,也就是批量生成表中的行数据. s ...
- SNF快速开发平台成长史V4.5-Spring.Net.Framework-SNF软件开发机器人
SNF快速开发平台成长史 SNF框架CS\BS 视频教程 https://pan.baidu.com/s/1dFegFKX SNF开发机器人教程:链接:https://pan.baidu.com/s/ ...
- GitHubPage博客搭建学习专栏
Hexo NexT 博客本地搭建指南 Hexo NexT 博客与Github page 关联指南 Hexo NexT 博客后台管理指南
- grokking deep learning
https://www.manning.com/books/grokking-deep-learning?a_aid=grokkingdl&a_bid=32715258