当前位置: 首页 > news >正文

「JavaSE」类和对象3

🎇个人主页:Ice_Sugar_7
🎇所属专栏:快来卷Java啦
🎇欢迎点赞收藏加关注哦!

类和对象3

  • 🍉多态
    • 🍌重写
    • 🍌向上转型&向下转型
    • 🍌静态绑定&动态绑定
    • 🍌多态的利弊
  • 🍉写在最后

🍉多态

概念:对于同一个行为,不同的对象去做,会产生不同的状态
比如对于吃这个行为,狗这个对象去做的话就是吃狗粮;猫去做的话就是吃猫粮
再比如,对于景区买票这个行为,学生去做的话就是买学生票;儿童去做的话就是买儿童票;成人去做的话就是买成人票

java中的多态指同一个方法可以根据接收的不同参数类型,产生不同的行为
要实现多态,必须同时满足以下几个条件:

  • 子类必须要对父类中方法进行重写
  • 必须在继承体系下实现向上转型
  • 通过父类的引用调用重写的方法

下面对这些条件一一讲解

🍌重写

继承关系上,如果满足:

  • 方法名一样
  • 方法的参数列表一样

那我们就说这两个方法之间的关系是重写
举个例子:

public class Animal {public String name;public int age;public void eat() {System.out.println(name+"正在吃饭");}
}public class Dog extends Animal{public String color;@Overridepublic void eat() {System.out.println(name+"在吃狗粮");}
}

父类中有一个eat方法,而子类中也有一个,不同点在于它们所吃的东西不同(一个吃饭、一个吃狗粮)

重写的规则:

  • 被重写的父类方法不能被private、final修饰,并且不是构造方法、静态方法
  • 被重写的方法返回值类型可以不同,但必须具有父子关系
  • 子类方法的访问权限不能低于父类中被重写方法的访问权限。比如父类方法被public修饰,那子类中重写的方法就不能声明为 protected
  • 重写的方法可以使用 @Override 注解来显式指定,它能帮我们进行校验,确保顺利重写

重写和重载的区别:
在这里插入图片描述

🍌向上转型&向下转型

一、向上转型
创建一个子类对象,但是用父类引用来引用它
语法格式:父类类型 对象名 = new 子类类型()

Animal animal = new Cat("Mimi",1);

Animal是父类类型,但可以引用一个子类对象,因为是从小范围大范围的转换(子类是小范围,父类是大范围,这就类似隐式类型转换),安全性很好

常见的可以发生向上转型的场景:

  1. 直接赋值
    这个就是刚才上面所举的例子

  2. 方法传参
    形参为父类引用,可以接收任意子类对象

public static void eat(Animal a){a.eat();
}public static void main(String[] args) {Cat cat = new Cat("Mimi",1);eat(cat);
}
  1. 作为返回值返回
    方法的返回类型为父类类型,返回任意子类对象
public Animal func() {Dog dog = new Dog();return dog;
}

向上转型可以提高代码的灵活性、通用性比如说有一个方法的参数类型是Animal类,那它就可以接收Dog类、Cat类、Bird类等实参,而且根据传递的对象的类型,确定要使用哪个对象的具体表现(比如传Dog类就表现出跑的动作,而传Bird类就表现出飞的动作),这就是我们所讲的多态

二、向下转型
将一个子类对象向上转型之后,它不能调用子类特有的属性、方法,但有时候可能需要调用子类特有的方法,所以将父类引用再还原为子类对象即可,即向下转型
简而言之就是:父类强制类型转换之后给子类。从谁转型上来的,就转下去成为谁

