JavaSE-多态

多态的概念

        在完成某个行为时,不同的对象在完成时会呈现出不同的状态。

比如:动物都会吃饭,而猫和狗都是动物,猫在完成吃饭行为时吃猫粮,狗在完成吃饭行为时吃狗粮,猫和狗都会叫,狗在完成这个行为时会狗叫,而哈基米会哈气。

在编程中,多态是指利用子类继承父类的特性在使用对象时达到简化代码的目的。

多态的实现条件

在java中要实现多态,必须要满足如下几个条件,缺一不可:
1. 必须在继承体系下
2. 子类必须要对父类中方法进行重写
3. 通过父类的引用调用重写的方法
多态体现:在代码运行时,当传递不同类对象时,会调用对应类中的方法。

下面是简单的示例:

public class Animal {public String name;public int age;public Animal(String name,int age) {this.name = name;this.age = age;}public void cry(){System.out.println(name+"正在叫---");}}public class Dog extends Animal{public Dog(String name,int age){super(name,age);}public void cry(){System.out.println(name+"正在狗叫---");}
}ublic class Cat extends Animal{public Cat(String name,int age){super(name,age);}public void cry(){System.out.println(name+"正在哈气---");}
}public class test {public static void main(String[] args) {Animal dog = new Dog("富贵",3);Animal cat = new Cat("哈吉米",4);dog.cry();cat.cry();}
}

运行结果:

在父类Animal和子类Dog与Cat中都有名为cry的方法,我们可以发现在主方法实例化子类后调用的cry均为子类本身的方法,这种现象就称之为多态。 

重写

重写(override):也称为覆盖。重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

【方法重写的规则】
1.子类在重写父类的方法时,一般必须与父类方法原型一致: 返回值类型 方法名 (参数列表) 要完全一致
2.被重写的方法返回值类型可以不同,但是必须是具有父子关系的
3.访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为 protected
4.父类被static、private修饰的方法、构造方法都不能被重写。
5.重写的方法, 在编译器中使用 @Override 注解来显式指定. 有了这个注解能帮我们进行一些合法性校验. 例如不小心将方法名字拼写错了 (比如写成 aet), 那么此时编译器就会发现父类中没有 aet 方法, 就会编译报错, 提示无法构成重写。

方法的重写与重载的区别:

在重写中,两个方法的参数列表必须相同,返回类型必须相同或者构成父子关系,访问权限限定符必须相同或者更宽松,而在重载中,参数列表必须不同才能构成重载,返回类型可以随意修改,访问权限限定符可以随意修改。 

静态绑定:也称为前期绑定(早绑定),即在编译时,根据用户所传递实参类型就确定了具体调用那个方法。典型代表函数重载。
动态绑定:也称为后期绑定(晚绑定),即在编译时,不能确定方法的行为,需要等到程序运行时,才能够确定具体调用那个类的方法,典型代表函数重写。

两种转型

向上转型

概念;创建一个子类对象,将其作为父类对象来使用。

语法格式:父类类型 对象名 = new 子类类型();

 

由于父类包含子类,父类是大范围,子类是小范围,所以这种转型就是一种父类对子类的引用。

 向上转型的使用场景:

1.直接赋值

Animal dog = new Dog("富贵",3);

将子类直接赋值给父类。 

2.方法传参

public void AnimalCry(Animal a){a.cry();}

在方法的参数列表中使用父类Animal声明,在传参时就可以传入子类Cat和Dog。 

3.方法返回值

public Animal buyAnimal(int a){if(a==1){return new Cat("猫猫",1);}else if(a==2){return new Dog("狗狗",1);}else{return null;}}

示例:

public class test {public static void animalCry(Animal a){a.cry();}public static Animal buyAnimal(int a){if(a==1){return new Cat("猫猫",1);}else if(a==2){return new Dog("狗狗",1);}else{return null;}}public static void main(String[] args) {Animal dog = new Dog("富贵",3);Animal cat = new Cat("哈吉米",4);animalCry(dog);animalCry(cat);Animal sweet = buyAnimal(1);sweet.cry();sweet = buyAnimal(2);sweet.cry();}
}

在主方法中,我们首先实例化Dog和Cat,然后将两个子类对象传参给animalCry,然后用sweet接受buyAnimal返回的子类对象。这里就使用到了三种向上转型的场景。

向上转型的优点:使代码更加方便简洁。

向上转型的缺点:不能使用子类特有的方法。

向下转型

将一个子类对象向上转型为父类对象后,无法在使用子类特有的方法,此时需要用到向下转型。

