Java笔试面试题AI答之面向对象(9)

news2024/9/22 21:33:33

文章目录

  • 49. 简述Java继承时,类的执行顺序是什么?
      • 一、类的静态成员初始化顺序
      • 二、对象的初始化顺序
      • 三、总结
  • 50. 举例说明什么情况下会更倾向于使用抽象类而不是接口?
      • 1. 当需要定义和实现部分通用行为时
      • 2. 当需要访问修饰符或方法修饰符时
      • 3. 当需要定义成员变量时
      • 4. 当需要限制继承关系时
  • 51. 请列举适配器模式的应用场景 ?
      • 1. 接口不兼容
      • 2. 类的复用
      • 3. 封装适配逻辑
      • 4. 设计灵活性
      • 5. 其他应用场景
  • 52. 解释 Java 中,为什么不允许从静态方法中访问非静态变量?
  • 53. 简述Java中继承与聚合的区别 ?
      • 继承(Inheritance)
        • 优点
        • 缺点
      • 聚合(Aggregation)
        • 优点
        • 缺点
      • 总结
  • 54. Java序列化和反序列化为什么要实现Serializable接口?

49. 简述Java继承时,类的执行顺序是什么?

在Java中,继承是面向对象编程的一个重要特性,它允许我们定义一个类(子类)来继承另一个类(父类)的属性和方法。当涉及到类的执行顺序时,主要关注的是类的初始化顺序,包括静态成员、非静态成员以及构造方法的执行顺序。以下是Java继承时类的执行顺序的详细说明:

一、类的静态成员初始化顺序

  1. 父类静态变量和静态代码块:当类被加载到JVM中时,首先会初始化父类的静态变量和静态代码块(按它们在类中出现的顺序)。静态代码块在类加载时执行,且只执行一次。

  2. 子类静态变量和静态代码块:接着,会初始化子类的静态变量和静态代码块(同样按它们在类中出现的顺序)。

二、对象的初始化顺序

  1. 父类非静态变量:在创建对象时,首先为父类的非静态变量(实例变量)分配内存,并进行默认初始化(如果未显式初始化)。

  2. 父类构造代码块:然后执行父类的构造代码块(如果有的话),这些代码块在父类构造方法之前执行。

  3. 父类构造方法:接下来调用父类的构造方法。如果子类构造方法中没有显式调用父类的构造方法(通过super()),则默认调用父类的无参构造方法。

  4. 子类非静态变量:为子类的非静态变量分配内存,并进行默认初始化(如果未显式初始化)。

  5. 子类构造代码块:执行子类的构造代码块(如果有的话)。

  6. 子类构造方法:最后执行子类的构造方法。

三、总结

Java继承时类的执行顺序可以概括为:

  1. 父类静态变量和静态代码块(按出现顺序)
  2. 子类静态变量和静态代码块(按出现顺序)
  3. 父类非静态变量初始化
  4. 父类构造代码块
  5. 父类构造方法
  6. 子类非静态变量初始化
  7. 子类构造代码块
  8. 子类构造方法

需要注意的是,静态成员(包括静态变量和静态代码块)的初始化只会在类加载时执行一次,与创建多少个类的实例无关。而非静态成员的初始化和构造方法的调用则是在每次创建类的实例时都会进行的。此外,如果子类构造方法中显式调用了父类的有参构造方法,则不会调用父类的无参构造方法。

50. 举例说明什么情况下会更倾向于使用抽象类而不是接口?

在软件开发过程中,选择使用抽象类还是接口往往取决于具体的设计需求和场景。以下是一些更倾向于使用抽象类而不是接口的情况:

1. 当需要定义和实现部分通用行为时

场景描述:当你希望为一系列子类提供一个共同的模板,并在这个模板中实现一些通用方法时,抽象类是一个更好的选择。接口只能定义方法的签名,而不能提供具体实现。

