67-Java面向对象三大特征之三:多态

一、面向对象三大特征之三:多态

1、多态是什么?
  • 同类型的对象,执行同一个行为,会表现出不同的行为特征。
    • 比如:猫和狗都是动物类型,执行同一个行为,但是会表现出不同的行为特征;

2、多态的常见形式
父类类型 对象名称 = new 子类构造器;
接口 对象名称 = new 实现类构造器;
package com.app.d1_polymorphism;

/**
    动物类:父类——抽象类
 */
public abstract class Animal {
    public abstract void run();
}
package com.app.d1_polymorphism;

/**
    狗类:子类,继承动物类
 */
public class Dog extends Animal{
    @Override
    public void run() {
        System.out.println("🐕跑得很快~~");
    }
}
package com.app.d1_polymorphism;

/**
    乌龟类:子类,继承动物类
 */
public class Tortoise extends Animal{
    @Override
    public void run() {
        System.out.println("🐢跑不起来!");
    }
}
package com.app.d1_polymorphism;

/**
    目标:认识多态,理解多态的形式和概念
 */
public class PolymorphismTest {
    public static void main(String[] args) {
//         以前的形式
        Dog d1 = new Dog();
        d1.run();

        Tortoise t1 = new Tortoise();
        t1.run();
        System.out.println("---------------------------------");

//         1、多态的形式:父类类型 对象名称 = new 子类构造器;
        // 其实多态的这个形式就是:右边的狗对象 赋值给 左边的动物对象
        // 狗对象只代表一种动物;动物对象代表所有的动物。属于小范围的 赋值给 大范围的,合情合理!
        Animal d2 = new Dog();
        d2.run();

        Tortoise t2 = new Tortoise();
        t2.run();
    }
}
🐕跑得很快~~
🐢跑不起来!
---------------------------------
🐕跑得很快~~
🐢跑不起来!

Process finished with exit code 0


3、多态中成员访问特点
  • 方法调用:编译看左边,运行看右边;
    在这里插入图片描述

  • 变量调用:编译看左边,运行也看左边。多态侧重行为多态
    在这里插入图片描述

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


4、多态的前提
  • 有继承/实现关系;有父类引用指向子类对象;有方法重写。


二、多态的优势

1、优势

(1)在多态形式下,右边对象可以实现解耦合,便于扩展和维护

  • 没换掉之前
    在这里插入图片描述在这里插入图片描述


  • 换掉之后,run行为也会随着对象而变,不需要改动代码

在这里插入图片描述


  • 解耦合: 什么意思呢?

    • 举例说明:
      • 比如你家孩子买了一个变形金刚的玩具,玩着玩着没电了,这时候只需要换电池,就可以继续玩;
      • 再比如你买了一辆电动车,哪天轮胎爆了,这时候只需要去维修店换轮胎,是不是就可以继续开了。

(2)定义方法的时候,使用父类型作为参数,该方法就可以接收这个父类的一切子类对象,体现出多态的扩展与便利

  • 所有动物参加赛跑比赛
    在这里插入图片描述


  • 执行原理:
    在这里插入图片描述


2、多态下产生的问题
  • 多态下不能使用子类的独有功能

    • 因为父类是被继承的,因此继承了父类的子类会有父类的一切行为,但是父类是没有子类独有行为的。
      在这里插入图片描述


      在这里插入图片描述


      在这里插入图片描述

三、多态下引用类型的类型转换

1、引用类型是什么?
  • 也就是我们自己定义的:动物类、学生类、猫类、老师类等等。
2、引用类型的类型转换
  • 自动类型转换(从子到父):子类对象赋值给父类类型的变量指向。

    • 因为父类范围大,所有子类对象赋值给父类类型的变量指向—>属于:小范围 赋值给 大范围,因此是自动类型转换
  • 强制类型转换(从父到子)

    • 此时必须进行强制类型转换:

      子类 对象变量 = (子类)父类类型的变量;
      
    • 作用:可以解决多态下的劣势,可以实现调用子类的独有行为(方法功能)。
      在这里插入图片描述


      在这里插入图片描述


      在这里插入图片描述


      在这里插入图片描述



      在这里插入图片描述

    • 注意:如果 转型后的类型 和对象真实类型 不是同一种类型,那么在转换的时候就会出现 ClassCastException
      在这里插入图片描述
      在这里插入图片描述


3、instanceof关键字
  • Java建议多态下的引用类型在强制类型转换的前,使用 instanceof 关键字判断当前对象的真实类型,再进行强制类型转换。

    变量名 instanceof 真实类型
    判断 instanceof 左边的变量指向的对象的真实类型,是否与右边的类型或者与其子类类型一样,是则返回true,反之。
    

在这里插入图片描述



在这里插入图片描述



4、知识总结

1、引用类型的类型转换,有几种方式?

  • 有自动类型转换、强制类型转换

2、强制类型转换能解决什么问题?需要注意什么?

  • 可以解决多态下不能访问子类独有功能的问题,强制转换后可以访问
  • 有继承或者实现关系的两个类型就可以进行强制转换,编译无问题
  • 运行时,如果发现强制转换后的类型不是对象的真实类型则会报错
  • 注意:java建议强制转换前使用 instanceof 关键字判断一下当前对象的真实类型,再进行强制类型转换


四、多态综合案例

1、案例一

