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

【一步一步了解Java系列】:重磅多态

看到这句话的时候证明:此刻你我都在努力
加油陌生人
微信图片编辑_20240229212205.png

个人主页:Gu Gu Study
专栏:一步一步了解Java

喜欢的一句话: 常常会回顾努力的自己,所以要为自己的努力留下足迹


喜欢的话可以点个赞谢谢了。
作者:小闭


何为多态

在Java中,多态(Polymorphism)是一种允许不同类的对象对同一消息做出响应的能力,即同一个接口可以被不同的实例以不同的方式实现。多态性是面向对象编程的一个核心概念,它使得代码更加灵活和可扩展。
多态性主要通过以下几种方式实现:

  1. 方法重载(Overloading):这是编译时多态的一个例子。方法重载允许同一个类中有多个同名方法,只要它们的参数列表不同(参数的类型、数量或顺序不同)。
  2. 方法重写(Overriding):这是运行时多态的一个例子。当子类继承父类时,子类可以重写父类的方法。如果子类对象调用了一个被重写的方法,将执行子类中的方法实现,而不是父类中的实现。
  3. 接口实现:一个类可以实现一个或多个接口,接口定义了一组方法规范,具体的实现类必须提供这些方法的具体实现。不同的实现类可以以不同的方式实现同一个接口中定义的方法。
  4. 抽象类:抽象类可以包含抽象方法,这些方法没有具体的实现,必须由继承抽象类的子类来实现。这也是一种多态的体现,因为不同的子类可以提供不同的实现。

多态的使用可以带来以下好处:

  • 代码复用:通过继承和接口实现,可以减少代码的重复编写。
  • 扩展性:通过多态,可以在不修改现有代码的情况下,引入新的类和对象。
  • 灵活性:多态允许程序在运行时动态地绑定方法调用,使得程序更加灵活。

多态是Java中实现开闭原则(对扩展开放,对修改封闭)的关键机制之一,它允许程序更容易适应变化,同时保持代码的稳定性和可维护性。
多态实现的条件:

  1. 必须在继承体系下
  2. 子类必须要对父类中方法进行重写
  3. 通过父类的引用调用重写的方法

总的来说:多态即是不同对象,不同的的态度。


方法重载的多态

方法重载在前面其实已经说过了,下面是一个方法重载多态的情况:

public class Cat {String type="猫咪";public void eat(){System.out.println(type+"吃猫粮");}public void eat(int n){System.out.println(type+"吃"+n+"两猫粮");}}class Test{public static void main(String[] args) {Cat cat=new Cat();cat.eat();cat.eat(1);}}

image.png
上面我们对方法进行重载,然后传参不同时,同一个方法却呈现不同的打印方式即(不同的形态)。

方法重写的多态

我们先要认识,何为重写
在Java中,重写(Overriding)是指子类提供一个特定的实现,覆盖从父类继承来的方法的实现。这是运行时多态的一个体现,意味着在程序运行时,会根据对象的实际类型来调用相应的方法。
要实现方法重写,需要满足以下条件:

  1. 方法名、参数列表和返回类型:子类重写的方法必须具有与父类被重写方法相同的方法名、参数列表和返回类型。如果返回类型不同,则不是重写,而是重载(Overloading)。
  2. 访问权限:子类重写的方法不能具有比父类更严格的访问权限。例如,如果父类中的方法是public的,子类重写的方法也必须是public或protected,但不能是private。
  3. 非静态方法:重写必须发生在非静态方法上。静态方法(Static methods)不能被重写。
  4. 非最终方法:如果父类中的方法是final的,则不能被重写。

下面是一个简单的示例,展示如何在Java中重写方法:

class Animal {public void sound() {System.out.println("Animal makes a sound");}
}class Dog extends Animal {@Override // 这是一个注解,用于指示该方法重写了父类的方法public void sound() {System.out.println("Dog barks");}
}public class Main {public static void main(String[] args) {Animal myAnimal = new Dog(); // 向上转型myAnimal.sound(); // 输出 "Dog barks",展示了运行时多态}
}

在这个例子中,Dog 类继承自 Animal 类,并重写了 sound() 方法。当我们创建 Dog 类的实例并将其向上转型为 Animal 类型时,调用 sound() 方法会执行 Dog 类中重写的方法,而不是 Animal 类中的原始方法。这就是多态性的一个典型应用,它允许程序在运行时根据对象的实际类型来确定调用哪个方法。

了解完重写我们在看看,下面的代码:

public class Animal {String name="aaaa";public void eat(){System.out.println("吃东西。。。。。");}
}class Dog extends Animal{String name;public Dog(String name) {this.name = name;}public void eat(){System.out.println("吃狗粮。。。");}}class Cat extends Animal{String name;public Cat(String name) {this.name = name;}public void eat(){System.out.println("吃猫粮。。。");}}class Test{public static void main(String[] args) {Animal animal=new Dog("旺财");animal.eat();animal=new Cat("小黑");animal.eat();}}

image.png
我们在调用eat()方法时却呈现了不同的形态,即:一个吃猫粮,一个吃狗粮。

我们也可以用静态方法实现多态如下:

public class Animal {String name="aaaa";public void eat(){System.out.println("吃东西。。。。。");}
}class Dog extends Animal{String name;public Dog(String name) {this.name = name;}public void eat(){System.out.println("吃狗粮。。。");}}class Cat extends Animal{String name;public Cat(String name) {this.name = name;}public void eat(){System.out.println("吃猫粮。。。");}}class Test{
public static void eat(Animal animal){animal.eat();}public static void main(String[] args) {Dog dog=new Dog("旺财");eat(dog);Cat cat=new Cat("小黑");eat(cat);}}

image.png
这里我们在Test中实现了一个静态方法eat(Animal animal)然后传递一个对象进去即可完成多态。
其实上面的代码还涉及了,类的向上转型。我们接下来就讲讲向上转型和向下转型。

向上转型和向下转型

在Java中,向上转型(Upcasting)和向下转型(Downcasting)是面向对象编程中多态性的一部分,它们允许我们处理不同类型的对象,但以更通用的类型进行操作。
向上转型(Upcasting)
向上转型是指将子类对象赋值给父类引用的过程。向上转型是安全的,因为子类是父类的特化。这意味着子类继承了父类的所有属性和方法,所以子类对象可以被看作是父类对象。
示例代码:

class Animal {void makeSound() {System.out.println("Animal makes a sound");}
}class Dog extends Animal {void makeSound() {System.out.println("Dog barks");}
}public class Main {public static void main(String[] args) {Animal myAnimal = new Dog(); // 向上转型myAnimal.makeSound(); // 将调用Dog类的makeSound方法}
}

在这个例子中,Dog 类是 Animal 类的子类。我们创建了一个 Dog 类的实例,并将这个实例赋值给 Animal 类型的引用 myAnimal。由于向上转型是安全的,编译器允许这样做,并且当我们调用 makeSound() 方法时,将调用 Dog 类中重写的方法。
向下转型(Downcasting)
向下转型是指将父类对象赋值给子类引用的过程。向下转型是不安全的,因为父类引用可能没有指向实际的子类对象。如果向下转型不正确,将会导致 ClassCastException。
示例代码:

class Animal {void makeSound() {System.out.println("Animal makes a sound");}
}class Dog extends Animal {void makeSound() {System.out.println("Dog barks");}
}public class Main {public static void main(String[] args) {Animal myAnimal = new Dog();Dog myDog = (Dog) myAnimal; // 向下转型if (myAnimal instanceof Dog) {Dog myDogSafe = (Dog) myAnimal; // 安全的向下转型myDogSafe.makeSound(); // 将调用Dog类的makeSound方法} else {System.out.println("myAnimal is not a Dog");}}
}

在这个例子中,我们首先向上转型,将 Dog 对象赋值给 Animal 类型的引用 myAnimal。然后我们尝试向下转型,将 myAnimal 转换为 Dog 类型的引用 myDog。如果 myAnimal 实际上指向了一个 Dog 对象,那么向下转型将成功,否则将抛出 ClassCastException。
为了安全地进行向下转型,可以使用 instanceof 操作符来检查 myAnimal 是否确实指向了一个 Dog 对象。如果 instanceof 检查为 true,那么向下转型是安全的。

注意:
向上转型后只能调用父类的成员和方法,无法再调用子类特有的成员变量或方法。


一个小坑

避免在调用构造方法时调用已经重写过的方法,否则很容易出错。
如下代码:在实例化子类对象时,我们必须先调用完成父类的构造方法,然而Animal的构造方法又调用了子类的已经重写的方法func,这时发生动态绑定,方法执行重写的func,而此时num的值未完成初始化,就打印了0出来,所以打印结果就如下图:

public class Test {public static void main(String[] args) {Dog dog=new Dog();}
}class Animal{public void func(){System.out.println("动物");
}public Animal(){func();
}}class Dog extends Animal{int num=999;public void func(){System.out.println("狗");System.out.println(num);}}

image.png

浅谈final关键字

第一:final修饰类,则类不能被继承
image.png

第二:修饰类的方法则方法不能被重写
image.png

第三:修饰成员变量则变量相当于常量,无法在进行修改。
image.png

相关文章:

【一步一步了解Java系列】:重磅多态

看到这句话的时候证明:此刻你我都在努力 加油陌生人 个人主页:Gu Gu Study专栏:一步一步了解Java 喜欢的一句话: 常常会回顾努力的自己,所以要为自己的努力留下足迹 喜欢的话可以点个赞谢谢了。 作者:小闭…...

运维工具 - SFTP 和 FTP 的区别?

SFTP 和 FTP 的区别有三点 连接方式 SFTP 是在客户端和服务器之间通过 SSH 协议建立的安全连接来传输文件,而 FTP 则是 TCP 端口 21 上的控制连接建立连接。 安全性 SFTP 使用加密传输认证信息来传输数据,因此 SFTP 相对于 FTP 更安全的。 效率 SF…...

创新入门|营销中的视频内容:不可或缺的策略

视频在营销中日益重要。你是否也发现,视频内容最近似乎无处不在?它占据着社交媒体的推文、网站首页,甚至电子邮件中的位置。事实上,并不是你一个人有这样的感受。在过去十年中,视频作为一种营销手段日益成熟和强大。这是因为,人类天生就是视觉动物。我们大脑处理视觉信息的速度…...

《探索Stable Diffusion:AI绘画的创意之路与实战秘籍》

《Stable Diffusion AI 绘画从提示词到模型出图》介绍了 Stable Diffusion AI 绘画工具及其使用技巧。书中内容分为两部分:“基础操作篇”,讲解了 SD 文生图、图生图、提示词、模型、ControlNet 插件等核心技术的应用,帮助读者快速从新手成长…...

某铁路信息中心运营监测项目

某铁路信息中心承担大量实时监测、例行巡检和排障维护等工作,为巩固信息化建设成果,提高整体运维效果,保障铁路信息系统稳定运行,需对现有网络监测系统进行升级改造。 设备类型:服务器、交换机、数据库、中间件、虚拟…...

Threejs加载DOM+CSS到场景中,实现3D场景展示2D平面的效果

1. 前言 本篇文章主要实现了将DOM元素转换为Threejs可以使用的数据结构,使用CSS2DRenderer渲染器渲染这些DOMCSS的平面,使其可以作为一个物体添加到Threejs场景里 如下效果图: 2. 实现步骤 首先创建一个ThreejsVueVite的项目,作为本次的demo项目下载Threejs第三方库 yarn…...

本地知识库开源框架Fastgpt、MaxKB产品体验

本地知识库开源框架Fastgpt、MaxKB产品体验 背景fastgpt简介知识库共享部署 MaxKB总结 背景 上一篇体验了Quivr、QAnything两个开源知识库模型框架,这次介绍两款小众但是体验比较好的产品。 fastgpt 简介 FastGPT 是一个基于 LLM 大语言模型的知识库问答系统&am…...

音视频开发15 FFmpeg FLV封装格式分析

FLV(Flash Video)简介 FLV(Flash Video)是Adobe公司推出的⼀种流媒体格式,由于其封装后的⾳视频⽂件体积⼩、封装简单等特点,⾮常适合于互联⽹上使⽤。⽬前主流的视频⽹站基本都⽀持FLV。采⽤ FLV格式封装的⽂件后缀为.flv。 FLV封装格式的组成 FLV封装…...

Qt 的 d_ptr (d-pointer) 和 q_ptr (q-pointer)解析;Q_D和Q_Q指针

篇一: Qt之q指针(Q_Q)d指针(Q_D)源码剖析---源码面前了无秘密_qtq指针-CSDN博客 通常情况下,与一个类密切相关的数据会被作为数据成员直接定义在该类中。然而,在某些场合下,我们会…...

【机器学习】深度探索:从基础概念到深度学习关键技术的全面解析——梯度下降、激活函数、正则化与批量归一化

🔥 个人主页:空白诗 文章目录 一、机器学习的基本概念与原理二、深度学习与机器学习的关系2.1 概念层次的关系2.2 技术特点差异2.3 机器学习示例:线性回归(使用Python和scikit-learn库)2.4 深度学习示例:简…...

C++模板类与Java泛型类的实战应用及对比分析

C模板类和Java泛型类都是用于实现代码重用和类型安全性的重要工具,但它们在实现方式和应用上有一些明显的区别。下面,我将先分别介绍它们的实战应用,然后进行对比分析。 C模板类的实战应用 C模板类允许你定义一种通用的类,其中类…...

使用Qt对word文档进行读写

目录 开发环境原理使用的QT库搭建开发环境准备word模板测试用例结果Gitee地址 开发环境 vs2022 Qt 5.9.1 msvc2017_x64,在文章最后提供了源码。 原理 Qt对于word文档的操作都是在书签位置进行插入文本、图片或表格的操作。 使用的QT库 除了基本的gui、core、…...

docker容器内无法使用命令问题

更换国内源 /etc/apt/source.list 可以先apt-get install vim #进入容器 docker exec -it 容器ID /bin/bashmv /etc/apt/source.list /etc/apt/source.list.bd vim /etc/apt/source.list#此处我使用腾讯云的源 deb http://mirrors.cloud.tencent.com/debian/ buster main non…...

【深度学习】安全帽检测,目标检测,Faster RCNN训练

文章目录 资料环境尝试训练安全帽数据训练测试预测全部数据、代码、训练完的权重等资料见: 资料 依据这个进行训练: https://github.com/WZMIAOMIAO/deep-learning-for-image-processing/tree/master/pytorch_object_detection/faster_rcnn ├── bac…...

IDEA2024创建maven项目

1、new->project 2、创建后展示 3、生成resources文件夹 4、测试--编写一个hello文件...

linux上VirtualBox使用

前言 最近想把唯一的windows系统装成linux, 但是确实存在一些特殊软件无法舍弃,所有装完linux需要用虚拟机装个windows 上来使用特定的一些软件(不想用wine了)。 还有对一些特定usb设备的透传,这样才能保证在虚拟机中…...

PID控制算法介绍及使用举例

PID 控制算法是一种常用的反馈控制算法,用于控制系统的稳定性和精度。PID 分别代表比例(Proportional)、积分(Integral)和微分(Derivative),通过组合这三个部分来调节控制输出&#…...

因子区间[牛客周赛44]

思路分析: 我们可以发现125是因子个数的极限了,所以我们可以用二维数组来维护第几个数有几个因子,然后用前缀和算出来每个区间合法个数,通过一个排列和从num里面选2个 ,c num 2 来计算即可 #include<iostream> #include<cstring> #include<string> #include…...

代码随想录算法训练营第四十四天 | 01背包问题理论基础、01背包问题滚动数组、416. 分割等和子集

背包问题其实有很多种&#xff0c;01背包是最基础也是最经典的&#xff0c;软工计科学生一定要掌握的。 01背包问题 代码随想录 视频讲解&#xff1a;带你学透0-1背包问题&#xff01;| 关于背包问题&#xff0c;你不清楚的地方&#xff0c;这里都讲了&#xff01;| 动态规划经…...

【PingPong_注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞 …...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...