【Java SE】多态
🥰🥰🥰来都来了,不妨点个关注叭!
👉博客主页:欢迎各位大佬!👈
文章目录
- 1. 多态
- 1.1 多态是什么
- 1.2 多态的意义
- 1.3 多态的实现条件
- 2. 重写
- 2.1 重写的概念
- 2.2 重写的规则
- 2.3 重写与重载的区别
- 2.4 重写的设计
- 3. 向上转型和向下转型
- 3.1 向上转型
- 3.2 向下转型
- 3.3 instanceof关键字
- 4. 多态的优缺点
- 4.1 多态的优点
- 4.2 多态的缺点
1. 多态
面向对象三大特性:封装、继承、多态
今天我们一起来看看多态这一特性~~~
1.1 多态是什么
在生活中,如果遇到特别伤心的事情或者心情很沮丧,可能就会哭泣,但在不同人身上,哭泣的形式不一样,比如"臣妾做不到",小女孩哇哇大哭,还有大耳朵图图抱着妈妈的腿哭泣等等。总之,同一件事情,发生在不同对象上,表现的形式是不一样的~
【多态】通俗来说,多种形态,即去完成某个行为,当不同的对象去完成时会产生出不同的状态
1.2 多态的意义
【多态的意义】
在于提高代码的复用性和扩展性,同时实现接口统一,并十分灵活,可以根据不同的输入参数或条件,调用不同的子类方法实现不同的功能,易于维护和修改(本期内容结尾将重点提到)
1.3 多态的实现条件
在Java中实现多态的条件如下(缺一不可):
(1) 必须在继承下
(2) 子类必须要对父类中方法进行重写
(3) 通过父类的引用调用重写的方法(向上转型)
多态体现的方面:当传递不同类对象时,会调用对应类中的方法
【代码】
public class Animal {String name;String gender;int age;public Animal(String name,String gender, int age) {this.name = name;this.gender = gender;this.age = age;}public void eat() {System.out.println(name+"吃饭");}
}
public class Cat extends Animal{public Cat(String name,String gender,int age) {super(name, gender, age);}@Overridepublic void eat() {System.out.println(name+"吃🐟");}
}
public class Dog extends Animal{public Dog(String name,String gender,int age) {super(name, gender, age);}@Overridepublic void eat() {System.out.println(name+"吃骨头");}
}
public class Bird extends Animal{public Bird(String name,String gender,int age) {super(name, gender, age);}@Overridepublic void eat() {System.out.println(name+"啄米");}
}
public class Test {public static void eat(Animal a) {a.eat();}public static void main(String[] args) {Cat cat = new Cat("柚子","雌",2);Dog dog = new Dog("球球","雄",1);Bird bird = new Bird("泡芙","雌",2);eat(cat);eat(dog);eat(bird);}
}
【运行结果】
【解释说明】
在上述代码中,Animal、Cat、Dog和Bird类是类的实现者写的,Test类是类的调用者写的
当类的调用者在编写 eat 这个方法的时,传进来的参数类型为 Animal父类,在该方法内部并不知道当前的a 引用指向的是哪个类型,哪个子类的实例,即a这个引用调用 eat方法可能会有多种不同的表现(a引用的实例相关,比如猫类实例调用、狗类实例调用等,eat表现的形式不同),这种行为称为多态
【图示】
【@Override】
@Override是jdk的注解,用于指示一个方法是重写了父类中的方法
这个注解只在编译时有效,不会保留在生成的字节码文件中
使用 @Override 注解的优点:
1)提高代码的可读性和安全性
2)在编译时检查可能的错误
但它不是必需要写的,只要正确地重写了父类中的方法,不使用 @Override 注解,代码仍能够正常运行
(即使用或不使用取决于编码风格和习惯)
2. 重写
2.1 重写的概念
【重写】也称为覆盖,重写是子类对父类实现过程进行重新编写, 返回值和形参都不能改变,即外壳不变,核心重写,重写的好处是子类可以根据需要,定义特定于自己的行为,即子类能够根据需要实现父类的方法
2.2 重写的规则
【重写规则】
1)子类在重写父类的方法时,一般必须与父类的返回值类型 ,方法名 (参数列表) 完全一致
2)被重写的方法返回值类型可以不同,但必须具有父子类关系
3)访问权限不能比父类中被重写的方法的访问权限更低(如父类方法被public修饰,则子类中重写该方法不能声明为 private)
4)父类被static、private、final修饰的方法、构造方法都不能被重写
5)重写的方法可使用 @Override 注解来显式指定,能进行一些合法性校验,检查可能会出现的错误(如不小心将方法名字写错, 此时编译器就会发现父类中没有该方法,则编译报错,提示无法构成重写)
2.3 重写与重载的区别
2.4 重写的设计
【重写的设计原则】对于已经投入使用的类,尽量不要进行修改,最好是重新定义一个新的类,重复利用其中共性的内容,并添加或者改动新的内容
举一个栗子吧~
例如之前的电视机,只能看正在播放的频道,而当今时代,科技越来越发达,技术在进步,现在的电视不仅可以看正在播放的频道,还可以回看,直播等等,而我们不应该直接在原来的类修改,因为原来的类可能仍有用户正在使用,而正确的解决方式为,新建一个新型电视机的类,对可以看的内容这个方法进行重写,增添更多的功能,即达到需求
【静态绑定】即在编译时,根据用户所传递实参类型就确定具体调用哪个方法,代表:函数重载
【动态绑定】即在编译时,不能确定方法的行为,需要等到程序运行时,才能够确定具体调用哪个类的方法(发生多态的基础)
3. 向上转型和向下转型
3.1 向上转型
【向上转型】实际上是创建一个子类对象,当父类对象使用
【语法格式】父类类型 对象名 = new 子类类型();
【语法举例】
Animal animal = new Bird(“泡芙”,“雌”,2);
animal是父类Animal类型,即小的范围变成大的范围(是可以的),比如猫、狗和鸟等都是动物,将子类对象转化为父类引用是合理、安全的,大的范围包含小的范围
【使用场景】
1)直接赋值 2)方法传参 3)方法返回 【具体使用代码举例如下】:
public class Test1 {public static void main(String[] args) {Cat cat = new Cat("柚子","雌",2);Dog dog = new Dog("球球","雄",1);//1.直接复制 子类对象赋值给父类对象Animal bird = new Bird("泡芙","雌",2);eat(cat);eat(dog);eat(bird);}//2.方法传参 形参的类型为Animal父类,可接受任意子类对象,即animal1的类型可以是猫、狗、鸟等子类public static void eat(Animal animal1) {animal1.eat();}//3.方法返回 返回任意子类对象public static Animal guessAnimal(String name) {if("球球".equals(name)) {return new Dog("球球","雄",1);}return null;}
}
【优点】
让代码实现更简单灵活
【缺点】
不能调用到子类特有的方法,只能调用父类的方法
3.2 向下转型
【向下转型】子类对象向上转型后当父类对象方法使用,再无法调用子类的方法,如需调用子类特有的方法,将父类引用再还原为子类对象即可,即向下转型,在Java中,向下转型是从一个更通用的类型向一个更具体的类型转换的过程
【语法格式】子类对象名 = (子类类型) 对象名
【语法举例】
bird = (Bird)animal;
【使用场景】
将它们转回具体的类型以利用它们的具体实现的情况
public class Animal {String name;String gender;int age;public Animal(String name,String gender, int age) {this.name = name;this.gender = gender;this.age = age;}public void eat() {System.out.println(name+"吃饭");}
}
public class Cat extends Animal{public Cat(String name,String gender,int age) {super(name, gender, age);}@Overridepublic void eat() {System.out.println(name+"吃🐟");}public void meow() {System.out.println("猫在叫~");}
}
public class Dog extends Animal{public Dog(String name,String gender,int age) {super(name, gender, age);}@Overridepublic void eat() {System.out.println(name+"吃骨头");}public void bark() {System.out.println("狗在叫~");}
}
public class Bird extends Animal{public Bird(String name,String gender,int age) {super(name, gender, age);}@Overridepublic void eat() {System.out.println(name+"啄米");}public void chirp() {System.out.println("小鸟叫~");}}
public class Test2 {public static void main(String[] args) {Cat cat = new Cat("柚子","雌",2);Dog dog = new Dog("球球","雄",1);Bird bird = new Bird("泡芙","雌",2);//向上转型Animal animal = cat;animal.eat();animal = dog;animal.eat();animal = bird;animal.eat();//向下转型//程序可以通过编程但是会抛出异常,animal实际指向的是鸟,但现在强制还原为猫,无法还原//cat = (Cat)animal;//cat.meow();//animal指向的是鸟,将animal还原为鸟是安全的bird = (Bird)animal;bird.chirp();//instanceof 判断它左边的对象是否是它右边的类的实例,返回boolean的数据类型,是返回true否则返回false;if(animal instanceof Cat) {cat = (Cat)animal;cat.meow();}if(animal instanceof Dog) {dog = (Dog)animal;dog.bark();}//animal指向的是鸟,左边的对象animal是右边鸟类的实例,为true,执行if内容语句if(animal instanceof Bird) {bird = (Bird) animal;bird.chirp();}}
}
【运行结果】
【解释说明】
【优点】
可访问更具体类型的特定方法和属性,明确正在处理的具体类型
【缺点】
不安全,万一转换失败,运行时会抛异常,Java中为了提高向下转型的安全性,引入instanceof关键字 ,如该表达式为true,则可以安全转换,较为麻烦
3.3 instanceof关键字
【概念】instanceof是Java中的保留关键字
【作用】测试它的左边对象是否是它的右边类的实例,返回类型:boolean类型
【用法】res = 对象名 instanceof 类名;
【举例】以上述代码举例
4. 多态的优缺点
4.1 多态的优点
1)能够避免使用大量的 if - else
如果需要打印多个形状,不基于多态写,则会有好几个if语句
public class Shape {public void draw() {System.out.println("画图形~");}
}
public class Rectangle extends Shape{@Overridepublic void draw() {System.out.println("◇");}
}
public class Cycle extends Shape{@Overridepublic void draw() {System.out.println("○");}
}
public class Fish extends Shape{@Overridepublic void draw() {System.out.println("🐟");}
}
public class Test3 {public static void drawShapes() {Rectangle rectangle = new Rectangle();Cycle cycle = new Cycle();Fish fish = new Fish();String[] shapes = {"cycle","rectangle","fish"};for(String x : shapes) {if(x.equals("cycle")) {cycle.draw();}else if(x.equals("rectangle")) {rectangle.draw();}else if(x.equals("fish")) {fish.draw();}}}public static void main(String[] args) {drawShapes();}
}
基于多态编写代码,创建一个Shape对象的数组,则简洁明了~
public class Test3 {public static void drawShapes1() {Shape[] shapes = {new Cycle(),new Rectangle(),new Fish()};for(Shape x: shapes) {x.draw();}}public static void main(String[] args) {drawShapes1();}
}
两者打印结果一致,所以可以避免大量的if-else语句
2)可扩展能力更强
如果要新增加一种新的形状,使用多态方式编写的代码改动成本较低,体现可扩展性强,比如我们要增加三角形这个形状类型
public class Triangle extends Shape{@Overridepublic void draw() {System.out.println("△");}
}
【解释说明】基于多态代码,对类的使用者来说,drawShapes方法只需创建一个新类的实例,改动成本较低,对于不基于多态的代码, 则需把drawShapes方法中的 if - else 进行修改,改动成本更高
4.2 多态的缺点
代码的运行效率降低
1)属性没有多态性,当父类和子类都有同名属性时,通过父类引用只能引用父类自己的成员属性
2)构造方法没有多态性
A为父类,在A类构造方法中调用func()方法,B为子类,B类中重写func()方法
【代码举例】
public class A {public A() {func();}public void func() {System.out.println("A.func()");}
}
public class B extends A{private String str = "~";@Overridepublic void func() {System.out.println("B.func()"+" "+str);}
}
public class Test4 {public static void main(String[] args) {B b = new B();}
}
【运行结果】
【解释说明】
构造B对象的同时,会调用A的构造方法
A的构造方法中调用func()方法,此时会触发动态绑定,即在编译时不能确定方法的行为,等程序运行时,确定是具体调用B类中的 func()方法,此时B对象自身还没有构造, str是未初始化的状态,为null,如果具备多态性,str的值应该是~,即构造方法没有多态性
【结论】在构造函数内,尽量避免使用实例方法,除final和private方法
即尽量不要在构造器中调用方法,如果这个方法被子类重写,就会触发动态绑定,但此时子类对象还没构造完成,可能会出现一些隐藏但很难发现的问题,带来不必要的麻烦
💛💛💛本期内容回顾💛💛💛
✨✨✨本期内容到此结束啦~下期再见!
相关文章:

