【自学笔记】01Java基础-07面向对象基础-04接口与内部类详解
记录学习Java基础中有关接口类和内部类的知识。
1 接口
interface
关键字用于定义接口类,接口类是一系列方法的声明,一般只有方法的特征没有方法的实现,因此可以被不同的类接入实现,而这些实现可以具有不同的行为(功能)。
接口类似于抽象类(抽象类概念),其所有的方法默认是公开且抽象的(默认 public abstract
修饰),所有的成员变量默认是静态、不可变的常量( public static final
)。Java8开始,接口类也可以有非抽象的static静态方法和default方法,java9新增只能内部访问的private方法。
1.1 接口类的声明
- 使用
interface
关键字来定义一个接口。接口中所有的成员都是public的,即使不显式声明。
public interface InterfaceClass {// 常量声明,默认public static finalint CONSTANT_VARIABLE = 10; // 方法声明,默认是public abstract,可以省略void someMethod();// 默认方法defaultdefault void myDefaultMethod() {// ...}// 静态方法staticstatic void myStaticMethod() {// ...}
}
-
接口类方法:
- 接口中的所有方法默认具有
public abstract
修饰符(即使没有声明),实现了该接口的类必须实现所有方法。(java8新增的方法除外) - default方法:从java8开始,可以含
default
声明的方法,实现类可以直接使用或实现方法来覆写这类方法。 - static静态方法:从java8开始,可以含
static
声明的方法,实现类可以直接类名.方法名()调用,但不能实现。 - private私有方法:从java9开始,可以含
private
声明的方法,只能被本类其他默认方法或私有方法使用。
- 接口中的所有方法默认具有
-
静态常量:
- 接口中只能声明常量,无需显式声明
public static final
,它们自动具有这些修饰符,并且必须初始化赋值。
- 接口中只能声明常量,无需显式声明
1.2 实现类的声明
- 使用
implements
关键字来实现一个或多个接口,并提供接口中声明的所有抽象方法的实现。 - 如果实现类不能实现接口的所有抽象方法,这个类需要声明为抽象类。>抽象类概念
public class ImplClass implements InterfaceClass_1,InterfaceClass_2 {@Overridepublic void someMethod() {// 实现接口类中所有非静态的方法体// 接口类中default声明的方法可选实现}
}
1.3 接口的实现对比抽象类的继承
- 类和类的关系:单继承。
- 类和接口的关系:多实现。
- 接口和接口的关系:多继承,一个接口可以同时继承多个接口。
1.4 接口多继承的作用
规范合并,整合多个接口为同一个接口,便于子类实现。
1.5 接口的注意事项
1、接口不能创建对象
2、一个类实现多个接口,多个接口的规范不能冲突
2、一个类实现多个接口,多个接口中有同样的静态方法不冲突。(使用接口.方法名()调用)
3、一个类继承了父类,同时又实现了接口,父类中和接口中有同名方法,默认用父类的。
4、一个类实现了多个接口,多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。
5、一个接口继承多个接口,是没有问题的,如果多个接口中存在规范冲突则不能多继承。
1.6 接口的作用
- 接口主要用于定义某种规范或者协议,确保不同类的对象之间能够共享相同的行为特征。
- 它们在设计模式中广泛用于实现松耦合和面向接口编程,有助于提高代码的可重用性和可扩展性。
2 内部类
内部类就是定义在一个类里面的类,里面的类可以理解成(寄生),外部类可以理解成(宿主)。
public class People{// 内部类public class Heart{}
}
内部类的使用场景
- 场景:当一个事物的内部,还有一个部分需要一个完整的结构进行描述时。
基本作用
- 内部类通常可以方便访问外部类的成员,包括私有的成员。
- 内部类提供了更好的封装性,内部类本身就可以用private ,protectecd等修饰,封装性可以做更多控制
2.1 内部类的分类
- 静态内部类[了解]
- 成员内部类(非静态内部类) [了解]
- 局部内部类[了解]
- 匿名内部类(重点)
2.2 静态内部类[了解]
什么是静态内部类?
- 有static修饰,属于外部类本身。
- 它的特点和使用与普通类是完全一样的,类有的成分它都有,只是位置在别的类里面而已。
2.3 成员内部类[了解]
什么是成员内部类?
- 无static修饰,属于外部类的对象。
- JDK16之前,成员内部类中不能定义静态成员,JDK 16开始也可以定义静态成员了。
答案:heartbeat, this.heartbeat, People.this.heartbeat
2.4 局部内部类[了解]
2.5 匿名内部类【重点】
- 本质上是没有名字的局部内部类,同时也是一个对象,因此在创建时既声明又实例化。
- 同时代表一个对象,其对象类型为当前new的那个类的子类。
- 匿名内部类通常用在只使用一次且不需要单独定义一个类的情况下,简化代码编写。
1. 使用场景:
- 当需要快速定义一个类来响应事件(如:Java Swing中的ActionListener)。
- 当需要临时实现一个接口而不想为此创建单独的类文件时。
2. 定义与创建:
匿名内部类的格式如下:
//创建方式,new+类名()
new 外部类名() | 实现接口名() | 抽象类名(){// 实现父类方法或接口方法// 可以定义自己的成员变量和方法
};
//引用给对象
类名 对象名 = new 外部类名() | 实现接口名() | 抽象类名(){...}
Class c = new Class(){public void run(){}
};
c.run();
例如,实现一个Runnable接口的匿名内部类:
new Runnable() {@Overridepublic void run() {System.out.println("Running in anonymous class");}
}.run();
或者继承一个抽象类并覆盖其方法:
abstract class Animal {abstract void sound();
}new Animal() {@Overridevoid sound() {System.out.println("Animal makes a sound");}
}.sound();
3. 特点:
- 没有名称:匿名内部类由于没有名字,所以不能被引用,只能通过其父类或接口类型引用。
- 局部作用域:匿名内部类可以访问包含它的外部类的所有成员(包括私有成员),同时也可以定义自己的局部变量,但这些变量必须是final或者事实上是final的。
- 构造器限制:匿名内部类没有独立的构造函数,初始化过程通过构造代码块完成,即在类体中直接初始化成员变量。
- 静态限制:匿名内部类不能包含静态成员、静态初始化块和静态方法,因为它们没有类名,无法直接指向静态成员。
- 生命周期依赖外部类:匿名内部类的对象会隐式持有对外部类对象的引用,其生命周期受外部类实例的影响。
4. 注意事项:
- 如果匿名内部类要访问外部方法的参数或者局部变量,那么这些变量必须是final或者实际上不可变的(尽管在Java 8之后,编译器允许省略final关键字,但仍要求实际行为不变)。
以下是一个实际案例,展示匿名内部类用于实现事件监听器:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;// 假设我们有一个GUI组件(如按钮)
javax.swing.JButton button = new javax.swing.JButton("Click me!");// 按钮需要一个ActionListener来响应点击事件
// 而我们并不需要多次复用这个监听器,因此可以使用匿名内部类// 通过匿名内部类创建并实例化ActionListener
button.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// 当按钮被点击时,执行的逻辑System.out.println("Button is clicked!");}
});// 添加监听器到按钮上
frame.add(button);// 显示GUI
// ...
在这个例子中,我们没有创建一个新的ActionListener子类,而是直接new一个临时的、未命名的类实现ActionListener
接口。这样做的好处是能够将与按钮相关的操作逻辑紧密地封装在一起,同时简化代码编写。
另外,匿名内部类也可以用来扩展具体的类,例如在Android开发中,经常会有这样的场景:
public class MainActivity extends AppCompatActivity {private Button myButton;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);myButton = findViewById(R.id.my_button);// 使用匿名内部类实现OnClickListener接口myButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(MainActivity.this, "Button was clicked!", Toast.LENGTH_SHORT).show();// 在这里处理按钮点击事件}});}
}
在这个Android示例中,我们同样利用匿名内部类创建了一个OnClickListener对象,当myButton被点击时执行相应的逻辑。
相关文章:

【自学笔记】01Java基础-07面向对象基础-04接口与内部类详解
记录学习Java基础中有关接口类和内部类的知识。 1 接口 interface 关键字用于定义接口类,接口类是一系列方法的声明,一般只有方法的特征没有方法的实现,因此可以被不同的类接入实现,而这些实现可以具有不同的行为(功…...

【cmu15445c++入门】(5)c++中的模板类
一、template模板类 除了模板方法【cmu15445c入门】(4)c中的模板方法 模板也可以用来实现类 二、代码 /*** file templated_classes.cpp* author Abigale Kim (abigalek)* brief Tutorial code for templated classes.*/// Includes std::cout (printing). #include <io…...
MongoDB聚合:$bucket
$bucket将输入文档按照指定的表达式和边界进行分组,每个分组为一个文档,称为“桶”,每个桶都有一个唯一的_id,其值为文件桶的下线。每个桶中至少要包含一个输入文档,也就是没有空桶。 使用 语法 {$bucket: {groupBy…...

从优化设计到智能制造:生成式AI在可持续性3D打印中的潜力和应用
可持续性是现代工业中一个紧迫的问题,包括 3D 打印领域。为了满足环保制造实践日益增长的需求,3D 打印已成为一种有前景的解决方案。然而,要使 3D 打印更具可持续性,还存在一些需要解决的挑战。生成式人工智能作为一股强大的力量&…...

vue3 响应式api中特殊的api
系列文章目录 TypeScript 从入门到进阶专栏 文章目录 系列文章目录一、shallowRef()二、triggerRef()三、customRef()四、shallowReactive()五、shallowReadonly()六、toRaw()七、markRaw()八、effectScope()九、getCurrentScope() 一、shallowRef() shallowRef()是一个新的响…...
【大厂算法面试冲刺班】day2:合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 递归 class Solution {public ListNode mergeTwoLists(ListNode l1, ListNode l2) {if (l1 null) {return l2;}else if (l2 null) {return l1;}else if (l1.val < l2.…...

【JaveWeb教程】(19) MySQL数据库开发之 MySQL数据库操作-DML 详细代码示例讲解
目录 3. 数据库操作-DML3.1 增加(insert)3.2 修改(update)3.3 删除(delete)3.4 总结 3. 数据库操作-DML DML英文全称是Data Manipulation Language(数据操作语言),用来对数据库中表的数据记录进行增、删、改操作。 添加数据(INSERT)修改数据…...

Web前端篇——ElementUI之el-scrollbar + el-backtop + el-timeline实现时间轴触底刷新和一键返回页面顶部
ElementUI之el-scrollbar el-backtop el-timeline实现时间轴触底刷新和一键返回页面顶部。 背景:ElementUI的版本(vue.global.js 3.2.36, index.css 2.4.4, index.full.js 2.4.4) 废话不多说,先看动…...
CAS-ABA问题编码实战
多线程情况下演示AtomicStampedReference解决ABA问题 package com.nanjing.gulimall.zhouyimo.test;import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicStampedReference;/*** @author zho…...

Linux 常用进阶指令
我是南城余!阿里云开发者平台专家博士证书获得者! 欢迎关注我的博客!一同成长! 一名从事运维开发的worker,记录分享学习。 专注于AI,运维开发,windows Linux 系统领域的分享! 其他…...

windows通过ssh连接Liunx服务器并实现上传下载文件
连接ssh 输入:ssh空格用户名ip地址,然后按Enter 有可能出现下图提示,输入yes 回车即可 输入 password ,注意密码是不显示的,输入完,再按回车就行了 以上是端口默认22情况下ssh连接,有些公司它…...

【K8S 存储卷】K8S的存储卷+PV/PVC
目录 一、K8S的存储卷 1、概念: 2、挂载的方式: 2.1、emptyDir: 2.2、hostPath: 2.3、NFS共享存储: 二、PV和PVC: 1、概念 2、请求方式 3、静态请求流程图: 4、PV和PVC的生命周期 5、…...

工业智能网关如何保障数据通信安全
工业智能网关是组成工业物联网的重要设备,不仅可以起到数据交换、通信、边缘计算的功能,还可以发挥数据安全保障功能,保障工业物联网稳定、可持续。本篇就为大家简单介绍一下工业智能网关增强和确保数据通信安全的几种措施: 1、软…...

基于Springboot的课程答疑系统(有报告)。Javaee项目,springboot项目。
演示视频: 基于Springboot的课程答疑系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构&…...
操作系统 内存相关
0 内存 cpu和内存的关系 内存覆盖 内存的覆盖是一种在程序运行时将部分程序和数据分为固定区和覆盖区的技术。这种技术的主要目的是为了解决程序较大,无法一次性装入内存导致无法运行的问题。 具体来说,内存的覆盖技术将用户空间划分为以下两个部分&…...

【模拟IC学习笔记】 PSS和Pnoise仿真
目录 PSS Engine Beat frequency Number of harmonics Accuracy Defaults Run tranisent?的3种设置 Pnoise type noise Timeaverage sampled(jitter) Edge Crossing Edge Delay Sampled Phase sample Ratio 离散时间网络(开关电容电路)的噪声仿真方法 PSS PSS…...

IPv6邻居发现协议(NDP)---路由发现
IPv6路由发现(前缀公告) 邻居发现 邻居发现协议NDP(Neighbor Discovery Protocol)是IPv6协议体系中一个重要的基础协议。邻居发现协议替代了IPv4的ARP(Address Resolution Protocol)和ICMP路由器发现(Router Discovery),它定义了使用ICMPv6报文实现地址解析,跟踪邻…...
OpenPLC v3 代码结构
OpenPLC v3 是一个基于 C 的开源实时自动化平台,主要用于控制和自动化行业中的设备。该项目具有以下主要模块: 1. Core:核心模块,提供数据结构和算法实现。 2. Master:主设备模块,实现与从设备通信的接口。…...
安全防御之备份恢复技术
随着计算机和网络的不断普及,人们更多的通过网络来传递大量信息。在网络环境下,还有各种各样的病毒感染、系统故障、线路故障等,使得数据信息的安全无法得到保障。由于安全风险的动态性,安全不是绝对的,信息系统不可能…...
条款39:明智而审慎地使用private继承
1.前言 在之前挑款32曾讨论了C如何将public继承视为is-a关系,在那个例子中我们有个继承体系,其中class Student以public形式继承class Person,于是编译器在必要时刻将Student转换为Persons。。现在,我在以原先那个例子࿰…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...