public class Animal {public String name;public int age;public Animal(String name,int age) {this.name = name;this.age = age;}public void cry(){System.out.println(name+"正在叫---");}}public class Dog extends Animal{public Dog(String name,int age){super(name,age);}public void cry(){System.out.println(name+"正在狗叫---");}public void eatBone(){System.out.println(name+"正在啃骨头---");}
}public class Cat extends Animal{public Cat(String name,int age){super(name,age);}public void cry(){System.out.println(name+"正在哈气---");}public void eatFish(){System.out.println(name+"正在吃鱼---");}
}public class test {public static void main(String[] args) {Dog dog = new Dog("富贵",3);Cat cat = new Cat("哈吉米",4);//向上转型Animal animal =cat;animal.cry();animal=dog;animal.cry();animal.eatBone();//这里编译器会将animal作为Animal对象处理//而Animal类中没有eatBone方法//所以会编译报错cat = (Cat)animal;cat.eatFish();//这里对animal进行强制类型转换为cat//但是animal在向上转换之前指向的实际是dog//所以这里在运行时会出现异常dog=(Dog)animal;dog.eatBone();}
}

删除错误代码后的运行结果:

为了确保向下转型时的安全性,Java引入了instanceof关键字

当(a instanceof b )为真时,代表a为b类实例化的对象,以此判断a的类型。 

多态的优缺点

优点

假设有如下父类和子类:

class Shape {public void draw() {System.out.println("画图形!");}}
class Rect extends Shape{public void draw() {System.out.println("♦");}
}
class Cycle extends Shape{public void draw() {System.out.println("●");}
}
class Flower extends Shape{public void draw() {System.out.println("❀");}
}

如果我们不使用多态思想,那么需要这样打印这些图形:

public static void drawShapes() {Rect rect = new Rect();Cycle cycle = new Cycle();Flower flower = new Flower();String[] shapes = {"cycle", "rect", "cycle", "rect", "flower"};for (String shape : shapes) {if (shape.equals("cycle")) {cycle.draw();} else if (shape.equals("rect")) {rect.draw();} else if (shape.equals("flower")) {flower.draw();}}}

使用多态思想:

public static void drawShapes() {// 我们创建了一个 Shape 对象的数组.Shape[] shapes = {new Cycle(), new Rect(), new Cycle(), new Rect(), new Flower()};for (Shape shape : shapes) {shape.draw();}}

两种方法输出相同,代码量却相去甚远:

我们可以看出多态思想为我们省去了许多if-else分支,降低了代码的圈复杂度 ,这就是多态的第一个优点。

多态的第二个优点时可扩展性强,如果新增一种形状,使用多态的方法改动也更加简洁:

class Triangle extends Shape {public void draw() {System.out.println("△");}
}

缺点

1. 属性没有多态性
当父类和子类都有同名属性的时候,通过父类引用,只能引用父类自己的成员属性
2. 构造方法没有多态性

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

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

相关文章

TDengine 使用最佳实践(2)

TDengine 使用最佳实践(1) 安装部署 目录规划 软件安装 参数配置 时钟同步 验证环境 集群部署 写入查询 连接方式 数据写入 数据查询 运维巡检 运维规范 数据库启停 状态检查 运维技巧 日常巡检 数据库升级 故障排查 故障定位 日志调试 故障反馈 关于 T…

如何通过公网IP访问部署在kubernetes中的服务?

背景说明我们有些私有化部署的项目,使用k8s来承载服务,通过ingress-nginx转发外部的请求到集群。有时候业主的域名没有申请下来,我们会配置临时的域名,测试同事配置主机hosts来完成功能验证,等功能验证完毕后&#xff…

Datawhale AI 夏令营2025科大讯飞AI大赛<夏令营:用AI做带货视频评论分析>

赛题题目 任务一:商品识别 基于视频内容识别对应的商品 【情感分析】对评论文本进行多维度情感分析,涵盖维度见数据说明; 任务二(文本分类):从非结构化评论中提取情感倾向 评论聚类】按商品对归属指定维度的…

AI 时代的分布式多模态数据处理实践:我的 ODPS 实践之旅、思考与展望

AI 时代的分布式多模态数据处理实践:我的 ODPS 实践之旅、思考与展望 🌟嗨,我是LucianaiB! 🌍 总有人间一两风,填我十万八千梦。 🚀 路漫漫其修远兮,吾将上下而求索。 目录 1. 什…

硬件工程师笔试面试高频考点汇总——(2025版)

目录 1 电子器件部分 1.1 电阻 1.1.1 电阻选型时一般从哪几个方面进行考虑? 1.1.2 上拉下拉电阻的作用 1.1.3 PTC热敏电阻作为电源电路保险丝的工作原理 1.1.4 如果阻抗不匹配,有哪些后果 1.1.5 电阻、电容和电感0402、0603和0805封装的含义 1.1.6 电阻、电…

华为HarmonyOS 5.0深度解析:跨设备算力池技术白皮书(2025全场景智慧中枢)

​​摘要​​HarmonyOS 5.0的​​跨设备算力池技术​​正在重构终端计算范式。本文首次系统性拆解其技术内核:通过​​异构硬件资源虚拟化​​、​​任务流图调度引擎​​、​​确定性时延网络​​三大支柱,实现手机、汽车、智慧屏等设备的算力动态聚合与…

ASP.NET Core 中的延迟注入:原理与实践

在软件开发中,依赖注入已成为构建可维护、可测试和可扩展应用程序的核心模式。ASP.NET Core 内置的依赖注入容器为我们管理服务生命周期提供了极大的便利。然而在某些特定场景下,我们可能不希望某个依赖项在宿主对象被创建时立即实例化,而是希…

PHP内存溢出问题的深度分析与系统解决方案

文章目录一、问题本质:什么是PHP内存溢出?内存管理核心原理二、高频内存溢出场景深度解析场景1:大数据集不当处理场景2:无限递归陷阱场景3:实体关系映射(ORM)的N1问题场景4:未及时释…

常见 HTTP 方法的成功状态码200,204,202,201

HTTP 协议中,操作成功后的状态码选择取决于操作类型和响应内容,并非所有非 GET/POST 请求都返回 204。以下是常见 HTTP 方法的成功状态码规范:1. GET200 OK:默认成功状态码,表示请求成功且返回了资源内容。206 Partial…

【论文阅读】Think Only When You Need with Large Hybrid-Reasoning Models

Think Only When You Need with Large Hybrid-Reasoning Models2 Large Hybrid-Reasoning Models2.1 Problem Formulation关键定义与目标核心挑战与解决方案2.2 第一阶段:混合微调(Hybrid Fine-Tuning, HFT)核心设计数据构建数据集统计优化目…

洛谷 P13014:[GESP202506 五级] 最大公因数

【题目来源】 https://www.luogu.com.cn/problem/P13014 【题目描述】 对于两个正整数 ,他们的最大公因数记为 。对于 个正整数 ,他们的最大公因数为: 给定 个正整数 以及 组询问。对于第 组询问,请求出 的最大公因数&…

构建应用内智能:衡石嵌入式BI如何打造“指标中台”驱动的场景化分析

在当今数据驱动的业务环境中,将智能分析能力深度嵌入业务应用(如CRM、ERP、SCM、自研SaaS)已成为刚需。然而,实现高性能、一致性、可治理的嵌入式分析面临巨大技术挑战。衡石科技通过其核心的指标中台(Metric Platform…

带货视频评论洞察 Baseline 学习笔记 (Datawhale Al夏令营)

一、 项目认识背景:电商直播/短视频已积累大量「视频 评论」数据,蕴含了消费者的真实反馈。目标:通过「商品识别 → 情感分析 → 评论聚类」三步,辅助品牌洞察、网红投放评估。二、 Baseline 代码流程1. 读取和预处理video_data …

uniapp中使用uView-plus踩坑记录

​​​1.使用插件市场安装点击到插件市场 零云uview-plus3.0重磅发布,全面的Vue3鸿蒙移动组件库。 - DCloud 插件市场 点击选择项目直接导入就可以,下载完成后会在uni_modules中,这个.gitignore中不可忽略 ​ 使用在main.js里引入 import…

openGauss数据库管理实战指南——基本常用操作总结

查看所有数据库 查看所有表 \d 查看函数定义 查看所有用户 select usename from pg_user; 1.数据库创建管理 CREATE DATABASE test; 2.数据库用户创建管理 CREATE USER tom PASSWORD Root123456.; 3.表的创建及管理 3.1.创建表 CREATE TABLE test(ID INTEGER PRIMARY …

智慧公安信息化建设解决方案PPT(63页)

智慧公安的定义与职能 智慧公安是利用现代信息技术提升公安工作效率与服务质量的新模式,涵盖刑事侦查、治安管理、交通管理等多方面职能,致力于保障社会安全与秩序。 智慧公安信息化建设的重要性 信息化建设是智慧公安发展的核心,通过数据…

k8s存储入门

目录 一、 Volume 的概念 二、 Volume 的类型 三、 通过 emptyDir 共享数据 1. EmptyDir 特性 2. EmptyDir 共享数据 四:使用 HostPath 挂载宿主机文件 1. HostPath 特性 2. 挂载宿主机时区文件 五、 挂载 NFS 至容器 1. 前置准备(所有 K8s 节…

基于 Flutter 的开源文本 TTS 朗读器(支持 Windows/macOS/Android)

界面特性 基于 Flutter 的文本 TTS 朗读器支持 Windows、macOS、AndroidTTS 源:OpenAI TTS、Microsoft TTS支持设置代理支持设置应用主题支持倍速支持书签支持点击指定地方朗读支持 txt、epub、贴粘文本支持从上次地方开始朗读 源代码https://github.com/xchenhao/t…

深入理解大语言模型:从核心技术到极简实现

零基础的读者建议先看《零基础理解大语言模型:从生活例子到代码实现》,本教程的完整代码可以在GitHub上找到,如果你有任何问题或建议,欢迎交流讨论。 引言 自ChatGPT横空出世以来,大语言模型(Large Langua…

7月13日日记

看来每天写一篇日记对我来说还是一个不小的挑战。主要是和惰性做抗争吧。但是这个东西说实话也没有什么难度,也并不占用时间,一篇日记大概十几分钟就可以写完。可能更多的是健忘。忘了每天有一个这样的小任务。忘了前几天日记写没写了,三下乡…