【Java SE】多态
🥰🥰🥰来都来了,不妨点个关注叭! 👉博客主页:欢迎各位大佬!👈 文章目录 1. 多态1.1 多态是什么1.2 多态的意义1.3 多态的实现条件 2. 重写2.1 重写的概念2.2 重写的规则2.3 重写与重…...
Yarn vs npm的大同小异Yarn是什么?
Yarn vs npm的大同小异&Yarn是什么? 一、Yarn、npm是什么?二、Yarn vs npm:特性差异总结 一、Yarn、npm是什么? npm是Node.js的包管理器,是由Chris Korda维护。 npm,它全称为Node Package Manager,是…...

1.Godot引擎|场景|节点|GDS|介绍
Godot介绍 Godot是一款游戏引擎 可以通过在steam商城免费下载 初学者和编程基础稍差的推荐学习使用GDScript,和python有些相似 Godot节点 Godot的开发思想——围绕节点 节点的特征与优势 最常用基本的开发组件大部分都具有具体的功能,如图片…...
springboot3 redis 实现分布式锁
分布式锁介绍 分布式锁是一种在分布式系统中用于控制不同节点上的进程或线程对共享资源进行互斥访问的技术机制。 在分布式环境中,多个服务可能同时访问和操作共享资源,如数据库、文件系统等。为了保持数据的一致性和完整性,需要确保在同一…...
2024年第十四届MathorCup数学应用挑战赛A题思路分享(妈妈杯)
A题 移动通信网络中PCI规划问题 物理小区识别码(PCI)规划是移动通信网络中下行链路层上,对各覆盖小区编号进行合理配置,以避免PCI冲突、PCI混淆以及PCI模3干扰等现象。PCI规划对于减少物理层的小区间互相干扰(ICI),增加物理下行控制信道(PDCCH)的吞吐量有着重要的作用,尤其…...

