【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 {
    @Override
    public 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 {
    @Override
    public 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{
    @Override
    public 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,或者屏蔽的异常。

在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

rebase和merge

rebase 和merge区别: rebase变基,改变基底:rebase会抹去提交记录。 git pull 默认merge,git pull --rebase 变基 rebase C、D提交属于feature分支,是基于master分支,在B提交额外拉出来的,当…

科研工作中如何高效利用LabVIEW

LabVIEW作为图形化编程语言,在科研领域广泛应用于数据采集、自动控制、信号处理等任务。如何充分发挥其优势,提高实验效率和数据可靠性,是科研工作者需要重点关注的问题。本文从软件架构、硬件选型、数据处理、调试优化等方面详细探讨LabVIEW…

MybatisPlus整合druid多数据源

1.引入依赖&#xff1a; <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.2.0</version> </dependency><dependency><groupId>com.baomidou</gro…

实验6 客户端和服务器之间IPsec VPN配置

实验6 客户端和服务器之间IPsec VPN配置 1.实验目的 通过在两台计算机间或客户端与服务器之间配置IPsec VPN连接&#xff0c;掌握IPsec VPN配置方法&#xff0c;加深对IPsec协议的理解。 2.实验内容 &#xff08;1&#xff09;在Windows Server系统中配置VPN服务器。 &#xf…

VirtualBox中Ubuntu 22.04网卡配置以及解决过程中遇到的问题

1.添加网卡(仅主机) 2.启动虚拟机&#xff0c;查看新添加网卡信息 #查看网卡 ip addr # 查看网络信息&#xff0c;发现新网卡(enp0s8)未分配 ifconfig -a3.使用netplan进行网络配置 3.1 配置 DHCP获取IP # 进入netplan 文件夹 cd /etc/netplan #查看文件夹下yaml ls -al # 编…

上拉触底案例

1.什么是上拉触底 2. 修改上拉触底距离的默认值 3.上拉触底案例 上拉触底时获取随机颜色 4.添加loading效果 展示loading效果 隐藏loading效果 5.节流处理 进行节流处理&#xff0c;防止多次触底的时候&#xff0c;一次请求多页数据&#xff0c;正在请求下一页数据的时…

AES200物理机部署DeepSeek-R1蒸馏模型

AES200物理机部署DeepSeek-R1模型 华为官方官宣自己的NPU支持DeepSeek-R1模型部署&#xff0c;华为的大模型推理部署依托于其大模型推理引擎&#xff1a;MindIE&#xff0c;但是根据MindIE的文档&#xff0c;其只支持以下硬件&#xff1a; 表1 MindIE支持的硬件列表 类型配置…

2025年软件测试五大趋势:AI、API安全、云测试等前沿实践

随着软件开发的不断进步&#xff0c;测试方法也在演变。企业需要紧跟新兴趋势&#xff0c;以提升软件质量、提高测试效率&#xff0c;并确保安全性&#xff0c;在竞争激烈的技术环境中保持领先地位。本文将深入探讨2025年最值得关注的五大软件测试趋势。 Parasoft下载https://…

w200基于spring boot的个人博客系统的设计与实现

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;原创团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文…

【B站保姆级视频教程:Jetson配置YOLOv11环境(十)镜像备份】

Jetson配置YOLOv11环境&#xff08;10&#xff09;镜像备份 B站视频的镜像已打包上传至百度网盘&#xff0c;镜像的硬盘空间使用量如下&#xff0c;感兴趣的小伙伴可自行下载烧录&#xff0c;需使用64g及以上的tf卡&#xff1a; (pytorch) nxnx-desktop:~$ df -h Filesystem …

了解大语言模型的基本原理(一)——Transformer工作原理

为什么选择Transformer&#xff1f; RNN&#xff1a;无法并行计算&#xff0c;不擅长处理长序列 LSTM&#xff1a;依然存在这两个问题 Transformer&#xff1a;可以并行计算&#xff0c;并且能学习输入序列里所有词的相关性和上下文关系 Tranformer优点&#xff1a; 1、注…

【Matlab优化算法-第13期】基于多目标优化算法的水库流量调度

一、前言 水库流量优化是水资源管理中的一个重要环节&#xff0c;通过合理调度水库流量&#xff0c;可以有效平衡防洪、发电和水资源利用等多方面的需求。本文将介绍一个水库流量优化模型&#xff0c;包括其约束条件、目标函数以及应用场景。 二、模型概述 水库流量优化模型…

JAVA:CloseableHttpClient 进行 HTTP 请求的技术指南

1、简述 CloseableHttpClient 是 Apache HttpComponents 提供的一个强大 HTTP 客户端库。它允许 Java 程序与 HTTP/HTTPS 服务交互&#xff0c;可以发送 GET、POST 等各种请求类型&#xff0c;并处理响应。该库广泛用于 REST API 调用、文件上传和下载等场景。 2、特性 Close…

(2024|Nature Medicine,生物医学 AI,BiomedGPT)面向多种生物医学任务的通用视觉-语言基础模型

BiomedGPT: A generalist vision–language foundation model for diverse biomedical tasks 目录 1. 摘要 2. 引言 3. 相关研究 3.1 基础模型与通用生物医学 AI 3.2 生物医学 AI 的局限性 3.3 BiomedGPT 的创新点 4. 方法 4.1 架构及表示 4.1.1 模型架构选择 4.1.2 …

使用DeepSeek实现AI自动编码

最近deepseek很火&#xff0c;低成本训练大模型把OpenAI、英伟达等股票搞得一塌糊涂。那它是什么呢&#xff0c;对于咱们程序员编码能有什么用呢&#xff1f;DeepSeek 是一款先进的人工智能语言模型&#xff0c;在自然语言处理和代码生成方面表现出色。它经过大量代码数据训练&…

Linux之Https协议原理

Linux之Https协议原理 一.Https协议的概念二.常见的加密方法三.数据摘要&#xff08;数字指纹&#xff09;四.Https协议加密方法的逐渐完善4.1使用对称或者非对称加密4.2增加CA证书 一.Https协议的概念 Https协议是基于Http协议延申出的一种应用层协议&#xff0c;其原理就是在…

基于Java的在线购物系统的设计与实现

引言 课题背景 随着Internet国际互联网的发展&#xff0c;越来越多的企业开始建造自己的网站。基于Internet的信息服务&#xff0c;商务服务已经成为现代企业一项不可缺少的内容。很多企业都已不满足于建立一个简单的仅仅能够发布信息的静态网站。现代企业需要的是一个功能强…

HarmonyOS 5.0应用开发——全局自定义弹出框openCustomDialog

【高心星出品】 文章目录 全局自定义弹出框openCustomDialog案例开发步骤完整代码 全局自定义弹出框openCustomDialog CustomDialog是自定义弹出框&#xff0c;可用于广告、中奖、警告、软件更新等与用户交互响应操作。开发者可以通过CustomDialogController类显示自定义弹出框…

CSS基本语法和常用属性

目录 一、CSS二、CSS基本语法三、CSS的三种形式1、行内样式2、内部样式3、外部样式4、三者的优先级问题5、代码演示 四、选择器1 基础选择器1.1标签选择器1.2 ID选择器1.3 Class选择器1.4 属性选择器 2. 组合选择器2.1 层次选择器4.2.2 并列选择器 3. 伪类选择器4、选择器的优先…

白嫖RTX 4090?Stable Diffusion:如何给线稿人物快速上色?

大家都知道&#xff0c;在设计的初期&#xff0c;我们通常会先绘制草图&#xff0c;然后再进行上色处理&#xff0c;最终才开始进行最终的设计工作。在这个上色的过程中&#xff0c;配色是至关重要的一环。这不仅方便了内部同事的评审&#xff0c;也让产品方和客户可以直观地了…