Java进阶必备!继承与多态完美结合,让你代码更优雅更高效!

问题背景

在review代码的时候,发现了一个关于Java继承和多态的组合问题。
问题比较少,但是个人觉得是一个很好的问题,可以加深对继承和多态的理解。
问题如下:
在一个service中发现,一个方法里面调用了两个不同的函数,两个函数返回的对象不一样。A对象继承了B对象。

问题分析

这里其实就产生了一个问题,在调用A对象的方法时,调用的是A对象的方法,但是在调用B对象的方法时,调用的是B对象的方法。
那么为什么不调用一个呢?
查看代码才发现,因为特殊情况,需要返回A对象(B对象没有的值),所以就实现了两个接口。
那么就产生了思考:为什么不能直接调用一个接口,减少代码量呢?
*

多态

多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量到底会指向哪个类的实例对象,该引用变量在程序运行期间才确定,这就是多态的概念。

Java语言中的多态(Polymorphism)是面向对象编程的三大基本特性之一,它表示同一个行为具有多个不同表现形式或形态的能力。
在Java中,多态通常通过方法的重写(Override)和方法的重载(Overload)以及接口和父类引用子类对象来实现。

多态的基本概念

  1. 方法的重写(Override):子类可以重写父类中的方法,使得当使用父类类型的引用指向子类对象时,调用的是子类重写后的方法。

  2. 方法的重载(Overload):在同一个类中,可以有多个同名但参数列表不同的方法,这称为方法的重载。虽然重载不是严格意义上的多态,但它与多态在概念上有一定的联系。

  3. 接口和父类引用子类对象:Java中,父类类型的引用可以指向子类对象,调用的是实际对象(子类对象)的方法。这是多态性最典型的表现。

多态的示例

下面是一个通过重写父类方法和使用父类引用指向子类对象来实现多态的示例:

import com.alibaba.fastjson.JSON;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
import java.io.Serializable;

