【JavaSE】多态(多态实现的条件 重写 向上转移和向下转型 向上转型 向下转型 多态的优缺点 避免在构造方法种调用重写的方法)
文章目录
- 多态
- 多态实现的条件
- 重写
- 向上转移和向下转型
- 向上转型
- 向下转型
- 多态的优缺点
- 避免在构造方法种调用重写的方法
多态
一种事物,多种形态。
多态的概念:去完成某个行为,当不同对象去完成时会产生出不同的状态。
多态实现的条件
1.必须再继承体系下。
2.子类必须要对父类中的方法进行重写。
3.通过父类的引用调用重写的方法。

当我们发生向上转型之后,此时通过父类引用只能访问父类自己的成员,不能访问到子类特有的成员。
重写
重写需要满足三个条件:
- 方法名称相同。
- 参数列表相同。
- 返回值相同。
class Animal{public String name;public int age;public void eat(){System.out.println(name+" 正在吃饭!");}
}
class Dog extends Animal{public void wangwang(){System.out.println(name+" 正在汪汪叫!");}@Overridepublic void eat(){System.out.println(name+" 正在吃狗粮!");}
}

编译器可以生成:




class Animal{public String name;public int age;public void eat(){System.out.println(name+" 正在吃饭!");}
}
class Dog extends Animal{public void wangwang(){System.out.println(name+" 正在汪汪叫!");}@Overridepublic void eat(){System.out.println(name+" 正在吃狗粮!");}
}
class Bird extends Animal{public String wing;//翅膀public void fly(){System.out.println(name+" 正在飞!");}@Overridepublic void eat(){System.out.println(name+" 正在吃鸟粮!");}
}
public static void main(String[] args) {Animal animal1 = new Dog();animal1.name = "小黄";animal1.eat();System.out.println("=================");Animal animal2 = new Bird();animal2.name = "圆圆";animal2.eat();
}

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

重写需要注意:
- private修饰的方法不能被重写。
- static修饰的方法不能被重写。
- 子类的访问修饰限定权限要大于等于父类的权限。
private < 默认 < protected < public - 被final修饰的方法不能被重写,此时这个方法被称作密封方法。