运动听歌哪款耳机靠谱?精选五款热门开放式耳机
随着人们对运动健康的重视,越来越多的运动爱好者开始关注如何在运动中享受音乐。开放式蓝牙耳机凭借其独特的设计,成为了户外运动的理想选择。它不仅让你在运动时能够清晰听到周围环境的声音,保持警觉,还能让你在需要时与他人轻松…...

Kubernetes学习笔记12
k8s核心概念:控制器: 我们删除Pod是可以直接删除的,如果生产环境中的误操作,Pod同样也会被轻易地被删除掉。 所以,在K8s中引入另外一个概念:Controller(控制器)的概念,…...
Qt Designer 控件箱中的控件介绍及布局比列分配
控件箱介绍 Qt Designer的控件箱(Widget Box)包含了各种常用的控件,用户可以通过拖放的方式将这些控件添加到窗体设计器中,用于构建用户界面。以下是一些常见控件箱中的控件及其功能的讲解: 1.基本控件&#…...
蓝桥集训之三国游戏
蓝桥集训之三国游戏 核心思想:贪心 将每个事件的贡献值求出 降序排序从大到小求和为正是即可 #include <iostream>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const int N 100010;int a[N],b[N],c[N];…...

MySQL知识整理
MySQL知识整理 基础第一讲:基础架构:一条SQL查询语句是如何执行的?架构尽量减少长连接的原因和方案为什么尽量不要依赖查询缓存 索引第四讲:深入浅出索引(上)第五讲:深入浅出索引(下…...
代码随想录算法训练营第36天| 435. 无重叠区间、 763.划分字母区间*、56. 合并区间
435. 无重叠区间 力扣题目链接 代码 示例代码 class Solution { public:// 按照区间右边界排序static bool cmp (const vector<int>& a, const vector<int>& b) {return a[1] < b[1];}int eraseOverlapIntervals(vector<vector<int>>&a…...

SpringBoot整合Nacos
文章目录 nacosnacos下载nacos启动nacos相关配置demo-dev.yamldemo-test.yamluser.yaml 代码pom.xmlUserConfigBeanAutoRefreshConfigExampleValueAnnotationExampleDemoApplicationbootstrap.yml测试结果补充.刷新静态配置 nacos nacos下载 下载地址 一键傻瓜试安装即可,官…...
vue3 浅学
一、toRefs 问题: reactive 对象取出的所有属性值都是⾮响应式的 解决: 利⽤ toRefs 可以将⼀个响应式 reactive 对象的所有原始属性转换为 响应式的 ref 属性 二、hook函数 将可复⽤的功能代码进⾏封装,类似与vue2混⼊。 三、ref:获取元素或者组件 let …...

三小时使用鸿蒙OS模仿羊了个羊,附源码
学习鸿蒙arkTS语言,决定直接通过实践的方式上手,而不是一点点进行观看视频再来实现。 结合羊了个羊的开发思路,准备好相应的卡片素材后进行开发。遇到了需要arkTS进行解决的问题,再去查看相应的文档。 首先需要准备卡片对应的图片…...

如何使用 ArcGIS Pro 制作热力图
热力图是一种用颜色表示数据密度的地图,通常用来显示空间分布数据的热度或密度,我们可以通过 ArcGIS Pro 来制作热力图,这里为大家介绍一下制作的方法,希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的POI数…...

SpringBoot之集成Redis
SpringBoot之集成Redis 一、Redis集成简介二、集成步骤2.1 添加依赖2.2 添加配置2.3 项目中使用 三、工具类封装四、序列化 (正常都需要自定义序列化)五、分布式锁(一)RedisTemplate 去实现场景一:单体应用场景二&…...

mybatis-plus与mybatis同时使用别名问题
在整合mybatis和mybatis-plus的时候发现一个小坑,单独使用mybatis,配置别名如下: #配置映射文件中指定的实体类的别名 mybatis.type-aliases-packagecom.jk.entity XML映射文件如下: <update id"update" paramete…...

MySQL基础知识——MySQL日志
一条查询语句的执行过程一般是经过连接器、 分析器、 优化器、 执行器等功能模块, 最后到达存储引擎。 那么, 一条更新语句的执行流程又是怎样的呢? 下面我们从一个表的一条更新语句进行具体介绍: 假设这个表有一个主键ID和一个…...

uniapp 地图分幅网格生成 小程序基于map组件
// 获取小数部分 const fractional function(x) {x Math.abs(x);return x - Math.floor(x); } const formatInt function(x, len) {let result x;len len - result.length;while (len > 0) {result 0 result;len--;}return result; }/*** 创建标准分幅网格* param …...
python项目练习——22、人脸识别软件
功能分析: 人脸检测: 识别图像或视频中的人脸,并标记出人脸的位置和边界框。 人脸识别: 识别人脸的身份或特征,通常使用已知的人脸数据库进行训练,然后在新的图像或视频中识别出人脸并匹配到相应的身份。 表情识别: 识别人脸的表情,如高兴、悲伤、愤怒等,并给出相应…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...

现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
API网关Kong的鉴权与限流:高并发场景下的核心实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...

VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...