Java基础语法(十)| 多态

1. 多态

1.1 什么是多态

多态是继封装、继承之后,面向对象的第三大特性。生活中,比如跑的动作,小猫、小狗和大象,都是动物,跑起来是不一样的。

再比如飞的动作,昆虫、鸟类和飞机,飞起来也是不一样的。

可见,同一行为,通过不同的事物,可以体现出来的不同的形态。

多态,指的是同类事物、或实现同一接口的对象,同样的行为,呈现的不同形态。

1.2 多态的前提

 - 1.要有继承或实现关系
- 2.要有方法的重写
- 3.要有父类引用指向子类对象   fu  f = new zi();

1.3 多态格式

  •  普通类多态的格式

父类 对象 = new 子类();

  •  抽象类多态的格式

 抽象类 对象名 = new 抽象类子类();

  •  接口多态的格式

接口 对象名 = new 接口实现类();

1.4 多态中的成员访问特点

  • 成员变量

编译看左边(父类),运行看左边(父类)

  • 成员方法

编译看左边(父类),运行看右边(子类)

  • 代码示例

 动物类:

public abstract class Animal {int age = 40;public abstract void eat();
}

猫类:

public class Cat extends Animal {public int age = 20;public int weight = 10;//子类要重写父类中的方法@Overridepublic void eat() {System.out.println("猫吃鱼");public void playGame() {System.out.println("猫捉迷藏");}
}

测试类:

public class AnimalDemo {public static void main(String[] args) {//有父类引用指向子类对象Animal a = new Cat();//成员变量//编译看左边(父类),运行看左边(父类)System.out.println(a.age);// System.out.println(a.weight);  //弊端:不能使用子类的特有成员变量//成员方法//编译看左边(父类),运行看右边(子类)a.eat();// a.playGame(); //弊端:不能使用子类的特有成员方法}
}

1.5 多态的好处和弊端

  • 多态的弊端

不能使用子类的特有成员

  • 多态的好处

提高程序的扩展性。定义方法时候,使用父类型作为参数,在使用的时候,使用具体的子类型参与操作。

  • 多态的好处代码演示

实际开发的过程中,父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用,更能体现出多态的扩展性与便利。

 定义父类:

public abstract class Animal {      public abstract void eat();
}  

定义子类 :

class Cat extends Animal {  public void eat() {  System.out.println("吃鱼");  }  
}  class Dog extends Animal {  public void eat() {  System.out.println("吃骨头");      }  
}

定义测试类:

public class Test {public static void main(String[] args) {        // 多态形式,创建对象Cat c = new Cat();  Dog d = new Dog(); // 调用showCatEat showCatEat(c);// 调用showDogEat showDogEat(d); /*多态的好处: 以上两个方法, 均可以被showAnimalEat(Animal a)方法所替代,而执行效果一致同一个方法用于不同的对象,产生不同的执行结果(同一事物体现不同状态)增加新子类不影响已存在类的多态性,继承性及其他操作,有了更好的维护性和扩展性*/showAnimalEat(c);showAnimalEat(d); //showAnimalEat(new Cat());//showAnimalEat(new Dog());}public static void showCatEat (Cat c){c.eat(); }public static void showDogEat (Dog d){d.eat();}public static void showAnimalEat (Animal a){a.eat();}
}

【多态的好处小结】

由于多态特性的支持,showAnimalEat方法的Animal类型,是Cat和Dog的父类类型,父类类型接收子类对象,当然可以把Cat对象和Dog对象,传递给方法。当eat方法执行时,多态规定,执行的是子类重写的方法,那么效果自然与showCatEat、showDogEat方法一致,所以showAnimalEat完全可以替代以上两方法。

​不仅仅是替代,在扩展性方面,无论之后再多的子类出现,我们都不需要编写showXxxEat方法了,直接使用showAnimalEat都可以完成。

​所以,多态的好处,体现在,可以使程序编写的更简单,并有良好的扩展。

1.6 多态中的转型

  • 为什么要用转型

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误。也就是说,不能调用子类拥有,而父类没有的方法。编译都错误,更别说运行了。这也是多态给我们带来的一点"小麻烦"。所以,想要调用子类特有的方法,必须做向下转型。

  • 向上转型

多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的。

使用格式:

向上转型
父类类型  变量名 = new 子类类型();
如:Animal a = new Cat();

  • 向下转型 

父类类型向子类类型向下转换的过程,这个过程是强制的。

一个已经向上转型的子类对象,将父类引用转为子类引用,可以使用强制类型转换的格式,便是向下转型。

使用格式:

子类类型 变量名 = (子类类型) 父类变量名;
如:Cat c =(Cat) a;  