举例:假设你正在开发一个游戏,其中有多种角色(如战士、法师、盗贼等),这些角色都有一些共同的行为,如移动、攻击等。同时,每种角色还有其独特的技能。在这种情况下,你可以定义一个抽象类Character,其中包含移动和攻击等通用方法的实现,并让具体的角色类(如WarriorMageRogue)继承这个抽象类,并实现各自独特的技能方法。

2. 当需要访问修饰符或方法修饰符时

场景描述:接口中的方法默认是public abstract的,且不能有实现体。而抽象类中的方法可以有各种访问修饰符(如publicprotected)和方法修饰符(如staticfinal,但抽象方法不能是final的),以及可以有实现体。

举例:如果你需要定义一个方法,这个方法在某些子类中可能有默认实现,但在其他子类中需要被重写,那么你可以将这个方法放在抽象类中,并根据需要设置其访问修饰符。

3. 当需要定义成员变量时

场景描述:接口中不能定义成员变量(只能定义常量),而抽象类中可以定义成员变量。如果子类需要继承一些共同的属性,那么抽象类更合适。

举例:假设你正在开发一个图书馆管理系统,其中有多种书籍(如小说、教材、杂志等)。这些书籍都有一些共同的属性,如ISBN号、作者、出版日期等。你可以定义一个抽象类Book,其中包含这些共同属性的定义,并让具体的书籍类(如NovelTextbookMagazine)继承这个抽象类。

4. 当需要限制继承关系时

场景描述:在某些情况下,你可能希望限制只有特定的类才能继承某个类,或者希望控制继承的层次结构。虽然这可以通过其他设计模式(如工厂模式、单例模式等)来实现,但抽象类本身也可以作为一种限制手段。

举例:在某些框架或库中,可能有一个基础的抽象类,它定义了一系列核心方法和属性,但出于设计考虑,只允许特定的子类来继承这个抽象类。这可以通过将抽象类的构造方法设置为protectedprivate(虽然通常不推荐将抽象类的构造方法设置为private,因为这将使得抽象类无法被实例化,但可以通过其他方式如静态工厂方法来创建实例),并结合包级私有访问控制来实现。

综上所述,抽象类和接口各有其适用场景。在需要定义和实现部分通用行为、需要访问修饰符或方法修饰符、需要定义成员变量或需要限制继承关系时,更倾向于使用抽象类。然而,在实际开发中,应根据具体的设计需求和场景来灵活选择使用抽象类还是接口。

51. 请列举适配器模式的应用场景 ?

适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将一个类的接口转换成客户端所期望的另一个接口,使原本由于接口不兼容而不能一起工作的类可以协同工作。以下是适配器模式的一些主要应用场景:

1. 接口不兼容

  • 老代码与新接口:当系统中的某个类的接口与客户端期望的接口不兼容时,可以使用适配器模式将老代码适配到新接口上,从而避免修改原有代码带来的风险。
  • 第三方库接口适配:在使用第三方库时,如果第三方库的接口与现有系统的接口不兼容,可以通过适配器模式将第三方库的接口转换成系统所期望的接口。

2. 类的复用

  • 复用现有类:当需要复用一些现有的类,但其接口与系统要求的接口不匹配时,可以通过适配器模式将这些类适配到系统中,提高代码复用率。
  • 遗留系统整合:在整合遗留系统时,可能会遇到接口不兼容的问题,适配器模式可以帮助解决这一问题,使得新系统能够与遗留系统顺利交互。

3. 封装适配逻辑

  • 业务逻辑无关的适配:当需要封装与具体业务逻辑无关的适配逻辑时,可以使用适配器模式将适配的细节封装在适配器中,使客户端代码更简洁、更专注于业务逻辑的实现。

4. 设计灵活性

  • 扩展接口:在系统设计初期,可能无法准确预测未来所有可能的接口需求。通过使用适配器模式,可以在不修改现有代码的情况下,通过添加新的适配器类来扩展接口,提高系统的可扩展性。
  • 支持多种数据源:在处理多种数据源时,每种数据源可能有不同的接口。通过适配器模式,可以为每种数据源提供一个适配器类,将这些数据源的接口统一转换成系统内部使用的接口,从而提高系统的灵活性和可维护性。

