当前位置: 首页 > news >正文

java第八篇:Java内部类全解析

前言

一、什么是内部类

What:什么是内部类

Why:内部类的好处

二 、成员内部类

what:什么是成员内部类

Why:成员内部类的好处:

how:如何使用成员内部类

how:成员内部类如何创建对象

三、静态内部类:

What:什么是静态内部类

Why:为什么要用静态内部类

how:如何使用静态内部类

how:静态内部类如何创建对象

成员内部类和静态内部类对比:

四、局部内部类:

What:什么是局部内部类

Why:为什么要用局部内部类

How:如何使用局部内部类

how:局部内部类如何创建对象

五、匿名内部类(!!!):

What:什么是匿名内部类

Why:为什么要用匿名内部类

How:如何使用匿名内部类

匿名类的类名

匿名内部类的两种一般写法:

六、匿名内部类的lambada简化形式

适用条件:

简化规则:

总结



前言

今天我们学习内部类的相关内容。包括成员内部类、静态内部类、局部内部类、匿名内部类。我们将重点主要放在匿名内部类,并学习他的lambada简化的表达方式。


一、什么是内部类

What:什么是内部类

内部类(Inner Class)是指一个类定义在另一个类内部的类。内部类可以访问外部类的所有成员,包括私有成员,这使得它成为封装相关功能的强大工具。

在Java中,内部类主要分为四种类型:

Why:内部类的好处

  1. 增强封装性:将只在特定上下文中使用的类隐藏在外部类内部,减少命名冲突,提高代码的模块化程度。
  2. 访问外部类私有成员:内部类可以直接访问外部类的所有成员,包括私有字段和方法,这在实现某些设计模式时非常有用。
  3. 逻辑分组:当一个类只对另一个类有意义时,将其作为内部类可以使代码结构更加清晰,符合"高内聚"的设计原则。
  4. 实现多继承效果:Java不支持多继承,但内部类可以继承一个类,同时外部类继承另一个类,从而在某种程度上模拟多继承。
  5. 事件驱动编程:在GUI编程和回调机制中,匿名内部类提供了简洁的事件处理方式。

二 、成员内部类

what:什么是成员内部类

成员内部类是定义在一个外部类的成员位置的的类,没有 static 修饰。

Why:成员内部类的好处

how:如何使用成员内部类

//外部一个class类 class Outer { private String a = "hello"; //内部嵌套一个class类 class Inner { // 成员内部类 public void sys() { System.out.println(a); // 直接使用成员名访问 System.out.println(Outer.this.a);// 使用外部类的this引用访问,两个等效 } } }

当变量名相同的时候如何输出?

//当变量名相同的时候如何输出 class People { private int heartBeat = 100; public class Heart { private int heartBeat = 80; public void show() { int heartBeat = 200; System.out.println(heartBeat);// 200 System.out.println(this.heartBeat);// 80 System.out.println(People.this.heartBeat);// 100 } }

how:成员内部类如何创建对象

外部类名.内部类名.变量名=new 外部类名().new 内部类名();