但是向下转型不太安全,因为需要进行强制类型转换,如果转换后的类型与向上转型之前子类对象类型不一致的话,运行时就会抛异常
举个例子,比如我想让狗喵喵叫,这肯定是不行的

    public static void main(String[] args) {Animal animal = new Cat();Animal animal1 = new Dog();Dog dog = new Dog();dog = (Dog)animal1;  //向下转型成功dog = (Cat)animal;    //转换失败,因为animal不是由Cat类型向上转型得到的dog.mew();}

为了防止报错,可以在向下转型之前使用关键字instanceof进行检验
o1 instanceof o2
instanceof可以用来判断o1是否是o2或者o2子类实例化的对象,如果是,返回true;反之返回false

而对于第三个条件:通过父类的引用调用重写的方法。其实你会发现只要满足前面两个条件,那第三个条件肯定也满足了
满足三个条件之后,就会发生动态绑定,它是多态的基础。而有动态绑定,那自然也有静态绑定,下面对这两个概念进行解析

🍌静态绑定&动态绑定

  1. 静态绑定

编译阶段就确定要调用哪个函数

    int add(int x,int y) {return x+y;}int add(int x,int y,int z) {return x+y+z;}

比如上面两个add方法构成重载,在编译阶段根据所传参数个数就能确定要调用哪个add方法

  1. 动态绑定
    当一个父类的引用指向一个子类的对象时,可以通过父类的引用调用子类重写的方法。这种情况下,Java会根据对象的实际类型来决定调用哪个方法,这就是动态绑定

动态绑定是在程序运行期间才确定要调用哪个方法

    public static void main(String[] args) {Animal animal = new Dog("圆圆",19);animal.eat();}

在这里插入图片描述
汇编代码观察结果

当调用一个方法时,编译器会根据引用的类型来确定要调用的方法,所以在编译阶段,调用的还是Animal的eat方法(通过汇编可以观察到)
但是程序运行时,实际上被调用的方法是由引用所指向的对象的类型决定的所以我们看到运行结果是调用Dog的eat方法

🍌多态的利弊

多态的好处:

  • 能够简化代码,避免使用大量的 if - else
    比如要写一个类来打印不同的图案(○、△、❀),如果不基于多态,实现的代码如下:
public class Shape {public Shape shape;public void draw() {System.out.println("画一个图形");}
}public class Circle extends Shape{@Overridepublic void draw() {System.out.println("○");}
}public class Triangle extends Shape{@Overridepublic void draw() {System.out.println("△");}
}public class Flower extends Shape{@Overridepublic void draw() {System.out.println("❀");}
}public static void main(String[] args) {String[] array = {"Triangle","Circle","Circle","Flower"};for(String shape:array) {if(shape.equals("Triangle")) {System.out.println("△");} else if(shape.equals("Circle"))  {System.out.println("○");} else if (shape.equals("Flower")) {System.out.println("❀");}}}

如果使用多态,就可以简化为:

public class Shape {public Shape shape;public void draw() {System.out.println("画一个图形");}
}public class Circle extends Shape{@Overridepublic void draw() {System.out.println("○");}
}public class Triangle extends Shape{@Overridepublic void draw() {System.out.println("△");}
}public class Flower extends Shape{@Overridepublic void draw() {System.out.println("❀");}
}public static void main(String[] args) {Shape[] array = {new Triangle(),new Circle(),new Circle(),new Flower()};for(Shape shape:array) {shape.draw();}
}

以子类对象为数组元素,通过for循环调用draw函数打印相应的图案
在这里插入图片描述

  • 可扩展能力更强
    以上面打印图案为例,如果要新增一种新的形状,使用多态的方式代码改动成本也比较低

缺陷:

  • 属性没有多态性
    当父类和子类都有同名属性的时候,通过父类引用,只能引用父类自己的成员属性
  • 构造方法没有多态性
    注意:不要在构造方法里面调用重写的方法!!!因为会发生动态绑定,调用子类重写的方法,但此时子类还没构造完成,可能会出现一些极难被发现的问题

🍉写在最后

以上就是本篇文章的全部内容,如果你觉得本文对你有所帮助的话,那不妨点个小小的赞哦!(比心)

相关文章:

「JavaSE」类和对象3

🎇个人主页:Ice_Sugar_7 🎇所属专栏:快来卷Java啦 🎇欢迎点赞收藏加关注哦! 类和对象3 🍉多态🍌重写🍌向上转型&向下转型🍌静态绑定&动态绑定&#x…...

IntelliJ IDEA 中输出乱码解决

最近tomcat突然在控制台输出乱码,各种乱码问题,查阅大量的资料,最终得以解决. IDEA控制台输出乱码 问题一:idea中tomcat控制台输出乱码 运行本地的tomcat\bin\start.bat文件页面显示正常 在idea中显示乱码 解决: 根…...

序列到序列模型

一.序列到序列模型的简介 序列到序列(Sequence-to-Sequence,Seq2Seq)模型是一类用于处理序列数据的深度学习模型。该模型最初被设计用于机器翻译,但后来在各种自然语言处理和其他领域的任务中得到了广泛应用。 Seq2Seq模型的核…...

计算机网络(第六版)复习提纲4

计算机网络的体系结构: 三类体系结构: OSI七层:物理层比特位传输,链路层相邻链路传输检验,网络层进行路由选择,运输层实现端到端进程通信,会话层连接管理,表示层数据格式&#xff0c…...

天拓分享:汽车零部件制造企业如何利用边缘计算网关和数网星平台实现数控机床数据采集分析

一、项目背景 某汽车零部件制造企业为了提高生产效率、降低能耗和提高产品质量,决定引入TDE边缘计算网关和数网星工业互联网平台,对数控机床进行数据采集与分析。 二、解决方案 1、设备选型与配置:考虑到企业生产需求和数控机床的特性&…...

爬虫逆向开发教程1-介绍,入门案例

爬虫前景 在互联网的世界里,数据就是新时代的“黄金”。而爬虫,就是帮助我们淘金的“工具”。随着互联网的不断发展,数据量呈现指数级的增长,在数据为王的时代,有效的挖掘数据和利用,你会得到更多东西。 学…...

时序分解 | Matlab实现CEEMDAN+PE自适应噪声完备集合经验模态分解+排列熵计算

时序分解 | Matlab实现CEEMDANPE自适应噪声完备集合经验模态分解排列熵计算 目录 时序分解 | Matlab实现CEEMDANPE自适应噪声完备集合经验模态分解排列熵计算效果一览基本介绍程序设计参考资料 效果一览 基本介绍 CEEMDANPE自适应噪声完备集合经验模态分解排列熵计算 运行环境m…...

Oracle命令大全

文章目录 1. SQL*Plus命令(用于连接与管理Oracle数据库)2. SQL数据定义语言(DDL)命令3. SQL数据操作语言(DML)命令4. PL/SQL程序块5. 系统用户管理6. 数据备份与恢复相关命令1. SQL*Plus命令(用…...

目标检测--01

基本概念 什么是目标检测? ​ 目标检测(Object Detection)的任务是找出图像中所有感兴趣的目标(物体),确定它们的类别和位置,是计算机视觉领域的核心问题之一。由于各类物体有不同的外观、形状…...

MyBatisPlus学习笔记三-核心功能

接上篇: MyBatisPlus学习笔记二-CSDN博客 1、核心功能-IService开发基础业务接口 1.1、介绍 1.2、引用依赖 1.3、配置文件 1.4、用例-新增 1.5、用例-删除 1.6、用例-根据id查询 1.7、用例-根据ids查询 2、核心功能-IService开发复杂业务接口 2.1、实例-更新 3、…...

【并发编程系列】putIfAbsent和getOrDefault用法

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

人力资源智能化管理项目(day01:基础架构拆解)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes 觉得有帮助的同学,可以点心心支持一下哈 一、基础架构拆解 1.拉取模板代码 git clone GitHub - PanJiaChen/vue-admin-template: a vue2.0 minimal admin template 项目名 2.core-js…...

JAVA ORM Bee的设计模式分析

创建型 工厂模式(Factory Pattern) 日志工厂 LoggerFactory 静态工厂模式 *(Static Factory) BeeFactoryHelper 单例模式(Singleton Pattern) 使用单例模式管理系统的配置信息 HoneyConfig 建…...

go语言(三)----函数

1、函数单变量返回 package mainimport "fmt"func fool(a string,b int) int {fmt.Println("a ",a)fmt.Println("b ",b)c : 100return c}func main() {c : fool("abc",555)fmt.Println("c ",c)}2、函数多变量返回 pack…...

鸿蒙原生应用/元服务开发-延迟任务说明(一)

一、功能介绍 应用退至后台后,需要执行实时性要求不高的任务,例如有网络时不定期主动获取邮件等,可以使用延迟任务。当应用满足设定条件(包括网络类型、充电类型、存储状态、电池状态、定时状态等)时,将任务…...

正信晟锦:借钱一直都不还可以起诉吗

在日常生活中,我们可能会遇到一些经济困难,需要向亲朋好友或者金融机构借款。然而,有些人在借款后并没有按照约定的时间还款,甚至一直拖欠不还。这种情况下,债权人是否可以起诉债务人呢?答案是肯定的。 我们需要明确的…...

npm run dev 启动vue的时候指定端口

使用的是 Vue CLI 来创建和管理 Vue 项目, 可以通过设置 --port 参数来指定启动的端口号。以下是具体的步骤: 打开命令行终端 进入您的 Vue 项目目录 运行以下命令,通过 --port 参数指定端口号(例如,这里设置端口号…...

深度学习|16.1 词表示、embedding

文章目录 词表示one-hot编码 embedding编码工具t-SNE——将多维空间投射到二维平面 词表示 one-hot编码 若有n类词,则用n维向量对单个类进行区分。在这个n维向量里面第i维为1,则说明这是第i个词,并且要求其他位置都是为0. embedding编码 每…...

.NetRSA签名(调的JAVA的接口)

公共类: using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; using System; using System.IO; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates;namespace CommonUtils {/// <summary>/// 将私钥&…...

CSS||选择器

目录 作用 分类 基础选择器 标签选择器 ​编辑类选择器 id选择器 通配符选择器 作用 选择器&#xff08;选择符&#xff09;就是根据不同需求把不同的标签选出来这就是选择器的作用。 简单来说&#xff0c;就是选择标签用的。 选择器的使用一共分为两步&#xff1a; 1.…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积

1.题目介绍 给定一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O…...

医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor

1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...

echarts使用graphic强行给图增加一个边框(边框根据自己的图形大小设置)- 适用于无法使用dom的样式

pdf-lib https://blog.csdn.net/Shi_haoliu/article/details/148157624?spm1001.2014.3001.5501 为了完成在pdf中导出echarts图&#xff0c;如果边框加在dom上面&#xff0c;pdf-lib导出svg的时候并不会导出边框&#xff0c;所以只能在echarts图上面加边框 grid的边框是在图里…...

数据分析六部曲?

引言 上一章我们说到了数据分析六部曲&#xff0c;何谓六部曲呢&#xff1f; 其实啊&#xff0c;数据分析没那么难&#xff0c;只要掌握了下面这六个步骤&#xff0c;也就是数据分析六部曲&#xff0c;就算你是个啥都不懂的小白&#xff0c;也能慢慢上手做数据分析啦。 第一…...

在MobaXterm 打开图形工具firefox

目录 1.安装 X 服务器软件 2.服务器端配置 3.客户端配置 4.安装并打开 Firefox 1.安装 X 服务器软件 Centos系统 # CentOS/RHEL 7 及之前&#xff08;YUM&#xff09; sudo yum install xorg-x11-server-Xorg xorg-x11-xinit xorg-x11-utils mesa-libEGL mesa-libGL mesa-…...