5. 其他应用场景

  • 双向适配器:在某些情况下,可能需要双向适配,即既可以将适配者接口转换成目标接口,也可以将目标接口转换成适配者接口。双向适配器模式可以满足这种需求。
  • 框架与库之间的桥接:在开发过程中,可能会使用多个框架或库,这些框架或库之间可能存在接口不兼容的问题。通过适配器模式,可以在这些框架或库之间建立桥接,使它们能够协同工作。

综上所述,适配器模式在软件开发中具有广泛的应用场景,特别是在处理接口不兼容、类的复用、封装适配逻辑、提高设计灵活性等方面发挥着重要作用。

52. 解释 Java 中,为什么不允许从静态方法中访问非静态变量?

在Java中,不允许从静态方法中访问非静态变量,这主要是由于静态和非静态成员之间的根本区别决定的。

  1. 存储位置不同

    • 静态变量存储在方法区的静态区域,属于类级别,所有实例共享一份数据。
    • 非静态变量存储在堆内存中,属于对象级别,每个对象都有自己的副本。
  2. 生命周期不同

    • 静态变量随着类的加载而加载,随着类的卸载而卸载。
    • 非静态变量随着对象的创建而存在,随着对象的销毁而销毁。
  3. 访问方式不同

    • 静态方法可以通过类名直接调用,无需创建对象。
    • 非静态方法必须通过对象来调用。

由于这些差异,静态方法中没有this关键字的概念,this关键字用于引用当前对象,而静态方法是属于类的,不属于任何对象。因此,静态方法中无法直接访问属于对象级别的非静态变量。

如果需要在静态方法中访问非静态变量,你可以通过创建类的实例(对象)来访问,或者使用静态方法传递非静态变量作为参数的方式进行访问。这样做是因为非静态变量依赖于具体的对象实例,而静态方法在没有对象实例的情况下也能被调用,所以直接访问非静态变量是不合理的。

53. 简述Java中继承与聚合的区别 ?

在Java中,继承(Inheritance)和聚合(Aggregation)是实现代码复用和组织类之间关系的两种不同方式。它们各有特点,适用于不同的场景。

继承(Inheritance)

继承是面向对象编程中的一个核心概念,它允许创建一个基于现有类的新类,继承其属性和方法,并可以添加新的属性和方法或覆盖(Override)现有的方法。继承关系表示一种“是一个(is-a)”的关系。例如,如果我们有一个Animal类,那么Dog类可以通过继承Animal类来获得Animal类的特性,并且Dog“是一个”Animal

优点
  • 代码复用
  • 方法重写,实现多态
缺点
  • 破坏封装性
  • 父类变,子类就得变
  • 继承是侵入性的

聚合(Aggregation)

聚合是另一种类之间的关系,表示“有一个(has-a)”的关系。在这种关系中,一个类包含对另一个类的引用作为它的成员变量。与继承不同,聚合允许你将不同的类组合在一起,以表示更复杂的结构,同时保持类的独立性。例如,Classroom类可以包含一个Student类的列表,表示这个班级有这些学生,但是Classroom并不是Student的一种类型。

优点
  • 降低了类之间的耦合度
  • 提高了代码的灵活性和可维护性
缺点
  • 需要手动管理对象之间的关系

总结

  • 继承主要用于表示类之间的层次关系,是“是一个”的关系。
  • 聚合主要用于表示类之间的组合关系,是“有一个”的关系。
  • 继承是强耦合的,子类依赖于父类的实现;而聚合是松耦合的,允许类之间的独立开发和使用。
  • 在实际开发中,应该优先考虑使用聚合,因为它提供了更好的灵活性和可维护性,只有在确实需要表示“是一个”的关系时才使用继承。

54. Java序列化和反序列化为什么要实现Serializable接口?

在Java中,序列化和反序列化是对象持久化的两种基本机制。序列化是指将对象的状态信息转换为可以存储或传输的形式的过程,以便稍后可以通过反序列化重建对象。为了实现这一过程,Java提供了一个称为Serializable的标记接口。

