日期:2026-07-27
项目:c260727
作者:WanJL
Java 中的内部类分为三大类:
| 类型 | 说明 |
|---|---|
| 成员内部类 | 定义在类中方法外的类,分为普通成员内部类和静态成员内部类 |
| 局部内部类 | 定义在方法体或代码块中的类 |
| 匿名内部类 | 没有名字的内部类,定义后直接使用 |
📄 来源:
Demo01.java
匿名内部类,顾名思义,就是这个类没有名字,是匿名的,一般就是定义之后,直接使用。
存在一个 类 或 接口,这里的类可以是普通类,也可以是抽象类。
// 基于普通父类/抽象父类
new 类名() {
// 重写类的方法
};
// 基于接口
new 接口名() {
// 重写接口的方法
};
📄 来源:
Demo01.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
Tableware tableware = new Tableware() {
@Override
public void openTableware() {
System.out.println("打开一次性筷子");
}
@Override
public void useTableware() {
System.out.println("使用一次性筷子");
}
};
person.eat(tableware);
📄 来源:
Test02.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
优势:如果某个实现类只想在当前场景使用一次,不想被其他人复用,使用匿名内部类可以避免创建独立的实现类文件,使代码更紧凑。
在匿名内部类中定义特有的方法,通过匿名对象直接调用(不经过多态)。
new Compute() {
@Override
public int add(int a, int b) {
return a + b;
}
public void method() {
System.out.println("匿名内部类特有的方法");
}
}.method(); // 直接调用匿名内部类的特有方法
📄 来源:
Demo01.java(注释部分)
注意:这种方式因为没有变量名,所以只能调用一次。
定义 USB 设备的统一规范。
public interface Usb {
void startUsb();
void closeUsb();
}
📄 来源:
Usb.java
定义餐具的使用规范(开餐、用餐)。
public interface Tableware {
void openTableware();
void useTableware();
}
📄 来源:
Tableware.java
public class 筷子 implements Tableware {
@Override
public void openTableware() { }
@Override
public void useTableware() { }
}
📄 来源:
筷子.java
public abstract class Compute {
public abstract int add(int a, int b);
}
📄 来源:
Compute.java
public interface Sort {
Student compare(Student s1, Student s2);
}
📄 来源:
Sort.java
public class NoteBook {
/**
* 使用USB设备
* @param usb 接口,实际参数要传入的是实现类对象/匿名内部类对象
*/
public void useUSB(Usb usb) {
usb.startUsb();
usb.closeUsb();
}
}
📄 来源:
NoteBook.java
public class Person {
/**
* 吃饭
* @param tableware 吃饭使用的餐具
*/
public void eat(Tableware tableware) {
tableware.openTableware();
tableware.useTableware();
System.out.println("开始干饭......");
}
}
📄 来源:
Person.java
public class Student {
private String id;
private String name;
private Integer age;
// 构造方法、getter/setter...
}
📄 来源:
Student.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临时设备"); }
});
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
设计意图:如果不希望接口实现类被其他人复用,使用匿名内部类可以限制其使用范围。
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(){...}) |
核心优势:
📄 对应练习文件:
课堂练习题/20260727-内部类练习.md
本次课堂练习涵盖了以下知识点:
static 修饰,创建格式为 外部类.内部类 变量 = new 外部类.内部类()