内部类 --- (寄生的哲学)
内部类总共有 4 种(静态内部类、非静态内部类、局部内部类、匿名内部类)
作用:
一:内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。
二:内部类可以直接访问外部类的私有数据,因为内部类被当成其外部类成员,同一个类的成员之间可以互相访问,但是外部类不能访问内部类的实现细节,例如内部类的成员变量。
三:匿名内部类适合用于创建那些只需要创建一次使用的类。
四:内部类比外部类可以多使用三个修饰符:private、protected、static
五:非静态内部类不能拥有静态成员。
1.非静态内部类:
非静态内部类定义在外部类里面
public class Demo {private String name;private Integer age;//定义构造器重载public Demo(){}public Demo(String name, Integer age) {this.name = name;this.age = age;}//定义一个非静态内部类private class InnerDemo {//非静态内部类private double length;private String color;public InnerDemo(){}public InnerDemo(double length, String color) {this.length = length;this.color = color;}// 此处省略 length 的getter 和 setter 方法.....................//非静态内部类实例方法public void info() {System.out.print("名字是:" + name + ": " + "年龄是: " + age +"肤色是: " + color + "身高是: " + length);}}public void test() {var innerDemo = new InnerDemo(180, "黄");innerDemo.info();}public static void main(String[] args) {Demo demo = new Demo("李白", 30);demo.test();}}
当非静态成员内部类的方法访问某个变量的时候,系统优先在该方法内查找是否存在该名字的局部变量,如果存在就使用该变量;如果不存在则查找该方法所在的内部类中是否存在该名字的成员变量, 如果不存在,则到外部类中查找是否存在该名字的成员变量,如果依然不存在,则会报编译错误:提示找不到该变量。
因此,如果外部类成员变量、内部类成员变量与内部类里面的方法同名,则可以通过使用 this、外部类类名.this 作为限定区分。
可以参考如下模板:
public class Demo {private String name = "外部类的成员变量";private class InClass {private String name = "内部类的成员变量";public void info(){var name = "局部变量";System.out.print("外部类的实例变量值:" + Demo.this.name);//通过 this.varName 访问内部类的成员变量System.out.print("内部类的成员变量:" + this.name);//直接访问局部变量System.out.print("局部变量的值:" + name);}}public void test() {var inClass = new InClass();inClass.info();}public static void main(String[] args) {Demo demo = new Demo();demo.test();}}
2. 静态内部类
使用 static 修饰的内部类被称为静态内部类,它属于外部类本身,不属于外部类某个实例对象。
静态内部类可以包含静态成员,也可以包含非静态成员。根据静态成员不能访问非静态成员的规则,静态内部类不能访问外部类的实例成员,只能访问外部类的类成员。即使是静态内部类的实例方法也不能访问外部类的实例成员,只能访问外部类的静态成员。
public class Demo {private String name = "李白";private static int age = 2;static class StaticInnerClass {//静态内部类可以包含静态成员private static String womanName = "李清照";public void info() {//下面代码出现错误,静态内部类不能访问外部类的实例变量System.out.print(name);//下面代码正常System.out.print(age);}}}
静态内部类是外部类的一个成员,因此外部类的所有方法、所有初始化块中可以使用静态内部类来定义变量、创建对象等
public class Demo {static class StaticInnerClass {private static int age = 10;private String name = "李白";}public void info() {//System.out.print(age)//上面代码出现错误,应改为如下格式//通过类名访问静态内部类的类成员System.out.print(StaticInnerClass.age);//System.out.print(name);//上面代码出现错误,应改为如下格式//通过实例访问静态内部类的实例成员System.out.print(new StaticInnerClass().name);}}
Java 还允许在接口里定义内部类,接口里定义的内部类默认使用 public static 修饰,也就是说接口内部类只能是静态内部类。
3.使用内部类:
1.在外部类内部使用内部类
在外部类内部使用内部类的时,与平常使用普通类没有太大的区别。一样可以直接通过内部类类名来定义变量,通过 new 调用内部类构造器来创建实例。
唯一的区别是:不要在外部类的静态成员(包括静态方法和静态初始化)中去使用非静态内部类,因为静态成员不能访问非静态成员。
在外部类内部定义内部类的子类与平常定义子类也没有太大的区别。
2.在外部类外部使用非静态内部类
如果想在外部类外部使用非静态内部类,则内部类不能使用 private 访问控制权限,private 修饰的内部类只能在外部类内部使用。对于使用其他访问控制符修饰的内部类,则能在访问控制符对应的访问权限内使用。
由于非静态内部类的对象必须寄生在外部类的对象里,因此创建非静态内部类对象之前,必须先创建其外部类对象。在外部类外面创建内部类实例的语法如下:
outerInstance.new InnerContructor();
当创建一个子类的时候,子类构造器总会调用父类的构造器,因此在创建非静态内部类的子类时,必须保证让子类构造器可以调用非静态内部类的构造器,调用非静态内部类的构造器时,必须存在一个外部类对象
class Out {class Inner {public Inner(String name) {System.out.print(name);}}
}public class Demo extends Out.Inner {//显式定义构造器public Demo(Out out) {out.super("Hello")}}
非静态内部类的子类不一定是内部类,它也可以是外部类。但非静态内部类的子类实例一样需要保留一个引用,该引用指向其父类所在外部类的对象。也就是说,如果有一个内部类子类的对象存在,则一定存在与之对应的外部类对象。
3.在外部类以外使用静态内部类。
因为静态内部类是外部类类相关的,因此创建静态内部类对象时无需创建外部类对象。创建语法如下:
new OutClass.InnerClass();
相比之下,使用静态内部类比使用非静态内部类要简单很多,只要把外部类当成静态内部类的包空间即可。因此当程序需要使用内部类时,应该优先考虑使用静态内部类。
4.局部内部类
把内部类定义在方法里面,这个就是局部内部类。局部内部类因为只能在方法里面有效,不能在外部类方法以外使用。所以不能使用访问控制符和 static 修饰符修饰。
局部内部类是一份非常鸡肋的语法,在实际开发中很少定义局部内部类,这是因为局部内部类的作用域太小了;只能在当前方法中使用。大部分时候,定义一个类之后,当然希望多次复用这个类,但局部内部类无法离开它所在的方法,因此在实际开发中很少使用。
5.匿名内部类
匿名内部类适合创建那种只需要创建一次使用的类,匿名内部类不能重复使用。
匿名内部类必须继承一个父类或者实现一个接口,但最多只能继承一个父类,或实现一个接口。
关于匿名内部类还有如下两条规则:
1.匿名内部类不能是抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象,所以不能把不允许将匿名内部类定义成抽象类。
2.匿名内部类不能定义构造器。由于匿名内部类没有类名,所以无法定义构造器,但可以定义初始化块,可以通过初始化块来完成构造器需要完成的事。
interface Animal {double getPrice();String getName();
}public class Demo {public void test(Animal a) {System.out.print("购买了一个: " + a.getName() + "价格是:" + a.getPrice());}public static void main(String[] args) {var tar = new Demo ();//调用 test()方法时需要传入一个 Animal 参数//此处传入匿名实现类的实例tar.test(new Animal() {public double getPrice() {return 567.9;}public String getName() {return "二哈";}});}}
上面程序中的 Animal 类定义了一个 test()方法,该方法需要一个 Animal 对象作为参数,但 Animal 只是一个接口,无法直接创建对象,因此此处创建一个 Animal 接口实现类的对象传入该方法----如果这个 Animal 接口实现类需要重复用,则应该将实现类定义为一个独立类:如果这个 Animal 接口实现类只需一次使用,则可以采用上面程序中的方式,定义一个匿名内部类。
定义匿名内部类无需 class 关键字,而是在定义匿名内部类的时候直接生成该匿名内部类的对象。
由于匿名内部类不能是抽象类,所以匿名内部类必须实现它的抽象类或者接口里面包含的所有抽象方法。
当通过实现接口创建匿名内部类时,匿名内部类不能显式地定义构造器,因此匿名内部类只有一个隐式的无参构造器,故 new 接口名后的括号里不能传入参数值。
但如果是通过继承父类来创建匿名内部类时,匿名内部类将拥有和父类相似的构造器,此处的相似指的时拥有相同的形参列表。
abstract class Device {private String name;public abstract double getPrice();public Device(){}public Device(String name) {this.name = name;}//此处省略 setter 和 getter 方法...}public class AnonymousInner {public void test(Device d) {System.out.print("购买了一个"+d.getName() + ", 花掉了"+d.getPrice());}public static void main(String[] args) {var ai = new AnonymousInner();ai.test(new Device("电饭煲") {public double getPrice(){return 500.2;}});//调用无参数的构造器创建Device 匿名实现类的对象var d = new Device(){//初始化块{System.out.print("匿名内部类的初始化块....");}//实现抽象方法public double getPrice() {return 56.2;}//重写父类的实例方法public String getName() {return "鼠标";}};ai.test(d);}}
上面的程序创建了一个抽象父类 Device 类,这个抽象父类包含两个构造器:一个无参数的,一个有参数的。当创建以Device 为父类的匿名内部类时,既可以传入参数,也可以不传入参数。
当创建匿名内部类时,必须实现接口或抽象类里面的所有抽象方法。如果有需要,也可以重写父类中的普通方法。
在 Java 8 之前,Java 要求被局部内部类、匿名内部类访问的局部变量必须使用 final 修饰,从 Java 8 开始这个限制被取消了,Java 8更加智能,如果局部变量被匿名内部类访问,那么该局部变量相当于自动加上了 final 修饰。
相关文章:

内部类 --- (寄生的哲学)
内部类总共有 4 种(静态内部类、非静态内部类、局部内部类、匿名内部类) 作用: 一:内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。 二:内部类可以…...

Python深度学习GRU、LSTM 、BiLSTM-CNN神经网络空气质量指数AQI时间序列预测及机器学习分析|数据分享...
全文链接:https://tecdat.cn/?p38742 分析师:Zhixiong Weng 人们每时每刻都离不开氧,并通过吸入空气而获得氧。一个成年人每天需要吸入空气达6500升以获得足够的氧气,因此,被污染了的空气对人体健康有直接的影响&…...

JSP基础
一、Tomcat 1.Tomcat简介: Tomcat是一个免费的开源JSP容器,是Apache的Jakarta项目中的一个核心项目因免费、稳定而成为目前比较流行的Web应用服务器网址:https://tomcat.apache.org/ 2.Tomcat的配置——环境变量 (1)…...

基于Springboot +Vue 在线考试管理系统
基于Springboot Vue 在线考试管理系统 前言 随着信息技术的飞速发展,教育领域正经历着深刻的变革。传统的考试模式因其诸多限制和不便,已难以满足现代教育的需求。基于SpringBoot和Vue框架开发的在线考试系统应运而生,它充分利用了现代互联…...

Node.js 函数
Node.js 函数 1. 概述 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境,它允许开发者使用 JavaScript 编写服务器端和网络应用程序。在 Node.js 中,函数是一等公民,意味着它们可以作为变量传递,可以作为参数传递给其他函数,也可以从其他函数返回。本文将详细…...

JVM学习指南(9)-JVM运行时数据区
JVM学习指南(9)-JVM运行时数据区 引言 Java虚拟机(JVM)是Java程序运行的核心,它为Java程序提供了一个与平台无关的执行环境。JVM的重要性不仅在于它实现了Java的跨平台特性,还在于它对程序执行过程中内存的管理。JVM运行时数据区是程序执行过程中存储数据的关键区域,理解…...

2025/1/4期末复习 密码学 按老师指点大纲复习
我们都要坚信,道路越是曲折,前途越是光明。 --------------------------------------------------------------------------------------------------------------------------------- 现代密码学 第五版 杨波 第一章 引言 1.1三大主动攻击 1.中断…...

关于嵌入式系统的知识课堂(二)
成长路上不孤单😊😊😊😊😊😊 【14后😊///计算机爱好者😊///持续分享所学😊///如有需要欢迎收藏转发///😊】 今日分享关于嵌入式系统的知识课堂(…...

基于ETAS工具的AutoConnect实现方案
文章目录 前言基于ISOLAR工具实现AutoConnect基于脚本实现AutoConnect总结前言 Autosar软件架构设计中,Connect通常来自于Composition之间(Assembly connectors),Component之间(Assembly connectors),Component与Composition之间(Delegation connectors),还有一种Pa…...

BGP基础配置实验
一、实验拓补 二、实验要求及分析 实验要求: 1,R1为AS 100区域;R2、R3、R4为AS 200区域且属于OSPF协议;R5为AS 300区域; 2,每个设备上都有环回,且通过环回可以使设备互通; 实验分…...

基于单片机的人体健康指标采集系统设计
1.系统的功能及方案设计 根据系统设计要求,人体健康指标采集系统的系统结构框图如图2.1所示。系统以单片机作为主控核心,协调控制各个模块进行工作。在传感器检测模块中包括MAX30102心率血氧检测模块、体温检测模块、液晶显示模块。系统以无创的形式实现…...

Go语言性能优化-字符串格式化优化
在 Go 语言中,格式化字符串(例如使用 fmt.Sprintf、fmt.Printf 等函数)确实可能对性能产生影响,尤其是当频繁执行格式化操作时。格式化字符串涉及对格式符的解析和数据类型的转换,这会增加额外的开销。为了减少格式化字符串带来的性能影响,可以采取以下一些优化策略: 1…...

UE5失真材质
渐变材质函数:RadialGradientExponential(指数径向渐变) 函数使用 UV 通道 0 来产生径向渐变,同时允许用户调整半径和中心点偏移。 用于控制渐变所在的位置及其涵盖 0-1 空间的程度。 基于 0-1 的渐变中心位置偏移。 源自中心的径…...

SAP 01-初识AMDP(ABAP-Managed Database Procedure)
1. 什么是AMDP(ABAP-Managed Database Procedure) 1.)AMDP - ABAP管理数据库程序,是一种程序,我们可以使用SQLSCRIPT在AMDP内部编写代码,SQLSCRIPT是一种与SQL脚本相同的数据库语言,这种语言易于理解和编码。 将AM…...

关于视频审核,内容风控在“控”什么?
随着互联网用户每周上网时长的增加,内容偏好逐渐向视频形式转移,视频内容成为了企业竞争的新战场。然而,视频内容审核和风险控制成为了企业面临的重大挑战。那么在视频审核中,内容风控到底在“控”什么呢? 视频内容风…...

5G NTN(七) 高层(1)
说明:本专题主要基于3GPP协议38.821 目录 1. Idle态移动性增强 1.1 TA问题 1.1.1 TA的大小 1.1.2 针对NTN LEO的移动TA,场景C2和D2 1.1.3 针对NTN LEO的固定TA,场景C2和D2 1.1.3.1 方法1:当UE位置信息无法获取的时候 1.1.…...

专家混合(MoE)大语言模型:免费的嵌入模型新宠
专家混合(MoE)大语言模型:免费的嵌入模型新宠 今天,我们深入探讨一种备受瞩目的架构——专家混合(Mixture-of-Experts,MoE)大语言模型,它在嵌入模型领域展现出了独特的魅力。 一、M…...

《柴油遗产-无耻时代》V98375官方版
靠近你所在赛道上的另一名玩家进行攻击或防守,跳到另一条赛道上进行恢复,或闪到对手背后打他个措手不及。与队友合作,充分利用每个角色的独特玩法来控制战斗走向! 《柴油遗产-无耻时代》官方版 https://pan.xunlei.com/s/VODW7xDX…...

科技云报到:洞见2025年科技潮流,技术大融合开启“智算时代”
科技云报到原创。 随着2024年逐渐接近尾声,人们不禁开始展望即将到来的2025年。这一年,被众多科技界人士视为开启新纪元的关键节点。站在新的起点上,我们将亲眼目睹未来科技如何改变我们的世界。从人工智能到量子计算,从基因编辑…...

【openwrt】OpenWrt 路由器的 802.1X 动态 VLAN
参考链接 [OpenWrt Wiki] Wi-Fi /etc/config/wirelesshttps://openwrt.org/docs/guide-user/network/wifi/basic#wpa_enterprise_access_point 介绍 基于802.1X 无线网络身份验证...

[coredump] 生成管理
在 Linux 系统中,core dump 文件的生成路径和文件名可以通过几个方面来控制: 系统默认路径: 默认情况下,core dump 文件通常生成在程序的工作目录,即程序运行时的当前目录。文件名通常为 core,或者在某些系…...

CSS——5. 外部样式
<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>方法3:外部样式</title><link rel"stylesheet" href"a.css" /><link rel"stylesheet" href"b.css"/&g…...

检查字符是否相同
给你一个字符串 s ,如果 s 是一个 好 字符串,请你返回 true ,否则请返回 false 。 如果 s 中出现过的 所有 字符的出现次数 相同 ,那么我们称字符串 s 是 好 字符串。 输入:s "abacbc" 输出:t…...

casaos安装最新版homeassistant-arm
进入cosOS界面点自定义安装 Docker镜像:homeassistant/armv7-homeassistant Tag:2024.12.2 标题:Home Assistant 图片路径:https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStoremain/Apps/HomeAssistant/icon.png Web UI:http&…...

openwrt host方式编译ffmpeg尝试及问题分析
openwrt host方式编译ffmpeg尝试及问题分析 configure错误分析编译错误一: ERROR: gnutls not found using pkg-config编译错误2: ERROR: libdrm not found using pkg-config编译错误3: ERROR: libmp3lame >= 3.98.3 not found编译错误4: ERROR: x264 not found using pkg…...

【three.js】搭建环境
一、安装Node.js和npm 下载与安装: 访问Node.js官方网站(nodejs.org),根据你的操作系统下载并安装最新稳定版(LTS版本)的Node.js。安装过程中,npm(Node包管理器)会随No…...

SQLite AND/OR 运算符
SQLite AND/OR 运算符 SQLite 的 AND 和 OR 运算符用于基于一个以上的条件来过滤记录。这些运算符在 WHERE 子句中与 SELECT、UPDATE 和 DELETE 语句一起使用。理解这些运算符的工作方式对于有效地查询数据库至关重要。 AND 运算符 AND 运算符允许我们在 WHERE 子句中指定多…...

《普通逻辑》学习记录——命题的判定与自然推理
目录 一、真值 1.1、真值联结词 1.2、真值联结词与逻辑联结词的区别 1.3、真值形式 1.3.1、真值符号的优先级和结合性规则 1.4、真值规则 1.4.1、条件式(蕴含式) P → Q 的真值规则 1.4.2、双条件式(等值式) P ↔ Q 的真值规则 1.…...

道可云人工智能元宇宙每日资讯|崂山区政务服务虚拟大厅启用
道可云元宇宙每日简报(2024年12月31日)讯,今日元宇宙新鲜事有: 崂山区政务服务虚拟大厅启用 近日,崂山区政务服务“虚拟大厅”在青岛正式上线,成为该市首个采用虚拟现实、人工智能、大数据及3D虚拟数字人…...

高并发写利器-组提交,我的Spring组件实战
高并发写优化理论 对于高并发的读QPS优化手段较多,最经济简单的方式是上缓存。但是对于高并发写TPS该如何提升?业界常用的有分库分表、异步写入等技术手段。但是分库分表对于业务的改造十分巨大,涉及迁移数据的麻烦工作,不会作为…...