Serializable接口是一个标记接口,它不包含任何方法。它的作用主要是告诉Java虚拟机(JVM),这个类的对象可以被序列化。JVM在序列化对象时会检查对象所属的类是否实现了Serializable接口,如果没有实现,就会抛出NotSerializableException异常。

实现Serializable接口有几个好处:

  1. 兼容性:实现Serializable接口的类可以确保序列化的对象版本与类定义版本之间的兼容性。

  2. 安全性:Java序列化机制提供了基于对象序列化的安全特性,比如防止对敏感信息的非法访问。

  3. 易于实现:开发者只需实现Serializable接口,JVM就会自动处理序列化和反序列化的过程,无需编写额外的代码。

然而,仅仅实现Serializable接口并不足以处理所有序列化相关的问题。例如,如果一个类的某些字段是敏感的,不应该被序列化,可以使用transient关键字标记这些字段。此外,还可以自定义序列化过程,通过实现readObjectwriteObject方法,来精确控制序列化和反序列化的行为。

总的来说,Serializable接口是Java序列化机制的核心,它使得对象可以被序列化和反序列化,同时提供了灵活性和安全性,使得开发者可以根据需要定制序列化过程。

答案来自文心一言,仅供参考
在这里插入图片描述

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

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

相关文章

07.整合Pinia

1. 前言 Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。更加契合 VUE3 组合式 API 和 TS 类型支持。想进一步了解,参考官网:https://pinia.vuejs.org/ 如果是使用官方脚手架搭建的工程,选择了 pinia 将会自动帮我…

Git之2.5版本重要特性及用法实例(五十七)

简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者. 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列…

Qt应用的高分辨率适配

背景 工作中需要面对触控大屏的4K分辨率场景,同时也有越来越多人开始使用高分屏,原来多基于1080p分辨率开发的Qt程序无法很好适配更高的分辨率。 没有特意针对高分辨率场景做适配时,Qt应用的表现通常有两种情况: 分辨率高的情况…

六西格玛管理培训公司 谈 故障树分析(Fault Tree Analysis)