向上转移和向下转型
向上转型
实际就是创建一个子类对象,将其当成父类对象来使用。
- 直接赋值
class Animal{public String name;public int age;public void eat(){System.out.println(name+" 正在吃饭!");}
}
class Dog extends Animal{public void wangwang(){System.out.println(name+" 正在汪汪叫!");}
}
public class Test2 {public static void main1(String[] args) {Dog dog = new Dog();dog.name = "小黄";dog.eat();dog.wangwang();Animal animal = dog;}
}
- 方法传参
class Animal{public String name;public int age;public void eat(){System.out.println(name+" 正在吃饭!");}
}
class Dog extends Animal{public void wangwang(){System.out.println(name+" 正在汪汪叫!");}
}
public class Test2 {public static void func(Animal animal){}public static void main(String[] args) {Dog dog = new Dog();func(dog);}
}
3.方法返回值
class Animal{public String name;public int age;public void eat(){System.out.println(name+" 正在吃饭!");}
}
class Dog extends Animal{public void wangwang(){System.out.println(name+" 正在汪汪叫!");}
}
public class Test2 {public static Animal func2(){return new Dog();}public static void main(String[] args) {func2();}
}
优点:让代码实现更简单灵活。
缺陷:不能调用到子类特有的方法。
向下转型
class Animal{public String name;public int age;public void eat(){System.out.println(name+" 正在吃饭!");}
}
class Dog extends Animal{public void wangwang(){System.out.println(name+" 正在汪汪叫!");}
}
public class Test2 {public static void main(String[] args) {Animal animal1 = new Dog();//向下转型Dog dog = (Dog)animal1;dog.name = "小黄";dog.wangwang();}
}
向下转型非常不安全,比如:

解决方法:Java中为了提高向下转型的安全性,引入了 instanceof ,如果该表达式为true,则可以安全转换。
if(animal1 instanceof Dog){//向下转型Dog dog = (Dog)animal1;dog.name = "小黄";dog.wangwang();
}
可以理解为判断animal1这个引用,是不是引用Dog对象。
多态的优缺点
class Shap{public void draw(){System.out.println("画图形!");}
}
class Rect extends Shap{@Overridepublic void draw() {System.out.println("画矩形!");}
}
class Cycle extends Shap{@Overridepublic void draw() {System.out.println("画圆!");}
}
class Flower extends Shap{@Overridepublic void draw() {System.out.println("画一朵花❀!");}
}
public class Test3 {public static void drawMap(Shap shap){shap.draw();}public static void main(String[] args) {Rect rect = new Rect();Cycle cycle = new Cycle();drawMap(rect);drawMap(cycle);drawMap(new Flower());}
}

class Shap{public void draw(){System.out.println("画图形!");}
}
class Rect extends Shap{@Overridepublic void draw() {System.out.println("画矩形!");}
}
class Cycle extends Shap{@Overridepublic void draw() {System.out.println("画圆!");}
}
class Flower extends Shap{@Overridepublic void draw() {System.out.println("画一朵花❀!");}
}
public class Test3 {public static void drawMap2(){Rect rect = new Rect();Cycle cycle = new Cycle();Flower flower = new Flower();//c r c r fString[] 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 main(String[] args) {drawMap2();}
}

多态实现:
public static void drawMap3(){Rect rect = new Rect();Cycle cycle = new Cycle();Flower flower = new Flower();Shap [] shaps = {cycle,rect,cycle,rect,flower};for(Shap shap:shaps){shap.draw();}
}
多态好处:
- 能够降低代码的 “圈复杂度”, 避免使用大量的 if - else。
- 可扩展能力更强如果要新增一种新的形状, 使用多态的方式代码改动成本也比较低。
多态缺陷:代码的运行效率降低。
- 属性没有多态性:当父类和子类都有同名属性的时候,通过父类引用,只能引用父类自己的成员属性。
- 构造方法没有多态性。
避免在构造方法种调用重写的方法
下面我们看一段有坑的代码:
class B {public B() {
// do nothingfunc();}public void func() {System.out.println("B.func()");}
}
class D extends B {private int num = 1;@Overridepublic void func() {System.out.println("D.func() " + num);}
}
public class Test4 {public static void main(String[] args) {D d = new D();}
}
当在父类的构造方法当中去调用父类和子类重写的方法的时候,此时会调用子类的。
num为0是因为父类此时还没有走完,就来到了打印阶段。

结论: “用尽量简单的方式使对象进入可工作状态”, 尽量不要在构造器中调用方法(如果这个方法被子类重写, 就会触发动态绑定, 但是此时子类对象还没构造完成), 可能会出现一些隐藏的但是又极难发现的问题。
相关文章:
【JavaSE】多态(多态实现的条件 重写 向上转移和向下转型 向上转型 向下转型 多态的优缺点 避免在构造方法种调用重写的方法)
文章目录 多态多态实现的条件重写向上转移和向下转型向上转型向下转型 多态的优缺点避免在构造方法种调用重写的方法 多态 一种事物,多种形态。 多态的概念:去完成某个行为,当不同对象去完成时会产生出不同的状态。 多态实现的条件 1.必须…...
MySQL学习---13、存储过程与存储函数
1、存储过程概述 MySQL从5.0版本开始支持存储过程和函数。存储过程和函数能够将负杂的SQL逻辑封装在一起,应用程序无序关注存储过程和函数内部复杂的SQL逻辑,而只需要简单的调用存储过程和函数就可以。 1.1 理解 含义:存储过程的英文是Sto…...
Mysql日志管理、备份与恢复
文章目录 一、Mysql日志管理1.mysql日志2.日志种类3.日志的查询4.配置日志文件 二、Mysql备份与分类1.数据备份的重要性 一、Mysql日志管理 1.mysql日志 Mysql的日志默认保存位置为/usr/local/mysql/date,Mysql的日志配置文件为/etc/my.cnf,里面有一个…...
STM32单片机声控语音识别RGB彩灯多种模式亮度可调WS2812彩灯
实践制作DIY- GC0129-语音识别RGB彩灯 一、功能说明: 基于STM32单片机设计-语音识别RGB彩灯 二、功能介绍: STM32F103C系列最小系统板5VUSB电源64个灯珠的WS2812灯板1个开关键(3档亮度调节)1个模式切换键(白灯 红灯…...
高校9大学术工具推荐,一定要用起来哦!
1、文献管理工具:例如EndNote、Mendeley和Zotero,这些工具可以帮助您整理、管理和引用文献。 2、数据分析工具:例如SPSS、R和Python等,用于进行统计分析和数据处理。 3、学术写作工具:例如LaTeX和Microsoft Word&…...
记一次压力测试
性能测试文档 背景 为对产品性能有一定了解,现将产品展开一次性能测试; 环境与工具 本章为基本工具准备及linux命令说明,无先后顺序。 Xshell工具 本文使用Xshell在Windows界面下远程登录linux主机安装Xshell直接全部选择默认选项即可&…...
一个文明是否有竞争力,在很大程度上取决于信息传递的效率。
文章目录 引言I 有效地传递信息1.1 信息传播分类1.2 信息传递的有效性II 科技进步的必要条件和充分条件2.1 能量总量2.2 能量密度2.3 衡量科技成就的大小2.4 科学的诞生的意义:获得叠加式收益引言 科技进步的必要条件是能量总量,而充分条件是能量密度。一个文明是否有竞争力,…...
测试4年,跳槽一次涨8k,我跳了3次···
最近有人说,现在测试岗位初始工资太低了,有些刚刚入行的程序员朋友说自己工资连5位数都没有.....干了好几年也没怎么涨。看看别人动辄月薪2-3万,其实我想说也没那么难。说下如何高效地拿到3w。 1.暂且把刚入行的条件设低些吧,大专…...
Redis 入门教程(简单全面版)
1 安装: 1.1 生产环境安装 注意: 1、如果安装过程有问题可以参考源代码中的 README.md 文件 2、如果服务器只安装一个 redis 通常选择 /usr/local/redis 作为安装目录,如果安装多台则建议带上 服务名称 区分(建议带上 服务名称 区…...
java并发-AQS
当我们使用Java并发编程时,我们经常会听到“AQS”的概念。AQS代表“AbstractQueuedSynchronizer”,是Java并发包中的一个重要组件。AQS提供了一个框架,使得开发者可以轻松地实现各种同步器,例如锁,信号量,倒…...
openAI图像生成开发文档
图像生成 了解如何使用我们的 DALLE 型号 介绍 图像 API 提供了三种与图像交互的方法: 根据文本提示从头开始创建图像根据新的文本提示创建现有图像的编辑创建现有图像的变体 本指南介绍了使用这三个 API 终结点的基础知识以及有用的代码示例。要了解它们的实际…...
Python综合案例—利用tkinter实现计算器的程序
目录 一、导入 tkinter 库 定义全局变量 二、定义回调函数 三、创建窗口对象 四、创建标签控件 五、创建数字按钮 六、创建加、减、乘、除和等于按钮 七、创建清空按钮 八、总结 用Python实现计算器可以让我们更好地理解面向对象编程、GUI 编程和事件驱动编程等概念&a…...
canvas学习笔记
其实还有react还没有学,但是公司技术栈里面有canvas,所以先系统学习一下canvas 一、canvas 简介 <canvas> 是 HTML5 新增的,一个可以使用脚本(通常为 JavaScript) 在其中绘制图像的 HTML 元素。它可以用来制作照片集或者制作简单(也…...
Navicat Premium 15安装注教程
Navicat Premium 15安装 准备工作 下载好安装包navicat150_premium_cs_x64和安装完成Navicat Premium 15 链接:https://pan.baidu.com/s/1TJs3pjAXJXhu7-13DJLzpg 提取码:hunk 安装Navicat Premium 15 无脑操作,下一步下一步就行了&…...
yolo v8
这个系列代码被封装的非常的精致,对二次开发不太友好,虽然也还是可以做些调节 模型的导出 有三种方式试过,都可以导出onnx的模型 1. 用yolov8 源码来自:ultralytics\yolo\engine\exporter.py (不固定尺寸) yolo export modelpa…...
2022IDEA的下载、安装、配置与使用
文章目录 1.IntelliJ IDEA 介绍1.2 JetBrains 公司介绍1.2 IntelliJ IDEA 介绍1.3 IDEA 的主要功能介绍1.3.1 语言支持上1.3.2 其他支持 1.4 IDEA 的主要优势:(相较于 Eclipse 而言)1.5 IDEA 的下载地址1.6 官网提供的详细使用文档 2.windows 下安装过程2.1 安装前的…...
实验十 超市订单管理系统综合实验
实验十 超市订单管理系统综合实验 应粉丝要求,本博主帮助实现基本效果! 未避免产生版权问题,本项目博主不公开源码,如果您遇到相关问题可私聊博主! 一、实验目的及任务 通过该实验,掌握利用SSM框架进行系…...
微服架构基础设施环境平台搭建 -(二)Docker私有仓库Harbor服务搭建
微服架构基础设施环境平台搭建 -(二)Docker私有仓库Harbor服务搭建 通过采用微服相关架构构建一套以KubernetesDocker为自动化运维基础平台,以微服务为服务中心,在此基础之上构建业务中台,并通过Jekins自动构建、编译、…...
springboot+freemarker+restful
什么是freemarker? FreeMarker是一种模板引擎,它可以用于生成各种类型的文档,比如HTML、XML、PDF、Word等。它可以通过简单的模板语法和数据模型来生成文档内容。与传统的JSP相比,FreeMarker的语法更加简洁和易读,并且可以很好地…...
基于Kubernetes集群构建大中型企业CICD应用平台(1)-- devOps
一、DevOps介绍 软件开发最开始是由两个团队组成: 开发计划由开发团队从头开始设计和整体系统的构建。需要系统不停的迭代更新。 运维团队将开发团队的Code进行测试后部署上线。希望系统稳定安全运行。 这看似两个目标不同的团队需要协同完成一个软件的开发。 …...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...
