1.定义

多态:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)

2.实现多态的技术称为

动态绑定(dynamicbinding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。

3.作用

消除类型之间的耦合关系。

4.现实中,关于多态的例子不胜枚举

比方说按下F1键这个动作,如果当前在Flash界面下弹出的就是AS3的帮助文档;如果当前在Word下弹出的就是Word帮助;在Windows下弹出的就是Windows帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。

5.多态存在的三个必要条件

  1. 要有继承;

  2. 要有重写;

  3. 父类引用指向子类对象。

6.多态的好处:

  1. 可替换性(substitutability):多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。

  2. 可扩充性(extensibility):多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。

  3. 接口性(interface-ability):多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,完善或者覆盖这两个接口方法。

  4. 灵活性(flexibility):它在应用中体现了灵活多样的操作,提高了使用效率。

  5. 简化性(simplicity):多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。

7.Java中多态的实现方式

  • 接口实现
  • 继承父类进行方法重写,同一个类中进行方法重载。

8.Java中多态的分类

在java中,多态大致可以分为以下几种情况:

  1. person为父类,student为子类。那么:person p = new student()

  2. fliable为接口,bird为实现接口的类,那么:fliable f = new bird()

  3. fliable为抽象类,bird为继承fliable的类,那么:fliable f = new bird()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Animal {
public void eat() {
System.out.println("eat");
}

public void sleep() {
System.out.println("sleep");
}
}

class Dog extends Animal {
public void eat() {
System.out.println("狗吃肉");
}
/*
public void sleep() {
System.out.println("狗站着睡觉");
}
*/
public void eatShit() {
System.out.println("dog is eating shit...");
}
}

public class TestDuoTai {
public static void main(String[] args) {
Animal dog = new Dog();
dog.eat(); //dog对象不能使用.eatShit()方法,因为父类中没有定义该方法
dog.sleep();
Dog dog1 = new Dog(); //只能通过子类本身的引用调用子类特有的方法
dog1.eatShit();
}
}

狗吃肉
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】,让我们一起成长,谢谢。
微信公众号