1.定义
多态:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
2.实现多态的技术称为
动态绑定(dynamicbinding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
3.作用
消除类型之间的耦合关系。
4.现实中,关于多态的例子不胜枚举
比方说按下F1键这个动作,如果当前在Flash界面下弹出的就是AS3的帮助文档;如果当前在Word下弹出的就是Word帮助;在Windows下弹出的就是Windows帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。
5.多态存在的三个必要条件
要有继承;
要有重写;
父类引用指向子类对象。
6.多态的好处:
可替换性(substitutability):多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
可扩充性(extensibility):多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。
接口性(interface-ability):多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,完善或者覆盖这两个接口方法。
灵活性(flexibility):它在应用中体现了灵活多样的操作,提高了使用效率。
简化性(simplicity):多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。
7.Java中多态的实现方式
- 接口实现
- 继承父类进行方法重写,同一个类中进行方法重载。
8.Java中多态的分类
在java中,多态大致可以分为以下几种情况:
person
为父类,student
为子类。那么:person p = new student()
;fliable
为接口,bird
为实现接口的类,那么:fliable f = new bird()
;fliable
为抽象类,bird
为继承fliable
的类,那么:fliable f = new bird()
;
1 | class Animal { |
狗吃肉
sleep
dog is eating shit…
多态时需要说明dog
声明为父类的引用,但他实际为子类引用。但是他只能调用父类中存在的方法(父类中的方法子类如果重写了,就调用子类的重写方法,如果没有被重写就调用父类中的方法)。
如果想使用子类中特有的方法,比如eatShit()
方法,那么使用声明类型dog
是不能调用该方法的,只能使用声明类型dog1
进行调用,即子类本身的引用。接口和继承都遵循该规律。
9.instanceof运算符
java
语言的多态机制导致了引用变量的声明类型和其实际引用对象的类型可能不一致,再结合虚方法调用规则可以得出结论:声明为同种类型的两个引用变量调用同一个方法时也可能会有不同的行为。这里就引入了instanceof
运算符。
那么如果我声明了person p = new student()
;我想将p转为student的可不可以?当然可以,但是就得强制转换了(儿子想成为父亲直接来,父亲想成为儿子你就强来)。
通常在强制转换时加上instanceof
来判断。
1 | if(p instanceof student) { student s =(student) p; } |
多态贯穿于java整个学习,比如在异常处理时写catch语句,我们规定必须子类异常写在前,父类异常写在后。为什么呢?原因就是多态了。我们的catch语句格式:catch(Exceptione)。java程序在产生异常时会自动生成一个异常对象,如果先产生一个子类异常,并且父类异常写在前,那么根据多态肯定会执行此catch语句,执行完一条catch语句后将会跳出。
reference
https://www.jb51.net/article/128815.htm
写在最后
欢迎大家关注鄙人的公众号【麦田里的守望者zhg】,让我们一起成长,谢谢。