当前位置: 首页 > 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;造成亏损无底洞 …...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...