【Java基础】为什么不支持多重继承?方法重载和方法重写之间区别、Exception 和 Error 区别?

Hi~!这里是奋斗的明志,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~
🌱🌱个人主页:奋斗的明志
🌱🌱所属专栏:Java基础面经

📚本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为展示我的学习过程及理解。文笔、排版拙劣,望见谅。

在这里插入图片描述

Java 基础

  • 一、为什么 Java 不支持多重继承?
    • 1、解释
    • 2、多继承不行,为什么接口多实现可以呢?
      • 2.1 Java JDK8 之前
      • 2.1 Java JDK8+
    • 3、总结
  • 二、Java 中 方法重载和方法重写之间的区别是什么?
    • 1、区别
    • 2、重载注意点
    • 2、重写注意点
  • 三、Java 中 Exception 和 Error 有什么区别?
    • 1、Exception
    • 2、Error
    • 3、图示各层关系
    • 4、异常处理注意点
      • 4.1 尽量不要捕获类似 Exception 这样通用的异常,而应该捕获特定的异常
      • 4.2 不要“吞”了异常
      • 4.3 不要延迟处理异常
      • 4.4 只在需要try-catch的地方try-catch,try-catch的范围能小则小
      • 4.5 不要通过异常来控制程序流程
      • 4.6 不要在finally代码块中处理返回值或者直接return

一、为什么 Java 不支持多重继承?

1、解释

主要是因为多继承会产生 菱形继承(也叫钻石继承)问题,Jva之父就是吸取C++他们的教训,因此不支持多继承。
所谓的菱形继承很好理解,我们来看下这个图:

在这里插入图片描述

是不是看起来很像一个菱形,BC继承了A,然后D继承了BC,假设此时要调用D内定义在A的方法,因为B和C都有不同的实现
此时就会出现歧义,不知道应该调用哪个了。

// 假设允许多继承(伪代码)
class A { void foo() { System.out.println("A"); } }
class B { void foo() { System.out.println("B"); } }
class C extends A, B {} // 错误:C 中的 foo() 是继承 A 还是 B?

2、多继承不行,为什么接口多实现可以呢?

接口和抽象类不同,接口里的方法都是抽象的(在Java 8之前),没有具体的实现。
所以当一个类实现多个接口时,即使这些接口有相同的方法签名,类只需要提供一个具体的实现,这样就避免了方法冲突的问题。因为接口本身没有实现,不会有多个实现带来的歧义。即使两个接口有相同的方法,实现类只需要实现一次这个方法,这样就不会有问题。

Java 8之后接口可以有默认方法,这时候如果有多个接口有相同的默认方法,实现类必须重写这个方法,否则编译器会报错。
这时候就需要在实现类中明确指定使用哪个接口的默认方法,或者自己重新实现。这可能也是允许接口多实现的一个调整,但核心还是因为接口的默认方法需要显式处理冲突,而类继承的结构性问题无法解决。

2.1 Java JDK8 之前

interface X { void foo(); }
interface Y { void foo(); }class Z implements X, Y {@Overridepublic void foo() { System.out.println("Z 统一实现 X 和 Y 的 foo()");}
}

2.1 Java JDK8+

  • 这种强制重写机制将冲突的解决权交给开发者,确保逻辑明确。
interface X { default void foo() { System.out.println("X"); } }
interface Y { default void foo() { System.out.println("Y"); } }class Z implements X, Y {@Overridepublic void foo() {X.super.foo(); // 显式选择调用 X 的默认实现// 或 Y.super.foo(); 或自定义逻辑}
}

3、总结

Java 通过禁止类的多继承避免了菱形问题和状态冲突,而接口的多实现通过以下机制保证安全:

  • 接口方法由实现类统一实现(消除方法歧义)。

  • 默认方法冲突需显式解决(开发者控制逻辑)。

  • 接口不涉及状态管理(避免字段冲突)。

这种设计在保证语言简洁性的同时,提供了高度的灵活性,符合“单一继承,多重接口”的面向对象设计原则。

二、Java 中 方法重载和方法重写之间的区别是什么?

1、区别

  • 方法重载(Overloading):在同一个类中,允许有多个同名方法,只要它们的参数列表不同(参数个数、类型或顺序)。主要关注方法的签名变化,适用于在同一类中定义不同场景下的行为

