# JavaSE 基础 — Day11 笔记 > **日期**:2026-07-27 > **项目**:`c260727` > **作者**:WanJL --- ## 一、Java 内部类概述 ### 1.1 内部类分类 Java 中的内部类分为三大类: | 类型 | 说明 | |------|------| | **成员内部类** | 定义在类中方法外的类,分为普通成员内部类和静态成员内部类 | | **局部内部类** | 定义在方法体或代码块中的类 | | **匿名内部类** | 没有名字的内部类,定义后直接使用 | > 📄 来源:`Demo01.java` --- ## 二、匿名内部类(核心) ### 2.1 什么是匿名内部类 **匿名内部类**,顾名思义,就是这个类没有名字,是匿名的,一般就是定义之后,直接使用。 ### 2.2 使用前提 存在一个 **类** 或 **接口**,这里的类可以是普通类,也可以是抽象类。 ### 2.3 语法格式 ```java // 基于普通父类/抽象父类 new 类名() { // 重写类的方法 }; // 基于接口 new 接口名() { // 重写接口的方法 }; ``` > 📄 来源:`Demo01.java` ### 2.4 本质 匿名内部类的本质是一个继承了某个类或实现了某个接口的 **【子类的匿名对象】**。 --- ### 2.5 使用方式一:多态接收(变量赋值) 将匿名内部类对象赋值给父类/接口类型的变量,通过多态调用方法。 ```java Usb usb = new Usb() { @Override public void startUsb() { System.out.println("启动鼠标"); } @Override public void closeUsb() { System.out.println("关闭鼠标"); } }; usb.startUsb(); usb.closeUsb(); ``` > 📄 来源:`Demo01.java` ```java Tableware tableware = new Tableware() { @Override public void openTableware() { System.out.println("打开一次性筷子"); } @Override public void useTableware() { System.out.println("使用一次性筷子"); } }; person.eat(tableware); ``` > 📄 来源:`Test02.java` ### 2.6 使用方式二:作为方法参数传递(开发中最常用) 直接创建匿名内部类作为参数传入方法,无需预先定义实现类。 ```java NoteBook nb = new NoteBook(); nb.useUSB(new Usb() { @Override public void startUsb() { System.out.println("使用USB临时设备"); } @Override public void closeUsb() { System.out.println("关闭USB临时设备"); } }); ``` > 📄 来源:`Test01.java` **优势**:如果某个实现类只想在当前场景使用一次,不想被其他人复用,使用匿名内部类可以避免创建独立的实现类文件,使代码更紧凑。 ### 2.7 使用方式三:直接调用方法(匿名对象调用) 在匿名内部类中定义特有的方法,通过匿名对象直接调用(不经过多态)。 ```java new Compute() { @Override public int add(int a, int b) { return a + b; } public void method() { System.out.println("匿名内部类特有的方法"); } }.method(); // 直接调用匿名内部类的特有方法 ``` > 📄 来源:`Demo01.java`(注释部分) **注意**:这种方式因为没有变量名,所以只能调用一次。 --- ## 三、接口与抽象类定义 ### 3.1 Usb 接口 定义 USB 设备的统一规范。 ```java public interface Usb { void startUsb(); void closeUsb(); } ``` > 📄 来源:`Usb.java` ### 3.2 Tableware 接口 定义餐具的使用规范(开餐、用餐)。 ```java public interface Tableware { void openTableware(); void useTableware(); } ``` > 📄 来源:`Tableware.java` ### 3.3 筷子类(Tableware 接口的实现类) ```java public class 筷子 implements Tableware { @Override public void openTableware() { } @Override public void useTableware() { } } ``` > 📄 来源:`筷子.java` ### 3.4 Compute 抽象类 ```java public abstract class Compute { public abstract int add(int a, int b); } ``` > 📄 来源:`Compute.java` ### 3.5 Sort 接口(学生比较排序) ```java public interface Sort { Student compare(Student s1, Student s2); } ``` > 📄 来源:`Sort.java` --- ## 四、业务类设计 ### 4.1 NoteBook — USB 设备管理器 ```java public class NoteBook { /** * 使用USB设备 * @param usb 接口,实际参数要传入的是实现类对象/匿名内部类对象 */ public void useUSB(Usb usb) { usb.startUsb(); usb.closeUsb(); } } ``` > 📄 来源:`NoteBook.java` ### 4.2 Person — 吃饭场景 ```java public class Person { /** * 吃饭 * @param tableware 吃饭使用的餐具 */ public void eat(Tableware tableware) { tableware.openTableware(); tableware.useTableware(); System.out.println("开始干饭......"); } } ``` > 📄 来源:`Person.java` ### 4.3 Student — 学生实体类 ```java public class Student { private String id; private String name; private Integer age; // 构造方法、getter/setter... } ``` > 📄 来源:`Student.java` --- ## 五、匿名内部类综合案例 ### 5.1 USB 设备接入案例 ```java // 方式一:普通创建(Demo01) Usb usb = new Usb() { @Override public void startUsb() { System.out.println("启动鼠标"); } @Override public void closeUsb() { System.out.println("关闭鼠标"); } }; usb.startUsb(); usb.closeUsb(); // 方式二:作为参数传递(Test01)—— 开发中最常用 NoteBook nb = new NoteBook(); nb.useUSB(new Usb() { @Override public void startUsb() { System.out.println("使用USB临时设备"); } @Override public void closeUsb() { System.out.println("关闭USB临时设备"); } }); ``` ### 5.2 餐具使用案例 ```java Person person = new Person(); Tableware tableware = new Tableware() { @Override public void openTableware() { System.out.println("打开一次性筷子"); } @Override public void useTableware() { System.out.println("使用一次性筷子"); } }; person.eat(tableware); ``` > 📄 来源:`Test02.java` **设计意图**:如果不希望接口实现类被其他人复用,使用匿名内部类可以限制其使用范围。 ### 5.3 学生比较排序案例 ```java Student s1 = new Student("1001", "张三", 20); Student s2 = new Student("1002", "李四", 25); Sort sort = new Sort() { @Override public Student compare(Student s1, Student s2) { if (Integer.getInteger(s1.getId()) < Integer.getInteger(s2.getId())) return s1; else return s2; } }; Student max = sort.compare(s1, s2); System.out.println(max.getName()); ``` > 📄 来源:`Test03.java` **说明**:使用匿名内部类实现 `Sort` 接口的比较逻辑,根据学生 ID 比较大小,返回较小的学生对象。 --- ## 六、匿名内部类应用场景总结 | 场景 | 说明 | 示例 | |------|------|------| | 接口实现类仅使用一次 | 避免创建独立的接口实现类文件 | USB设备、一次性餐具 | | 临时逻辑处理 | 实现简单的比较、回调等逻辑 | 学生比较排序 | | 方法参数需要接口/抽象类对象 | 直接传递匿名内部类简化代码 | `nb.useUSB(new Usb(){...})` | **核心优势**: 1. 减少类文件数量,代码更紧凑 2. 适合一次性使用的实现逻辑 3. 可以直接访问外部类的成员(包括私有成员) 4. 在方法参数位置直接创建,代码可读性更强 --- ## 七、随堂练习要点 > 📄 对应练习文件:`课堂练习题/20260727-内部类练习.md` 本次课堂练习涵盖了以下知识点: 1. **成员内部类**:定义在类中,可以直接访问外部类的私有成员 2. **私有内部类**:采用私有内部类设计,对外隐藏实现细节 3. **静态成员内部类**:使用 `static` 修饰,创建格式为 `外部类.内部类 变量 = new 外部类.内部类()` 4. **局部内部类**:定义在方法体中,作用域仅限于当前方法 5. **三种内部类综合运用**:计算机外设管理(USB + 键盘 + 鼠标)、银行账户系统 --- ## 八、拓展阅读 - [Java 匿名内部类(Anonymous Inner Class)详解](https://docs.oracle.com/javase/tutorial/java/javaOO/anonymous.html) - 内部类与 Lambda 表达式的关系(后续课程会详细讲解) - 设计模式中的策略模式(Strategy Pattern)与匿名内部类的结合使用