class People { private int heartBeat = 100; public class Heart { private int heartBeat = 80; public void show() { int heartBeat = 200; System.out.println(heartBeat);// 200 System.out.println(this.heartBeat);// 80 System.out.println(People.this.heartBeat);// 100 } } public static void main(String[] args) { People.Heart heart = new People().new Heart(); heart.show(); }

输出结果:

三、静态内部类:

What:什么是静态内部类

静态内部类是使用static关键字修饰的类,定义在另一个类的内部。它与外部类的实例无关,可以直接通过外部类名访问,而无需创建外部类的对象。

Why:为什么要用静态内部类

内存效率高:不会意外持有外部类引用,避免内存泄漏,特别适合工具类、辅助类

独立性强,解耦合:静态内部类可以独立于外部类使用,降低代码耦合度

命名空间管理:逻辑分组常量和工具类,避免命名冲突,提高代码可读性

设计模式支持:Builder设计模式等需要独立内部类的场景的最佳选择

how:如何使用静态内部类

public class Outer { private static String staticField = "静态"; private String instanceField = "实例"; // 静态内部类不能访问 // 静态内部类定义 public static class Inner { private String innerField = "内部字段"; private static String staticInnerField = "静态内部字段"; // 可以有静态成员 public void show() { System.out.println(staticField); // 可以访问外部类静态字段 // System.out.println(instanceField); // 编译错误!不能访问实例字段 System.out.println(innerField); System.out.println(staticInnerField); } } }

how:静态内部类如何创建对象

外部类名.内部类名 对象名 = new 外部类名.内部类名();

public static void main(String[] args) { // 创建对象:外部类名.内部类名 对象名 = new 外部类名.内部类名(); outer.Inner inner = new outer.Inner(); inner.show(); }

成员内部类和静态内部类对比:

特性静态内部类成员内部类
定义static class Innerclass Inner
创建对象new Outer.Inner()new outer.new Inner()
持有外部引用不持有持有
访问外部实例成员不能
访问外部静态成员
定义静态成员不能(除常量)
内存开销大(持有引用)

四、局部内部类:

What:什么是局部内部类

局部内部类是定义在方法或代码块内部的类,它的作用域仅限于该方法或代码块。局部内部类可以访问外部类的所有成员,也可以访问方法中的finaleffectively final(实际上不可变的)局部变量,但它不能有访问修饰符(public、private等),也不能定义静态成员(除了常量)。

Why:为什么要用局部内部类

How:如何使用局部内部类

局部内部类是定义在方法内部的内部类,只能在该方法内部使用,它的定义方式如下

class OuterClass { public OuterClass() { class LocalInnerClassA { // 在构造器中定义局部内部类 } } { class LocalInnerClassB { // 在实例代码块中定义局部内部类 } } static { class LocalInnerClassC { // 在静态代码块中定义局部内部类 } } public void fun() { int localVar; class LocalInnerClassD { // 在成员函数中定义局部内部类 } } }

例如:

public class Outer { private int data; public void method() { class Inner { public void print() { System.out.println(data); } } Inner inner = new Inner(); inner.print(); } }

how:局部内部类如何创建对象

  1. 创建对象:在定义类之后,但在作用域结束之前,使用new关键字实例化该类的对象。
  2. 使用对象:创建对象后,可以调用其方法或访问其属性,但仅限于当前作用域内。
public class Calculator { public void calculate(int a, int b) { final int multiplier = 10; // 定义局部内部类 class Operation { public int add() { return a + b; } public int multiply() { return (a + b) * multiplier; } } // 必须在定义它的方法内创建对象 Operation op = new Operation(); System.out.println("Sum: " + op.add()); System.out.println("Multiplied: " + op.multiply()); // 无法在方法外创建:Operation op2 = new Operation(); // 编译错误! } } // 使用 Calculator calc = new Calculator(); calc.calculate(5, 3);

五、匿名内部类(!!!):

What:什么是匿名内部类

匿名内部类是没有名字的内部类,只能一次性使用,它通常用于实现接口和抽象类的方法

匿名内部类本质上是一个局部内部类的简化形式,它只能在声明时创建一个实例,可以直接访问外部类的所有成员以及方法中finaleffectively final的局部变量,但不能定义构造方法、静态成员或任何静态代码块。

Why:为什么要用匿名内部类

更方便的创建一个子类对象

How:如何使用匿名内部类

先定义一个类,然后内部类进行new类或接口(参数值){一般是外部类的方法重写}

public abstract class Animal { public abstract void cry(); } //匿名内部类,直接方法重写,本质是子类 public class test { public static void main(String[] args){ Animal animal=new Animal() { @Override public void cry() { System.out.println("小猫喵喵"); } }; animal.cry(); } }

匿名类的类名

匿名内部类只是没有显式的类名,但实际上有隐式的名字,一般命名规则是外部类名$1,这里的 1 是指在这个外部类内定义的第一个匿名内部类,我们可以通过 getClass() 方法获取类名:

public class AnonymousClassNameDemo { public static void main(String[] args) { // 创建匿名内部类实例 Runnable runnable = new Runnable() { @Override public void run() { System.out.println("Running..."); } }; // 获取并打印类名 String className = runnable.getClass().getName(); System.out.println("匿名内部类的类名: " + className); }

匿名内部类的一般写法:

平时:Swim a=new Swim(){

匿名内部类:swim(new Swim(){

package itheima.innerclass2; public class test2 { public static void main(String[] args){ //第一种--正常创建对象方式 Swim a=new Swim(){ @Override public void swimming() { System.out.println("学生游泳很快"); } }; swim(a); //第二种--匿名内部类方式(去掉对象名,直接new对象) swim(new Swim(){ public void swimming() { System.out.println("老师游泳很慢"); } } );} public static void swim(Swim s){ System.out.println("开始~~~~~~~~"); s.swimming(); System.out.println("结束~~~~~~~~"); } interface Swim{ void swimming(); } }

六、匿名内部类的lambada简化形式

适用条件:

仅适用于函数式接口(有且仅有一个抽象方法的接口)

简化规则:

1. 当接口只有一个抽象方法时,可以省略接口名和方法名

2. 参数类型可以省略(编译器自动推断)

3. 单行代码可以省略大括号和return关键字

4. 无参数时保留空括号,单参数时可以省略括号

如何写:(被重写方法的形参列表)->被重写的代码,删掉new后面到方法前面的内容,只保留参数

//两者效果等同 swim(new Swim(){ public void swimming() { System.out.println("老师游泳很慢"); } } );} swim(() -> System.out.println("老师游泳很慢")

总结

内部类的出现进一步扩展了类的功能,使得类的功能更加丰富,内部类的种类繁多,但我们对于这一块只要求掌握就可以了,不必做过深的研究。

Tips:开发中并不是主动去写匿名内部类,而是函数方法需要我们写才写,是被动地写

今天我们学习了内部类的相关知识。本次分享到此结束,感谢大家的观看与支持!如果本内容对您有帮助,欢迎点赞、收藏,您的支持将是我持续创作的最大动力,谢谢!

http://www.cnnetsun.cn/news/1733475.html

相关文章:

  • 如何进行网站 SEO 优化以提高转化率
  • OpenClaw可视化监控:千问3.5-9B任务实时看板搭建
  • Stable Yogi Leather-Dress-Collection企业实操:Z世代营销素材24小时快速产出
  • ShardingSphere分片算法配置和雪花算法的高可用变种实现细节
  • SEO宣传推广一次性收费多少钱_SEO优化推广按月收费的价格是多少
  • OpenClaw个性化训练:为Phi-3-mini-128k-instruct添加专属知识库
  • AI股票分析效果优化:Matlab数值计算加速
  • 简单通俗的解释:API 就是“帮手”接口
  • 【RAG】【vector_stores007】异步索引创建示例
  • Pi0具身智能v1功能体验:自定义任务描述影响动作生成实测
  • Qwen3-TTS低延迟实战:集成WebRTC实现实时语音通话,无缝对话
  • OpenClaw技能市场巡礼:10款SecGPT-14B增强安全工具推荐
  • AIGlasses_for_navigation与Dify平台集成:快速构建导航应用工作流
  • ComfyUI Qwen镜像部署与使用:小白也能轻松玩转AI图像生成
  • SDMatte多模态应用初探:结合CLIP实现以文搜图与智能裁剪
  • LFM2.5-1.2B-Thinking-GGUF算法解析应用:动态图解经典排序与搜索算法
  • Android 11 Settings功能裁剪实战:从PreferenceController到XML配置的完整流程解析
  • GCC-Net实战解析:如何通过门控跨域协作提升水下目标检测精度
  • Phi-4-mini-reasoning辅助C++项目代码审查:内存管理与性能瓶颈推理
  • STM8硬件IIC驱动BNO055避坑指南:从模拟IIC失败到一次成功的完整流程
  • 跨平台文件同步:OpenClaw+Qwen3-4B自动归类NAS中的文档
  • Qwen3.5-4B模型软件测试用例生成实战:提升测试覆盖率
  • 视频剪辑新助手:用SAM 3智能跟踪分割视频中的运动物体
  • UNIT-00:Berserk Interface 深入解析Python核心机制:从语法糖到内存管理
  • SDMatte极限测试:应对低光照、高噪声、强遮挡的挑战
  • Rembg 图片去背景工具 懒人整合包 优化可视化界面和添加模型 cpu可用 gpu可用
  • 零基础玩转OpenClaw:Qwen3-32B镜像云端体验与技能市场探索
  • Ubuntu服务器运维指南:霜儿-汉服-造相Z-Turbo模型服务的监控与高可用保障
  • 三天踩坑实录:用Pyinstaller打包PaddleOCR+PyQt5桌面应用,我总结的这份spec文件配置清单请收好
  • 低成本GPU方案|SeqGPT-560M开源镜像部署:单卡T4即可跑满1.1GB模型