  • 方法重写(Overriding):子类在继承父类时,可以重写父类的某个方法(参数列表、方法名必须相同),从而为该方法提供新的实现。主要关注继承关系,用于子类改变父类的方法实现,实现运行时多态性

  • 区别主要如下:

区别重载重写
发生的场所在同一个类中在继承关系的子类和父类之间
参数列表必须不同(参数的数量、类型或顺序不同)必须相同,不能改变参数列表
返回类型可以不同必须与父类方法的返回类型相同,或者是父类返回类型的子类(协变返回类型)
访问修饰符不受访问修饰符影响子类方法的访问修饰符不能比父类更严格,通常是相同或更宽泛
静态和非静态方法可以是静态方法或非静态方法只能重写非静态方法,静态方法不能被重写(静态方法可以被隐藏)
异常处理方法的异常处理可以不同子类的异常不能抛出比父类更多的异常(可以抛出更少的或相同类型的异常)

2、重载注意点

重载中提到的方法同名 但参数列表不同(参数个数、类型或顺序),这里要注意和返回值没有关系,方法的签名仅是名字和参数列表不包括返回值

重载通常用于提供同一操作的不同实现,例如构造函数的重载、不同类型输入的处理等。

  • 代码实现:
public class A{// 重载方法:参数数量不同public void print(int a) {System.out.println("Printing int: " + a);}// 重载方法:参数类型不同public void print(String a) {System.out.println("Printing String: " + a);}// 重载方法:参数类型和数量不同public void print(int a, int b) {System.out.println("Printing two ints: " + a + ", " + b);}
}

2、重写注意点

在重写时,子类方法不能使用比父类更严格的访问级别
例如,父类的方法是 protected,子类不能将其修改为 private,但可以改为public
子类方法抛出的异常必须与父类一致,或者是其父类异常的子类

重写通常用于在子类中提供父类方法的具体实现,以实现运行时多态性。例如,子类对父类方法进行扩展或修改以适应特定需求。