  • 代码示例:

定义类:

abstract class Animal {  abstract void eat();  
}  class Cat extends Animal {  public void eat() {  System.out.println("吃鱼");  }  //子类特有方法public void catchMouse() {  System.out.println("抓老鼠");      }  
}  class Dog extends Animal {  public void eat() {  System.out.println("吃骨头");     }  //子类特有方法public void watchHouse() {  System.out.println("看家");  }  
}

测试类:

public class Test {public static void main(String[] args) {// 向上转型     fu f = new zi()Animal a = new Cat();  a.eat();                // 调用的是 Cat 的 eat// 向下转型    zi z = (zi)fu;  向下转型,获取子类特有的方法Cat c = (Cat)a;       c.catchMouse();         // 调用的是 Cat 的 catchMouse     }
}  

1.7 转型的异常

  • 问题描述

转型的过程中,一不小心就会遇到这样的问题,请看如下代码:

 public class Test {public static void main(String[] args) {// 向上转型  Animal a = new Cat();  a.eat();        // 调用的是 Cat 的 eat// 向下转型 Cat c = (Cat)a;c.catchMouse();//调用自己的方法System.out.println("================");// 向下转型  Dog d = (Dog)a;       //引用的父类,是多态cat类,并不是dog d.watchHouse();        // 调用的是 Dog 的 watchHouse 【运行报错】    }  
}
public class Test {public static void main(String[] args) {// 向上转型  Animal a = new Cat();  a.eat();               // 调用的是 Cat 的 eat// 向下转型  if (a instanceof Cat){Cat c = (Cat)a;       c.catchMouse();        // 调用的是 Cat 的 catchMouse        } else if (a instanceof Dog){Dog d = (Dog)a;       d.watchHouse();       // 调用的是 Dog 的 watchHouse}}  
}

分析:

这段代码可以通过编译,但是运行时,却报出了ClassCastException类型转换异常!这是因为,明明创建了Cat类型对象,运行时,当然不能转换成Dog对象的。这两个类型并没有任何继承关系,不符合类型转换的定义。

为了避免ClassCastException的发生,Java提供了instanceof关键字,给引用变量做类型的校验。

  •  instanceof使用格式

变量名 instanceof 数据类型 
    如果变量属于该数据类型,返回true。
    如果变量不属于该数据类型,返回false。 

