java--多态(详解)
目录
- 一、概念
- 二、多态实现的条件
- 三、向上转型和向下转型
- 3.1 向上转型
- 3.2 向下转型
- 四、重写和重载
- 五、理解多态
- 5.1练习:
- 5.2避免在构造方法中调用重写的方法:
欢迎来到权权的博客~欢迎大家对我的博客提出指导
这是我的博客主页:点击
一、概念
通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同 的状态。
二、多态实现的条件
在java中要实现多态,必须要满足如下几个条件,缺一不可:
- 必须在继承体系下
- 子类必须要对父类中方法进行重写
- 通过父类的引用调用重写的方法
三、向上转型和向下转型
3.1 向上转型
三种向上转型的方式:
1.直接赋值
Animals animals=new Dog("小狗",6);
2.方法的传参
public static void func(Animals animal){}public static void main(String[] args) {Dog dog=new Dog("x",6);func(dog);}
3.返回值
public static Animals func2(){Dog dog=new Dog("x",56);return dog;}public static void main(String[] args) {Animals animals=func2();}
}
缺点:通过父类的引用不能调用子类的方法
3.2 向下转型
向下转型无非就是把一个父类引用放着子类对象,然后强转成对应的子类类型在赋值给子类引用,也就是将父类引用还原成子类对象。
class TestAnimal {public static void main(String[] args) {//向下转型 -> 不安全//instanceof 判断animal引用的对象是不是Dog类型的,如果是则为 true 不是则为 falseAnimal animal = new Dog("王五", 12);if (animal instanceof Dog) {Dog dog = (Dog)animal;dog.eat();}}
}
四、重写和重载
重写(override):也称为覆盖。重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!重写的好处在于子类可以根据需要,定义特定于自己的行为。也就是说子类能够根据需要实现父类的方法。
【方法重写的规则】:
子类在重写父类的方法时,一般必须与父类方法原型一致:返回值类型方法名 (参数列表) 要完全一致被重写的方法返回值类型可以不同,但是必须是具有父子关系的。
访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为 protected父类被static、private修饰的方法、构造方法都不能被重写。
重写的方法, 可以使用@Override注解来显式指定. 有了这个注解能帮我们进行一些合法性校验. 例如不小心将方法名字拼写错了 (比如写成 aet), 那么此时编译器就会发现父类中没有 aet 方法, 就会编译报错, 提示无法构成重写.
在子类中对父类的方法进行重写
方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。
public class TestMethod {
public static void main(String[] args) {
add(1, 2); // 调用add(int, int)
add(1.5, 2.5); // 调用add(double, double)
add(1.5, 2.5, 3.5); // 调用add(double, double, double)
}
public static int add(int x, int y) {
return x + y;
}
public static double add(double x, double y) {
return x + y;
}
public static double add(double x, double y, double z) {
return x + y + z;
}
}
【重写和重载的区别】
五、理解多态
可以看到animals引用的对象是不一样的,但是调用的是同一个方法,此时表现出的不同现象我们叫做多态。
5.1练习:
打印指定不同图案(多态实现):
public class Drawing {public void draw() {System.out.println("画图");}
}
class DrawCircle extends Drawing {@Overridepublic void draw() {System.out.print("⚪");}
}
class DrawFlower extends Drawing {@Overridepublic void draw() {System.out.print("❀");}
}
class DrawTriangle extends Drawing {@Overridepublic void draw() {System.out.print("▲");}
}
第一种方法:用 for-each语句
class TestDraw {//方法一:使用 循环 + if elsepublic static void draw1() {DrawTriangle triangle = new DrawTriangle();DrawFlower flower = new DrawFlower();DrawCircle circle = new DrawCircle();String[] shapes = {"Triangle", "Flower", "Flower", "Circle", "Flower", "Triangle"};//增强for循环遍历数组for (String s : shapes) {if (s.equals("Triangle")) {triangle.draw();} else if (s.equals("Flower")) {flower.draw();} else if (s.equals("Circle")) {circle.draw();}}}public static void main(String[] args) {draw1();}
}
第二种用多态
class TestDraw {public static void draw2() {Drawing[] shapes = { new DrawTriangle(), new DrawFlower(), new DrawFlower(),new DrawCircle(), new DrawFlower(), new DrawTriangle()};for (Drawing s : shapes) {s.draw();}}public static void main(String[] args) {draw2();}
}
多态部分的优点:
可以有效降低代码复杂度,避免出现多个 if else可扩展性更强,如果要新增打印,也更简单
多态的缺点:
属性没有多态性,当父类属性和子类属性同名,通过父类引用只能调用父类自己的成员属性构造方法也没有多态性
5.2避免在构造方法中调用重写的方法:
class A {public A() {func();}public void func() {System.out.println("A.func()");}
}
class B extends A {private int num = 1;@Overridepublic void func() {System.out.println("B.func() " + num);}
}
public class Test {public static void main(String[] args) {A b = new B();}
}
可以看到构造 D 对象的同时, 会调用 B 的构造方法。
B 的构造方法中调用了 func 方法, 此时会触发动态绑定, 会调用到 D 中的 func此时 D >对象自身还没有构造, 此时 num 处在未初始化的状态, 值为 0.。
如果具备多态性,num的值应该是1.所以在构造函数内,尽量避免使用实例方法,除了final和private方法。
结论: “用尽量简单的方式使对象进入可工作状态”, 尽量不要在构造器中调用方法(如果这个方法被子类重写, 就会触发动态绑定, 但是此时子类对象还没构造完成), 可能会出现一些隐藏的但是又极难发现的问题。
欧耶!!!我学会啦!!!
相关文章:

java--多态(详解)
目录 一、概念二、多态实现的条件三、向上转型和向下转型3.1 向上转型3.2 向下转型 四、重写和重载五、理解多态5.1练习:5.2避免在构造方法中调用重写的方法: 欢迎来到权权的博客~欢迎大家对我的博客提出指导这是我的博客主页:点击 一、概念…...
windows DLL技术-DLL概述
动态链接库 (DLL) 是一个模块,其中包含可由另一个模块 (应用程序或 DLL) 使用的函数和数据。 DLL 可以定义两种类型的函数:导出函数和内部函数。 导出的函数旨在由其他模块调用,以及从定义它们的 DLL 中调用。 内部函数通常只能从定义内部函…...

C++ —— 实现一个日期类
目录 一. 对日期类的介绍 二. 实现日期类 1. 运算符重载 2.日期类实现代码 一. 对日期类的介绍 通过对类和对象(这里链接是类和对象的介绍)的学习,类就是一种模型一样的东西,是对象一种抽象的描述。所以实现日期类࿰…...

Java全栈经典面试题剖析5】JavaSE高级 -- 集合
目录 面试题3.18 Java中有多少种数据结构,分别是什么? 面试题3.19 List、Set和Map的区别? 面试题3.20 List遍历方式有多少种 面试题3.21 Arraylist,Vector和Linkedlist 的区别 面试题3.22 Collection和Collections的区别 面试…...
python中如何获取对象信息
目录 一、获取对象类型 二、使用isinstance()函数 三、使用dir()函数 四、使用对象的__dict__属性(适用于大多数自定义对象) 五、使用文档字符串(__doc__属性)获取对象的文档信息 一、获取对象类型 使用type()函数ÿ…...
逐行讲解transformers中model.generate()源码
目录 简介输入程序model.generate()输入参数1. 创建生成参数对象 generation_config2. 初始化部分输入参数3. 定义模型输入4. 定义其他模型参数5. 准备 input_ids6. 准备 max_length7. 确定生成模式8. 准备 logits 处理器9. 准备 stopping 处理器10. 执行生成 self._sample1. 先…...
小白对时序数据库的理解
一、什么是时序数据库? 时序数据库(Time Series Database,TSDB)是一种专门用于存储、处理和分析时间序列数据的数据库管理系统。时间序列数据是按时间顺序记录的数据,通常由各种设备和传感器生成,例如智慧…...

打开游戏提示丢失(或找不到)XINPUT1_3.DLL的多种解决办法
xinput1_3.dll是一个动态链接库(DLL)文件,它在Windows操作系统中扮演着重要的角色。该文件作为系统库文件,通常存放于C:\Windows\System32目录下(对于32位系统)或C:\Windows\SysWOW64目录下(对于…...
netty的网络IO模型
参考: 聊聊Netty那些事儿之从内核角度看IO模型...

电子木鱼小游戏小程序源码系统 带完整的安装代码包以及搭建部署教程
系统概述 在快节奏的生活中,人们越来越注重内心的平静与放松。电子木鱼小游戏小程序正是基于这一需求而诞生的,它将传统的木鱼文化与现代科技相结合,为用户提供了一个简单、方便、有趣的冥想与放松工具。通过敲击屏幕上的虚拟木鱼࿰…...
支付域——交易系统设计
摘要 交易是业务流转的基础,其中交易系统和订单系统的设计至关重要。交易系统需确保安全、高效与稳定。在设计时,要考虑支付方式的多样性及兼容性,保障资金流转的准确与安全。同时,应具备良好的风险控制机制,防范欺诈等风险。订单系统则负责记录和管理交易的全过程。需清…...
IBus 和 Fcitx 框架下的rime输入法引擎
Rime 输入法引擎 Rime(中州韵输入法引擎):这是一个跨平台的输入法引擎,支持多种输入法方案,如拼音、五笔、注音等。Rime本身不提供前端界面,它需要与输入法框架(如IBus或Fcitx)结合…...

Java基础-JVM
JVM构成部分 类加载系统 类加载子系统的作用是将磁盘中的.class文件加载到内存当中。工作过程如下: 加载:通过类全路径名获取二进制字节流;将这个二进制字节流代表的数存储构转化为方法区运行时数据结构;在内存生成一个代表该类的…...
集成学习:投票法、提升法、袋装法
集成学习:投票法、提升法、袋装法 目录 🗳️ 投票法 (Voting)🚀 提升法 (Boosting)🛍️ 袋装法 (Bagging) 1. 🗳️ 投票法 (Voting) 投票法是一种强大的集成学习策略,它通过将多个模型的预测结果进行组合…...

波浪理论、江恩理论、价值投资的结合
结合波浪理论、江恩理论和价值投资,需要理解这三种方法的核心原理和应用方式。下面详细解析如何将它们融合在一起,形成一个更全面的投资策略: 1. 基本概述 波浪理论:由艾略特提出,通过分析市场波动的五个上升浪和三个…...

LRDDR4芯片学习(三)——命令和时序
ddr command: activate commandrefresh commandprecharge commandwrite/read commandburst write/read commandMRR/MRW command 一、Activate命令 在读写命令之前,必须要发送Activate命令,由ACTIVATE-1、ACTIVATE-2命令组成。ACTIVATE命令中包含了BA[…...
【趣学C语言和数据结构100例】
【趣学C语言和数据结构100例】 问题描述 61.假定采用带头结点的单链表保存单词,当两个单词有相同的后缀时,可共享相同的后缀存储空间,例如,loading 和 being 的存储映像如下图所示,设 strl 和 str2 分别指向两个单词所在单链表的头结点,链表结点结构为 data next。请设计…...

linux卸载数据库(最为完整的卸载方式)
1.首先检查是否安装了MySQL组件 我们可以看到有五个与mysql相关的组件 2.卸载前关闭MySQL服务 systemctl stop mysqld systemctl status mysqld 3.收集MySQL对应的文件夹信息 whereis mysql 4.卸载删除MySQL各类组件 #例如 rpm -ev --nodeps mysql-community-libs-5.7.…...

H7-TOOL的LUA小程序教程第15期:电压,电流,NTC热敏电阻以及4-20mA输入(2024-10-21,已经发布)
LUA脚本的好处是用户可以根据自己注册的一批API(当前TOOL已经提供了几百个函数供大家使用),实现各种小程序,不再限制Flash里面已经下载的程序,就跟手机安装APP差不多,所以在H7-TOOL里面被广泛使用ÿ…...
使用梧桐数据库进行销售趋势分析和预测
在当今竞争激烈的商业环境中,企业需要深入了解销售数据,以便做出明智的决策。销售趋势分析和预测是帮助企业把握市场动态、优化库存管理、制定营销策略的重要工具。本文将介绍如何使用SQL来创建销售数据库的表结构,插入示例数据,并…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统
Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...

Python环境安装与虚拟环境配置详解
本文档旨在为Python开发者提供一站式的环境安装与虚拟环境配置指南,适用于Windows、macOS和Linux系统。无论你是初学者还是有经验的开发者,都能在此找到适合自己的环境搭建方法和常见问题的解决方案。 快速开始 一分钟快速安装与虚拟环境配置 # macOS/…...
Yii2项目自动向GitLab上报Bug
Yii2 项目自动上报Bug 原理 yii2在程序报错时, 会执行指定action, 通过重写ErrorAction, 实现Bug自动提交至GitLab的issue 步骤 配置SiteController中的actions方法 public function actions(){return [error > [class > app\helpers\web\ErrorAction,],];}重写Error…...
【Java】Ajax 技术详解
文章目录 1. Filter 过滤器1.1 Filter 概述1.2 Filter 快速入门开发步骤:1.3 Filter 执行流程1.4 Filter 拦截路径配置1.5 过滤器链2. Listener 监听器2.1 Listener 概述2.2 ServletContextListener3. Ajax 技术3.1 Ajax 概述3.2 Ajax 快速入门服务端实现:客户端实现:4. Axi…...
软件工程教学评价
王海林老师您好。 您的《软件工程》课程成功地将宏观的理论与具体的实践相结合。上半学期的理论教学中,您通过丰富的实例,将“高内聚低耦合”、SOLID原则等抽象概念解释得十分透彻,让这些理论不再是停留在纸面的名词,而是可以指导…...
第21节 Node.js 多进程
Node.js本身是以单线程的模式运行的,但它使用的是事件驱动来处理并发,这样有助于我们在多核 cpu 的系统上创建多个子进程,从而提高性能。 每个子进程总是带有三个流对象:child.stdin, child.stdout和child.stderr。他们可能会共享…...