  • 代码实现:
class A{public void display() {System.out.println("Parent display");}
}class B extends A{@Overridepublic void display() {System.out.println("Child display");}
}public class Test{public static void main(String[] args) {A a = new B();a.display(); // 输出 "Child display"}
}
  • 还有一个@Override注解,在重写方法时使用@Override注解,编译器可以帮助检查是否正确实现了重写,以防误操作。

三、Java 中 Exception 和 Error 有什么区别?

ExceptionError 都是 Throwable 类的子类(在Java代码中,只有继承了 Throwable 类的实例才可以被 throw 或者被 catch
它们表示在程序运行时发生的异常或者错误情况

总结:Exception 表示可以被处理的程序异常,Error 表示系统级的不可恢复错误

1、Exception

Exception : 是程序中可以处理的异常情况,表示程序逻辑或外部环境中的问题,可以通过代码进行恢复或处理。
常见子类有:IOExceptionSQLExceptionNullPointerExceptionIndexOutofBoundsException等。
Exception 又分为 Checked Exception(编译期异常)Unchecked Exception(运行时异常)
Checked Exception : 在编译时必须显式处理(如使用try-catch块或通过throws声明抛出)。如IOException
Unchecked Exception : 运行时异常,不需要显式捕获。常见的如 NullPointerExceptionIllegalArgumentException 等,继承自 RuntimeException

2、Error

Error 表示严重的错误,通常是 JVM 层次内系统级的、无法预料的错误,程序无法通过代码进行处理或恢复。例如内存耗尽(OutofMemoryError)栈溢出(Stackoverf1 OwError)。Error 不应该被程序捕获或处理,因为一般出现这种错误时程序无法继续运行。

3、图示各层关系

在这里插入图片描述

比如用户编写一个程序,如果文件没找到,会抛出 FileNotFoundException,属于编译异常,必须处理。而如果程序递归太深导致栈溢出,会抛出 StackOverflowError,属于 Error,程序一般无法处理。

4、异常处理注意点

4.1 尽量不要捕获类似 Exception 这样通用的异常,而应该捕获特定的异常

软件工程是一门协作的艺术,在日常的开发中我们有义务使自己的代码能更直观、清晰地表达出我们想要表达的信息。
但是如果你什么异常都用了 Exception ,那别的开发同事就不能一眼得知这段代码实际想要捕获的异常,并且这样的代码也会捕获到可能你希望它抛出而不希望捕获的异常。

4.2 不要“吞”了异常

如果我们捕获了异常,不把异常抛出,或者没有写到日志里,那会出现什么情况?线上除了bug莫名其妙的没有任何的信息,你都不知道哪里出错以及出错的原因。
这可能会让一个简单的bug变得难以诊断,而且有些同学比较喜欢用 catch之后 e.printStackTrace(),在我们产品中通常不推荐用这种方法,一般情况下这样是没有问题的但是这个方法输出的是个标准错误流。
比如是在分布式系统中,发生异常但是找不到 stacktrace
所以最好是输入到日志里,我们产品可以自定义一定的格式,将详细的信息输入到日志系统中,适合清晰高效的排查错误。

4.3 不要延迟处理异常

比如有个方法,参数是个 name,函数内部调了别的好几个方法,其实你的 name 传的是 null 值,但是你没有在进入这个方法或者这个方法一开始就处理这个情况,而是在你调了别的好几个方法然后爆出这个空指针。这样的话明明你的出错堆栈信息只需要抛出一点点信息就能定位到这个错误所在的地方,经过了好多方法之后可能就是一坨堆栈信息。

4.4 只在需要try-catch的地方try-catch,try-catch的范围能小则小

只要必要的代码段使用try-catch,不要不分青红皂白try住一坨代码,因为try-catch中的代码会影响JVM对代码的优化,例如重排序。

4.5 不要通过异常来控制程序流程

一些可以用 if/lse 的条件语句来判断 例如 null 值等,就不要用异常,异常肯定是比一些条件语句低效的,有CPU分支预测的优化等。
而且每实例化一个 Exception 都会对栈进行快照,相对而言这是一个比较重的操作,如果数量过多开销就不能被忽略了。

4.6 不要在finally代码块中处理返回值或者直接return

finallyreturn 或者处理返回值会让发生很诡异的事情,比如覆盖了try中的return,或者屏蔽的异常。

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

bladeX微服务框架如何修改nacos分组

nacos中注册的服务他的分组(分组名称)怎么修改 在org.springblade.common.launch // 指定注册IP PropsUtil.setProperty(props, "spring.cloud.nacos.discovery.ip", "127.0.0.1"); // 指定注册端口 PropsUtil.setProperty(props, &…

大数据项目2a:基于spark的电影推荐和分析系统设计与实现

1、项目目的 本项目的目的是设计并实现一个基于Spark的电影推荐系统,以应对大数据环境下电影推荐服务的挑战。通过整合电影、评分和用户数据集,并利用SparkSql框架进行高效处理,系统能够为用户提供个性化的电影推荐。项目采用多种先进技术&…

机器学习常用包matplotlib篇(四)绘图规范

前言 为了让 Matplotlib 绘图代码更规范、易读,且为后期图形完善预留空间,建议遵循一些规范绘图方法。😉 1.管理图形对象 建议使用 plt.figure() 或者 plt.subplots() 管理完整的图形对象,而非直接用 plt.plot(...) 绘图。这样能…

LVGL4种输入设备详解(触摸、键盘、实体按键、编码器)

lvgl有触摸、键盘、实体按键、编码器四种输入设备 先来分析一下这四种输入设备有什么区别 (1)LV_INDEV_TYPE_POINTER 主要用于触摸屏 用到哪个输入设备保留哪个其他的也是,保留触摸屏输入的任务注册,其它几种种输入任务的注册&…

5G技术解析:从核心概念到关键技术

1. 引言 5G技术的迅猛发展正在重塑我们的生活方式和社会结构。它不仅仅是新一代的移动通信技术,更是一场深刻的技术革命。5G网络正在以其惊人的高速、低延迟和大带宽能力,为智能家居、自动驾驶、工业自动化、远程医疗等另一带来前所未有的可能性。 本文…

背包问题1

核心: // f[i][j] 表示只看前i个物品,总体积是j的情况下,总价值是多少 //res maxx(f[n][]0-v] //f[i][j]: //1 不选第i个物品 f[i][j] f[i-1][j] //2 选第i个物品 f[i][j] f[i-1][j-v[i]] w[i]

Redis | 十大数据类型

文章目录 十大数据类型概述key操作命令数据类型命令及落地运用redis字符串(String)redis列表(List)redis哈希表(Hash)redis集合(Set)redis有序集合(ZSet / SortedSet&…

DeepSeek图解10页PDF

以前一直在关注国内外的一些AI工具,包括文本型、图像类的一些AI实践,最近DeepSeek突然爆火,从互联网收集一些资料与大家一起分享学习。 本章节分享的文件为网上流传的DeepSeek图解10页PDF,免费附件链接给出。 1 本地 1 本地部…

C# OpenCvSharp 部署MOWA:多合一图像扭曲模型

目录 说明 效果 项目 代码 下载 参考 C# OpenCvSharp 部署MOWA:多合一图像扭曲模型 说明 算法模型的paper名称是《MOWA: Multiple-in-One Image Warping Model》 ariv链接 https://arxiv.org/pdf/2404.10716 效果 Stitched Image 翻译成中文意思是&…

vite+vue3搭建前端项目并使用 Bulma 框架

vitevue3搭建前端项目并使用 Bulma 框架 bluma css框架参照。 https://bulma.org.cn/documentation/start/overview/ 1. 创建项目 npm init vitelatest ai-imageneration --template vue选择 vue 和 typescript 作为模板: 2. 安装依赖 npm install npm install…

Spring 6.2.2 @scope(“prototype“)原理

Spring Prototype 原理? 前置准备 创建一个MyService类 Scope("prototype") Service("myService") public class MyService {public String getMessage() {return "Hello, World!";} }创建一个main类,用于debug。 pr…

RabbitMQ 可靠性投递

文章目录 前言一、RabbitMQ自带机制1、生产者发送消息注意1.1、事务(Transactions)1.2、发布确认(Publisher Confirms)1.2.1、同步1.2.2、异步 2、消息路由机制2.1、使用备份交换机(Alternate Exchanges)2.…

【实用技能】如何借助3D文档控件Aspose.3D, 在Java中无缝制作 3D 球体

概述 创建 3D 球体是 3D 图形设计的一个基本方面。无论您是在开发游戏、模拟还是可视化,无缝创建 3D 球体模型的能力都至关重要。Aspose.3D通过提供强大的 3D 图形 SDK 在各个行业中发挥着重要作用。它允许开发人员轻松创建、操作和转换 3D 模型。此 SDK 对于希望将…

C语言基础系列【3】VSCode使用

前面我们提到过VSCode有多么的好用,本文主要介绍如何使用VSCode编译运行C语言代码。 安装 首先去官网(https://code.visualstudio.com/)下载安装包,点击Download for Windows 获取安装包后,一路点击Next就可以。 配…

windows安装WSL完整指南

本文首先介绍WSL,然后一步一步安装WSL及Ubuntu系统,最后讲解如何在两个系统之间访问和共享文件信息。通过学习该完整指南,能帮助你快速安装WSL,解决安装和使用过程中的常见问题。 理解WSL(Windows Subsystem for Linux…

123,【7】 buuctf web [极客大挑战 2019]Secret File

进入靶场 太熟悉了,有种回家的感觉 查看源代码,发现一个紫色文件 点下看看 点secret 信息被隐藏了 要么源代码,要么抓包 源代码没有,抓包 自己点击时只能看到1和3处的文件,点击1后直接跳转3,根本不出…

Formality:时序变换(五)(寄存器复制)

相关阅读 Formalityhttps://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482 一、引言 时序变换在Design Compiler的首次综合和增量综合中都可能发生,它们包括:时钟门控(Clock Gating)、寄存器合并(Register Merging)、…

我使用deepseek高效学习-分析外文网站Cron定时执行任务

最近在spring框架中 设置定时任务,有的末尾是星号有的是问号,有的是6位,有的是7位。就这个机会总结下cron表达式的使用,综合源代码中的crontab地址翻译分析,结合最近超爆的deepseek 提高学习效率,归纳总结出…

BurpSuite抓包与HTTP基础

文章目录 前言一、BurpSuite1.BurpSuite简介2.BurpSuite安装教程(1)BurpSuite安装与激活(2)安装 https 证书 3.BurpSuite使用4.BurpSuite资料 二、图解HTTP1.HTTP基础知识2.HTTP客户端请求消息3.HTTP服务端响应消息4.HTTP部分请求方法理解5.HTTPS与HTTP 总结 前言 在网络安全和…

google 多模态aistudio Stream Realtime体验

参考: https://aistudio.google.com/live 使用gemini多模态能力,支持语音图像文字输入输出,实时交互体验 支持语音实时交互、摄像头加语音、屏幕视频语音 摄像头 屏幕共享