此案例,无实际含义,目的是为了通过此案例理解之前所学的语法

  • 需求:

    • 使用面向对象编程模拟:设计一个电脑对象,可以安装2个USB设备;

    • 鼠标:被安装时可以完成接入、调用点击、拔出功能;

    • 键盘:被安装时可以完成接入、调用打字、拔出功能。

  • 分析实现:

    • 1、定义一个USB的接口:(申明USB设备的规范必须是:可以接入、拔出);

    • 2、定义2个USB实现类代表鼠标、键盘,让其实现USB接口,并分别定义它们自己独有的功能;

    • 3、创建电脑对象,创建2个USB实现类对象,分别安装到电脑中并触发功能的执行。

    • USB接口

      package com.app.d4_polymorphism_test;
      
      /**
          1、定义一个USB的接口:(申明USB设备的规范必须是:可以接入、拔出);
       */
      public interface USB {
          void access();  // 接入
          void pullOut(); // 拔出
      }
      

    • 键盘实现类

      package com.app.d4_polymorphism_test;
      
      /**
          2、定义USB实现类代表键盘,让其实现USB接口
       */
      public class KeyBoard implements USB{
          /**
              b、定义键盘名称:商标
           */
          private String keyBoardName;
      
      
          /**
              c、提供无参、有参构造器
           */
          public KeyBoard() {
      
          }
      
          public KeyBoard(String keyBoardName) {
              this.keyBoardName = keyBoardName;
          }
      
      
          /**
              d、提供变量对应的getter、setter方法,暴露其取值和赋值
           */
          public String getKeyBoardName() {
              return keyBoardName;
          }
      
          public void setKeyBoardName(String keyBoardName) {
              this.keyBoardName = keyBoardName;
          }
      
      
          /**
              a、实现USB接口的规范:接入、拔出
           */
          @Override
          public void access() {
              System.out.println(keyBoardName + "已成功连接电脑~");
          }
      
          @Override
          public void pullOut() {
              System.out.println(keyBoardName + "已安全拔出电脑~");
          }
      
      
          /**
              e、并定义它自己独有的功能:打字
           */
          public void tap() {
              System.out.println(keyBoardName + "敲击了:老铁,没毛病~~ 666~~~");
          }
      
      }
      
    • 鼠标实现类

      package com.app.d4_polymorphism_test;
      
      /**
          2、定义USB实现类代表鼠标,让其实现USB接口
       */
      public class Mouse implements USB{
          /**
              b、定义鼠标名称:商标
           */
          private String mouseName;
      
      
          /**
              c、提供无参、有参构造器
           */
          public Mouse() {
      
          }
      
          public Mouse(String mouseName) {
              this.mouseName = mouseName;
          }
      
      
          /**
              d、提供变量对应的getter、setter方法,暴露其取值和赋值
           */
          public String getMouseName() {
              return mouseName;
          }
      
          public void setMouseName(String mouseName) {
              this.mouseName = mouseName;
          }
      
      
          /**
              a、实现USB接口的规范:接入、拔出
           */
          @Override
          public void access() {
              System.out.println(mouseName + "已成功连接电脑~");
          }
      
          @Override
          public void pullOut() {
              System.out.println(mouseName + "已安全拔出电脑~");
          }
      
      
          /**
              e、并定义它自己独有的功能:点击
           */
          public void click() {
              System.out.println(mouseName + "点击了屏幕~");
          }
      
      }
      
    • 电脑类

      package com.app.d4_polymorphism_test;
      
      /**
          3、创建电脑对象:计算机类
       */
      public class Computer {
          /**
              a、定义计算机名称:商标
           */
          private String computerName;
      
          /**
              b、提供有参和无参构造器
           */
          public Computer() {
          }
      
          public Computer(String computerName) {
              this.computerName = computerName;
          }
      
          /**
              c、提供变量对应的getter、setter方法,暴露其取值和赋值
           */
          public String getComputerName() {
              return computerName;
          }
      
          public void setComputerName(String computerName) {
              this.computerName = computerName;
          }
      
      
          /**
              模拟电脑开机
           */
          public void start(){
              System.out.println(computerName + "开机了~");
          }
      
          /**
              d、提供安装USB时的入口
           */
          public void installUSB(USB usb){
              // USB设备连接电脑
              usb.access();
      
              // usb 有可能是键盘,也有可能是鼠标
              // 在接入时,先判读这个设备是键盘还是鼠标
              if (usb instanceof KeyBoard) {
                  // 是键盘,将USB强制转换成键盘
                  KeyBoard k = (KeyBoard) usb;
                  k.tap();
      
              }else if (usb instanceof Mouse) {
                  // 是鼠标,将USB强制转换成鼠标
                  Mouse m = (Mouse) usb;
                  m.click();
              }
      
              // USB设备安全拔出电脑
              usb.pullOut();
          }
      }
      
    • 测试类

      package com.app.d4_polymorphism_test;
      
      /**
          目标:USB设备模拟。
          通过此案例综合起之前所学的语法,训练面向对象的思维。
      
          需求:
              使用面向对象编程模拟:设计一个电脑对象,可以安装2个USB设备;
              鼠标:被安装时可以完成接入、调用点击、拔出功能;
              键盘:被安装时可以完成接入、调用打字、拔出功能。
       */
      public class Test {
          public static void main(String[] args) {
              // a、创建电脑对象
              Computer c1 = new Computer("联想电脑");
              // b、开机
              c1.start();
      
              // c、创建键盘、鼠标对象
              USB u1 = new KeyBoard("雷蛇");
              USB u2 = new Mouse("罗技鼠标");
      
              // d、连接电脑
              c1.installUSB(u1);
              c1.installUSB(u2);
          }
      }
      
    • 控制台

      联想电脑开机了~
      雷蛇已成功连接电脑~
      雷蛇敲击了:老铁,没毛病~~ 666~~~
      雷蛇已安全拔出电脑~
      罗技鼠标已成功连接电脑~
      罗技鼠标点击了屏幕~
      罗技鼠标已安全拔出电脑~
      
      Process finished with exit code 0
      
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值