故障树分析(Fault Tree Analysis, FTA):一种自顶向下的演绎故障分析工具,其中使用布尔逻辑将一系列较低级别的事件组合起来,用以分析系统的非期望状态。那么,如何使用故障树分析(FTA&#xff09…

集成电路学习:什么是CRC循环冗余校验

一、CRC:循环冗余校验 CRC(Cyclic Redundancy Check),即循环冗余校验,是一种根据网络数据包或计算机文件等数据产生简短固定位数校验码的快速算法。它主要用于检测或校验数据传输或保存后可能出现的错误。CRC利用除法及…

[Labview] 表格改值后单元格编辑功能,更改颜色、字体、颜色等

效果如下所示: 例子中演示了单元格变色,具体需要什么修改,在相同的位置进行操作即可。 检测到[鼠标释放]事件,则记录被选中的单元格。 使用[鼠标按下]事件也可以,不过我个人测试下来,[按下]的判断精准度不…

智能候诊系统 项目源码25287

摘 要 科技进步的飞速发展引起人们日常生活的巨大变化,电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流,人类发展的历史正进入一个新时代。在现实运用中,应用软件的工作…

万亿低空经济:无人机飞手考证正当时

随着低空经济的不断发展和国家政策的持续推动,无人机行业正迎来前所未有的发展机遇。低空经济作为一种新兴的综合性经济形态,依托低空空域,通过各类有人驾驶和无人驾驶航空器的低空飞行活动,辐射带动相关领域融合发展。这一领域涉…

视频结构化从入门到精通——GPU主要硬件平台介绍

视频结构化主要硬件平台 1. 深度学习中“硬”和“软”的概念 在深度学习中,“硬”和“软”通常用于描述不同的处理方法或策略,尤其是在解码、编码、推理等任务中。它们反映了算法在处理信息时的确定性和灵活性。 软(Soft) 处理…

电子检测报告如何盖骑缝章?

电子检测报告如何盖骑缝章?使用e章宝(易友EU3000智能盖章软件)给电子检测报告盖骑缝章,可以遵循以下步骤进行: 一、准备工作 确保e章宝软件已安装: 在计算机上安装e章宝(易友EU3000智能盖章软件…

小程序页面跳转传url参数被截取问题

跳转时处理 const params {url:hhtp://www.baidu.com?a1}const queryString Object.keys(params).map(key > ${encodeURIComponent(key)}${encodeURIComponent(params[key])}).join(&);wx.navigateTo({url: ../../toPageView/toPageView?${queryString},})webview页…

推荐Windows11中帮助提高远程工作效率的6个最佳工具

序言 由于我们中的许多人都在远程工作,Windows 11附带了一些内置的焦点工具来帮助我们完成工作也就不足为奇了。但是,Windows 11究竟为我们这些想要确保我们真正完成工作的专业人士提供了什么?让我们来看看。 专注期和生产力 Windows 11取消了任务栏上的焦点模式,代之以…

李林880重点题推荐

考研倒计时113天,九月份即将来临,目前大家都处在强化阶段的学习中。虽然每个人的复习进度有所不同,但无论进展如何,我们都要保持良好的心态。进度快的同学要继续稳扎稳打,而进度稍慢的同学也不要焦虑,保持专…

部署 Web 项目到 Linux,可以使他人也访问项目的方法

目录 一、环境配置 二、建构项目并打包 三、上传Jar包到服务器, 并运行 3.1 上传Jar包 3.2 运行 jar 包 3.3 开放端口号 四、其他问题 4.1 运行异常问题 4.2 杀掉进程 五、总结 一、环境配置 如果本地项目是SpringBoot项目,使用的数据库是MySQL&#xff…

C语言基础(二十六)

二叉树节点通常包含三个部分&#xff1a;存储数据的部分、指向左子节点的指针、以及指向右子节点的指针。 测试代码&#xff1a; #include "date.h" #include <stdio.h> #include <stdlib.h> #include <time.h> // 定义二叉树节点的结构&a…

Linux虚拟机搭建K8S环境

文章目录 一、环境准备二、系统初始化三、部署master四、添加node节点五、部署网络六、部署dashboard七、登录dashboard面板 一、环境准备 首先在vmware上新建4台相同配置的虚拟机&#xff0c;除了IP和主机名外&#xff0c;其余配置相同。由于是搭建K8S初始环境&#xff0c;没…

Pyqt5高级技巧:多线程任务、窗体交互、常用控件介绍(含基础Demo)

一、多线程任务和多窗体交互 【main】 import MainForm #import CRUD import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBoxif __name__ __main__:app QApplication(sys.argv)MainWindow QMainWindow()ui MainForm.Ui_MainWindow()#也可能是Ui…

算法设计与分析:实验三 回溯法——地图填色问题

实验内容与要求&#xff1a; 问题描述&#xff1a; 我们可以将地图转换为平面图&#xff0c;每个地区变成一个节点&#xff0c;相邻地区用边连接&#xff0c;我们要为这个图形的顶点着色&#xff0c;并且两个顶点通过边连接时必须具有不同的颜色。附件是给出的地图数据&#…

如何在 MySQL 中使用 Socket 身份验证 ?

在 MySQL 和 MariaDB 中&#xff0c;可以使用 socket 身份验证&#xff0c;而不是传统的用户名和密码组合。这种方法既安全又方便&#xff0c;因为它使用的是操作系统的用户凭证。 什么是 Socket 身份验证? Socket 身份验证允许使用 Unix 或 Linux 用户凭证连接到数据库&…

NS4892B 蓝牙耳机充电仓-线性锂电池充放电管理 IC

1 特性 充电部分  (0V) 涓流 / 恒流 / 恒压三段式充电  内部设定 300mA 充电电流  线性工作模式充电  内置自动复充功能  内部预设 4.2V 充电浮充电压  内置过温保护 放电部分  同步升压输出 5.1V  放电开关频率 1MHz  放电效率最…