  • instanceof代码示例
public class Test {public static void main(String[] args) {// 向上转型  Animal a = new Cat();  a.eat();               // 调用的是 Cat 的 eat// 向下转型  if (a instanceof Cat){Cat c = (Cat)a;       c.catchMouse();        // 调用的是 Cat 的 catchMouse        } else if (a instanceof Dog){Dog d = (Dog)a;       d.watchHouse();       // 调用的是 Dog 的 watchHouse}}  
}

无论发生什么,都不要放弃自己~      新的一天开开心心,快快乐乐~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/788929.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

不同设备使用同一个Git账号

想要在公司和家里的电脑上用同一个git账号来pull, push代码 1. 查看原设备的用户名和邮箱 第1种方法, 依次输入 git config user.name git config user.email第2种方法, 输入 cat ~/.gitconfig2. 配置新设备的用户名和邮箱 用户名和邮箱与原设备保持…

rocketmq管理工具rocketmq-console安装

rocketmq-console是一个图形化管理控制台,提供Broker集群状态查看,Topic管理,Producer、Consumer状态展示,消息查询等常用功能,这个功能在安装好RocketMQ后需要额外单独安装、运行。 中文文档地址:https:/…

【RedHat9.0】引导装载程序GRUB——root密码丢失实例

root用户密码忘记了?!!!怎么办!!! 在Linux系统中,root密码是系统管理员权限的凭证。 如果忘记了root密码,就无法以管理员身份登录系统,这可能会对系统安全和正…

C++核心高级编程 --- 1、内存分区模型 2、引用

文章目录 第一章:1.内存分区模型1.1 程序运行前1.2 程序运行后1.3 new操作符 第二章:2.引用2.1 使用2.2 注意事项2.3 做函数参数2.4 做函数返回值2.5 本质2.6 常量引用 第一章: 1.内存分区模型 4个区域: 代码区:存放…

Python可视化概率统计和聚类学习分析生物指纹

🎯要点 🎯使用Jupyter Notebook执行Dash 应用,确定Dash输入输出,设计回调函数,Dash应用中包含函数。🎯使用Plotly绘图工具:配置图对象选项,​将图转换为HTML、图像。使用数据集绘图…

健身房最重的是前门

你可以将任何你想做的事情 比如 一年读30本书 变成一周读一页 做四天瑜伽 变成拿出瑜伽垫 我知道真正的目的不只是拿出瑜伽垫 我知道我其实是想锻炼身体 这只是某种心理上的把戏 虽然暂时不会得到想要的结果 但退一步往远看 其实是在掌握“持续出现”的习惯 这让我们…

【mysql 第3-10条记录怎么查】

mysql 第3-10条记录怎么查 在MySQL中,如果你想要查询第3到第10条记录,你通常会使用LIMIT和OFFSET子句。但是,需要注意的是,LIMIT和OFFSET是基于结果集的行数来工作的,而不是基于记录的物理位置。这意味着它们通常与某种…

【C++庖丁解牛】高阶数据结构---红黑树详解(万字超详细全面介绍红黑树)

🍁你好,我是 RO-BERRY 📗 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 目录 前言1.红黑树的概念2.红黑…

vue + vite 项目架构笔记---- PC端屏幕自适应方案

背景: 项目中总有很多界面 需要做大小屏幕适配的兼容,那么怎么能够快速实现这一方案呢,SASS的出现是个非常好用的工具,可以通过自定义函数,来实现自动计算。 方案:vue3 vite sass 具体实现细节&#x…

开发环境搭建及驱动移植 2

1 开发环境搭建 前言: STD库-标准外设库 寄存器操作,将一些基本的寄存器操作封装成函数 HAL库-硬件抽象库将这些抽象成了一个抽象层,从使用的角度来看,是与硬件无关的 HAL库优势HAL库是ST未来主推的库,从2015开始ST…

探索Django:打造高效、可扩展的Web应用(终)

10. Django的静态文件管理与部署 配置静态文件路径收集静态文件部署Django应用 在Django应用程序中,静态文件(例如CSS、JavaScript、图像等)的管理和部署是非常重要的,它们用于美化网页样式、增强用户交互体验等。本节将详细介绍…

STM32重要参考资料

stm32f103c8t6 一、引脚定义图 二、时钟树 三、系统结构图 四、启动配置 (有时候不小心短接VCC和GND,芯片会锁住,可以BOOT0拉高试试(用跳线帽接)) 五、最小系统原理图 可用于PCB设计

C++类 单例模式

例子 请看如下的类和调用: 在您提供的代码片段中,CPathPlanMan 类使用了一个单例模式,这意味着这个类只需要一个实例,并且提供了全局访问点来获取这个实例。这通常用于控制对一个类实例的访问,尤其是在创建实例代价昂…

BetterZip for Mac2024最新mac解压缩软件

作为一名软件专家,对于市面上各类软件都有较为深入的了解,下面介绍的是一款适用于Mac系统的解压缩软件——BetterZip,将从其功能特点、使用方法、用户体验及适用人群等方面进行详细介绍。 BetterZip5-安装包绿色版下载如下: htt…

AWS相关服务说明

互联网网关 官网 # 官网 https://docs.aws.amazon.com/zh_cn/vpc/latest/userguide/VPC_Internet_Gateway.htmlInternet 网关是一种横向扩展、冗余且高度可用的 VPC 组件,支持在 VPC 和 Internet 之间进行通信。它支持 IPv4 和 IPv6 流量。它不会对您的网络流量造…

某音乐平台歌曲信息逆向之参数寻找

如何逆向加密参数:某音乐平台歌曲信息逆向之webpack扣取-CSDN博客 参数构建 {"comm": {"cv": 4747474,"ct": 24,"format": "json","inCharset": "utf-8","outCharset": "ut…

XML与Xpath

XML与Xpath XML是一种具有某种层次结构的文件,Xpath则是解析这种文件的工具 接下来将会解释XML文件的结构和Xpath的基本使用,并且用Java语言进行操作展示。 XML结构 XML(可扩展标记语言)文件具有一种层次结构,由标签…

c++11 标准模板(STL)本地化库 - 平面类别 - (std::ctype) 定义字符分类表(二)

本地化库 本地环境设施包含字符分类和字符串校对、数值、货币及日期/时间格式化和分析&#xff0c;以及消息取得的国际化支持。本地环境设置控制流 I/O 、正则表达式库和 C 标准库的其他组件的行为。 平面类别 定义字符分类表 std::ctype template< class CharT > clas…

Maven是什么? Maven的概念+作用

1.Maven的概念 Maven中文意思为“专家“、”内行“的意思&#xff0c;它是一个项目管理工具&#xff0c;可以对Java项目进行构建、依赖管理&#xff0c;通俗点 就是通过pom.xml文件的配置获取jar包不用手动的去添加jar包。 2.Maven的作用 对于大的工程&#xff0c;需要引用各…

jaihouse介绍

本文来自jaihouse在github上的仓库readme第一段。 https://github.com/siemens/jailhouse?tabreadme-ov-file 原文&#xff1a; Introduction Jailhouse is a partitioning Hypervisor based on Linux. It is able to run bare-metal applications or (adapted) operating …