/* 父类*/
@Data
class Animal  implements Serializable {@Serialprivate static final long serialVersionUID = 1L;private String name;private String color;void makeSound() {System.out.println("The animal makes a sound");}
}/* 子类1:狗*/
@EqualsAndHashCode(callSuper=true)@Data
class Dog extends Animal  implements Serializable {@Serialprivate static final long serialVersionUID = 1L;//品种  private String breed; private String gender;@Overridevoid makeSound() {System.out.println("The dog barks");}
}/* 子类2:猫*/
@EqualsAndHashCode(callSuper=true)@Data
class Cat extends Animal  implements Serializable {@Serialprivate static final long serialVersionUID = 1L;//是否有胡须private String hasWhiskers;//生命次数private int livesLeft;@Overridevoid makeSound() {System.out.println("The cat meows");}
}// 主类
public class Main {public static void main(String[] args) {// 创建Animal类型的数组,可以存放Animal及其子类的对象Animal[] animals = new Animal[2];// 创建Dog和Cat对象,并赋值给Animal类型的数组animals[0] = new Dog();animals[1] = new Cat();// 遍历数组,调用每个对象的makeSound方法for (Animal animal : animals) {animal.makeSound(); // 多态的体现:调用的是实际对象的方法}}
}

在这个例子中,我们有一个Animal父类,以及两个子类DogCat。这两个子类都重写了父类的makeSound方法。在Main类的main方法中,我们创建了一个Animal类型的数组,并分别将DogCat对象赋值给数组的元素。当我们遍历数组并调用每个元素的makeSound方法时,实际调用的是每个对象自己的makeSound方法实现,这就是多态的体现。

运行上述代码,输出将会是:

The dog barks
The cat meows

每个对象都按照它们自己的类型来执行相应的行为,尽管它们都是通过Animal类型的引用来调用的。这就是Java中多态的一个简单示例。通过多态,我们可以提高代码的灵活性和可维护性,使得程序能够更容易地扩展和适应新的需求。

解决方法

到了这里,大家应该明白了吧,其实我们可以反过来用,在接口的返回对象的时候,定义返回类型为Animal。然后在实际使用中在程序运行期间才确定具体的Animal对象(Cat或者Dog),然后直接引用属性就OK了。 后续就算这个接口返回的更多的类型,只要是继承的都可以返回父类的方式进行解决(如果改动太大,还是另外写会更好一些)


public class Main {static Animal getAnimalInfo(int type){ if (type == 1) {// 创建Dog对象Dog dog = new Dog(); dog.setBreed("拉布拉多");dog.setGender("公"); dog.setName("小黑");dog.setColor("白色");return dog;} else if (type == 2) {Cat cat =new Cat();cat.setHasWhiskers("有胡须");cat.setLivesLeft(9);cat.setName("小白");cat.setColor("黑色"); return cat;} return null;}public static void main(String[] args) {Dog dog = (Dog)getAnimalInfo(1); System.out.println(JSON.toJSONString(dog));Cat cat = (Cat)getAnimalInfo(2);System.out.println(JSON.toJSONString(cat));}
}
输出的结果是:```java{"breed":"拉布拉多","color":"白色","gender":"公","name":"小黑"}
{"color":"黑色","hasWhiskers":"有胡须","livesLeft":9,"name":"小白"}

这个我们就可以把子类对应的那个代码抽离放到一起,来快速解决这个问题。

PS:这样的设计其实还是有问题的,但是是个老系统的代码,把这个设计改起来会比较麻烦,就只能一步步去改了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/746501.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

将Linux curl命令转换为windows平台的Python代码

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

whereis命令——查找文件所在位置

whereis命令用于在一些特定的目录中查找文件,默认情况下,查找范围会比which要稍大一些,除了可以查找命令程序所在位置外,也可以查找一些非命令程序。 whereis命令的语法格式如下: whereis [选项] 文件名 常用选项如下…

3款国产良心软件,免费又实用,内存满了都舍不得卸载

以下三款软件质量卓越,失之交臂,实为遗憾。 1、文电通PDF 曾经一直依赖adobe reader来浏览PDF,但自从遇见文电通PDF,它的界面与Word如出一辙,让我这个习惯使用office的用户感到分外亲切。它不仅完全免费,…

nginx应用场景(附配置)

场景1:web服务器 server {listen 80;server_name example.com; # 替换为您的域名location / {root /data/wwwroot;index index.html index.htm;} }server {listen 443 ssl;server_name example.com; # 替换为您的域名ssl_certificate /path/to/certificate.crt;ssl…

Rust 深度学习库 Burn

一、概述 Burn 它是一个新的综合动态深度学习框架,使用 Rust 构建的,以极高的灵活性、计算效率和可移植性作为其主要目标。 Rust Burn 是一个以灵活性、高性能和易用性为核心设计原则工具,主打就是灵活性 、高性能 及易用性。 二、Rust B…

基于Python+django影片数据爬取与数据分析设计与实现

博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…

视觉系统对透明胶水的检测都有哪些方案?

透明胶水的检测在工业生产中是一个挑战,因为传统的基于RGB相机的视觉系统通常难以检测透明物体。然而,随着技术的发展,现在有多种方法可以有效地检测透明胶水。 1. 高光谱相机:高光谱相机可以提供不同于传统RGB相机的解决方案。例…

【运维}Linux是否可以解压多个rar,分卷压缩过的rar文件如何解压

要在Linux系统上安装7-Zip,可以按照以下步骤进行: 使用以下命令安装p7zip软件包(含有7-Zip命令行版本): sudo apt-get install p7zip-full安装完成后,你可以使用以下命令来解压RAR文件: 7z x…

如何实现固定公网地址远程SSH连接Linux Deepin系统

文章目录 前言1. 开启SSH服务2. Deppin安装Cpolar3. 配置ssh公网地址4. 公网远程SSH连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 前言 Deepin操作系统是一个基于Debian的Linux操作系统,专注于使用者对日常办公、学习、生活和娱乐的操作体验的极致&#xff0…

Text-to-SQL 工具Vanna | 查看训练数据、删除训练数据

1.查看训练数据vn.get_training_data vn.get_training_data 源码如下,可以看到返回的是df格式的数据 abstractmethoddef get_training_data(self, **kwargs) -> pd.DataFrame:"""Example:pythonvn.get_training_data()This method is used to ge…

要说2024年最热的技术,还得是AIGC

目录 1.AIGC几个方面进步 1.1 算法进步 1.2 计算能力 1.3 数据积累 1.4 应用需求 2.AIGC主要应用领域 2.1 内容创作

几大常用的排序算法

文章目录 一、插入排序二、希尔排序(缩小增量排序)三、选择排序四、堆排序五、冒泡排序六、快速排序6.1 Hoare法6.2挖坑法快排的优化快排的非递归实现 七、归并排序归并的非递归实现 八、计数排序 一、插入排序 直接插入排序是一种简单的插入排序法&…

spc x-bar 正态分布 echarts demo

使用echarts,elementUi,vue编写的spc分析的demo示例. 含x-bar和正态分布图,同一数据可以互转 chart.vue <template><div class"app-container"><el-row><el-col :span"4" class"button-container"><el-button clic…

【vue项目中点击下载】弹窗提示:离开此网站?系统可能不会保存您所做的更改,改为直接下载,不提示此弹窗内容,已解决

项目中用的是window.location.href实现下载 在Web浏览器中&#xff0c;当尝试通过window.location.href重定向到一个文件下载URL时&#xff0c;浏览器通常会显示一个确认对话框&#xff0c;询问用户是否要离开当前页面&#xff0c;因为下载的文件通常是在新窗口或新标签页中打…

程序员如何平衡主业与副业?

程序员的副业有哪些&#xff1f; 常见的有接私活&#xff0c;即外包一些软件项目来做&#xff0c;或者是写文章、拍教学视频、开直播等等。在这里&#xff0c;我更推荐程序员的副业是找个软件开发外包平台来接单&#xff0c;就是在工作之外接一下软件开发、外包项目等&#xf…

软件无线电系列——模拟无线电、数字无线电、软件无线电

本节目录 一、模拟无线电 二、数字无线电 1、窄带数字无线电 2、宽带数字无线电 三、软件无线电本节内容 一、模拟无线电 20世纪80年代的模拟体制(美国的AMPS/欧洲的TACS)被称为第一代移动通信&#xff0c;简称1G,主要目标是为在大范围内有限的用户提供移动电话服务。最主要的…

[Django 0-1] Core.Handlers 模块

Core.Handlers 模块 这个模块封装了 wsgi,asgi 两个类&#xff0c;分别用于处理外部的请求信息&#xff0c;asgi 提供异步处理能力。 Handler 模块将请求Request封装包裹了Middleware中间件&#xff0c;并将处理结果返回为Response响应对象。 BaseHandler 重要函数 load_m…

buuctf 部分web题

[b01lers2020]Welcome to Earth 打开网站&#xff0c;停一会会跳转die&#xff0c;了解一下&#xff0c;这就类似一个通关游戏&#xff0c;不能死亡&#xff0c;也就是说进入/die这个网站就意味着题就做不出来了&#xff1b;所以回到上一个网站原网站&#xff0c;查看源码&…

神经网络量化

神经网络量化&#xff08;Neural Network Quantization&#xff09;是一种技术&#xff0c;旨在减少神经网络模型的计算和存储资源需求&#xff0c;同时保持其性能。在深度学习中&#xff0c;神经网络模型通常使用高精度的参数&#xff08;例如32位浮点数&#xff09;来表示权重…

如何关闭 Visual Studio 双击异常高亮

[问题描述]&#xff1a; 最近 Visual Studio 更新后&#xff0c;双击选中关键字快要亮瞎我的眼睛了 &#x1f440;&#x1f440; [解决方法]&#xff1a; 摸索了一下&#xff0c;找到了关闭的方法&#xff1a;工具 → 选项 → 文本编辑器 → 常规&#xff0c;然后取消 勾选 sel…