(一)什么是多态?(What)

 I.基本概念

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


通俗理解:在程序运行时,相同类型的变量可以呈现出不同的行为特征。

II.多态核心

核心点一

       多态指程序中定义的引用变量(父类)所指向的具体类型和通过该引用变量发出的方法调用在编译时并不确定,而是在程序运行期间才确定,即一个引用变量最终会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。

核心点二

       子类对象指向父类的引用,通过父类的引用(变量)可以调用父类中的方法或者是子类重写父类的方法(动态连接、动态调用)。

核心点三

     继承链中对象方法的调用存在一个优先级this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。从子类依次深入,直到找到为止。

III.使用技术

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

(二)为什么要使用多态?(Why)

I.实例

   问题:饲养员喂养宠物

   饲养员

/**
* 创建饲养员类
* */
class Person1{
public void feed(Cat O){
System.out.println("feeding....");
O.eat();//调用Cat对象的eat()方法
}
public void feed2(Dog O){
System.out.println("feeding....");
O.eat();//调用Dog对象中的eat()方法
}
}

宠物

/**创建宠物类pets(父类)*/
class Pets {
public void eat(){
System.out.println("小动物们开始吃东西了....");
}
}
/**
* 创建Cat类来继承Pets类(Cat为Pets的子类,Pets为Cat的直接父类)
* 重写eat()方法
* */
class Cat extends Pets{
@Override
public void eat(){
System.out.println("吃小鱼....");
}
}
/**
* 创建Dog类来继承Pets类(Dog为Pets的子类,Pets为Dog的直接父类)
* 重写eat()方法
* */
class Dog extends Pets{
@Override
public void eat(){
System.out.println("吃狗粮....");
}
}

主函数

public static void main(String[] args) {
//创建一个饲养员
Person1 person1=new Person1();
//创建一个宠物
Cat cat=new Cat();
//创建一个宠物
Dog dog=new Dog();
//饲养员喂食动物
person1.feed(cat);
person1.feed2(dog);
}

分析

       在饲养员喂养宠物的过程中,对于不同的动物都需要在饲养员的类中的feed()方法中传入不同的形参对象,来实现对不同动物的喂食过程。

来看看多态性的魅力

/**
* 创建饲养员类
* */
class Person1{
/**
* 多态:子类对象指向父类引用
* */
public void feed(Pets O){
//子类对象赋值给父类引用(向上转型),调用子类中重写父类的方法
System.out.println("feeding....");
O.eat();//调用具体子类对象重写父类的eat()方法
}
}

分析

当把不同的子类对象都当作父类类型看待,可以屏蔽不同子类对象之间的差异,从而写出通用的代码达到通用编程,以适应需求中的不断变化。

II.多态优点

优点一

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

优点二

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

优点三

        接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。

优点四

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

优点五

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

(三)如何使用多态??(How)

I.使用条件

   注意:缺一不可!!!

      (1)继承关系(子父类关系)

      (2)方法的重写(子类重写<override>)父类中已有的方法)

        (3)  父类引用指向子类对象 

                  格式: 父类名 引用变量(父类) = new 子类名();

II.向上转型和向下转型

 (1)向上转型

       ①  基本概念:  指的是父类引用指向子类对象

       ②  格式父类名 引用变量(父类) = new 子类名();

       ③  使用说明:通过引用可以调用子类中重写父类的方法和父类中的方法

       ④  实例如下:  

public class Test6 {
public static void main(String[] args) {
//子类(Girl)对象指向父类的引用(customers) --->向上转型
Customers customers=new Girl();
//通过父类引用调用的是为子类中已经重写的Buy()方法
customers.Buy();// 运行结果 : 买发卡....
}
}
/**
* Customer类:指的是购物群体
* */
class Customers{
public void Buy(){
System.out.println("开心购物中....");
}
}
/**
* Boy类:指的是Customers中的具体的消费群体
* */
class Boy extends Customers{
@Override
public void Buy(){
System.out.println("买篮球...");
}
}
class Girl extends Customers{
@Override
public void Buy(){
System.out.println("买发卡....");
}
}

     ⑤ 优点(目的)达到参数统一。

(2)向下转型

    ① 基本概念:指的是通过强制转化为子类对象引用来调用其中专有方法。

    ② 要求:向下转型前要先发生向上转型,不然会报转换异常

    ③ 格式: 子类名 子类引用=(子类名)父类引用;(判断)

    ④ 实例如下:

/**  关键字:instanceof
* 作用:判断某一个对象是否是某一个类的实例(防止强制转化出现错误)
*/
public class Test6 {
public static void main(String[] args) {
//向上转型
Customers girl=new Girl();
//向下转型
if(girl instanceof Girl){
//通过instanceof关键字来进行判断
Girl girl1=(Girl)girl;
//向下转型(强制类型转化)
girl1.Read();
//调用Girl中特有的方法

//输出结果:我喜欢阅读...
}
}
}
/**
* Customer类:指的是购物群体
* */
class Customers{
public void Buy(){
System.out.println("开心购物中....");
}
}
/**
* Boy类:指的是Customers中的具体的消费群体
* */
class Boy extends Customers{
@Override
public void Buy(){
System.out.println("买篮球...");
}
}
class Girl extends Customers{
@Override
public void Buy(){
System.out.println("买发卡....");
}
public void Read(){
System.out.println("我喜欢阅读...");
}
}

  ⑤优点(目的):调用子类的特有的方法

注意:向下转型为强制转型,一般情况下不建议使用