20260727-笔记.md 8.2 KB

JavaSE 基础 — Day11 笔记

日期:2026-07-27
项目c260727
作者:WanJL


一、Java 内部类概述

1.1 内部类分类

Java 中的内部类分为三大类:

类型 说明
成员内部类 定义在类中方法外的类,分为普通成员内部类和静态成员内部类
局部内部类 定义在方法体或代码块中的类
匿名内部类 没有名字的内部类,定义后直接使用

📄 来源:Demo01.java


二、匿名内部类(核心)

2.1 什么是匿名内部类

匿名内部类,顾名思义,就是这个类没有名字,是匿名的,一般就是定义之后,直接使用。

2.2 使用前提

存在一个 接口,这里的类可以是普通类,也可以是抽象类。

2.3 语法格式

// 基于普通父类/抽象父类
new 类名() {
    // 重写类的方法
};

// 基于接口
new 接口名() {
    // 重写接口的方法
};

📄 来源:Demo01.java

2.4 本质

匿名内部类的本质是一个继承了某个类或实现了某个接口的 【子类的匿名对象】


2.5 使用方式一:多态接收(变量赋值)

将匿名内部类对象赋值给父类/接口类型的变量,通过多态调用方法。

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

2.6 使用方式二:作为方法参数传递(开发中最常用)

直接创建匿名内部类作为参数传入方法,无需预先定义实现类。

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 使用方式三:直接调用方法(匿名对象调用)

在匿名内部类中定义特有的方法,通过匿名对象直接调用(不经过多态)。

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 设备的统一规范。

public interface Usb {
    void startUsb();
    void closeUsb();
}

📄 来源:Usb.java

3.2 Tableware 接口

定义餐具的使用规范(开餐、用餐)。

public interface Tableware {
    void openTableware();
    void useTableware();
}

📄 来源:Tableware.java

3.3 筷子类(Tableware 接口的实现类)

public class 筷子 implements Tableware {
    @Override
    public void openTableware() { }

    @Override
    public void useTableware() { }
}

📄 来源:筷子.java

3.4 Compute 抽象类

public abstract class Compute {
    public abstract int add(int a, int b);
}

📄 来源:Compute.java

3.5 Sort 接口(学生比较排序)

public interface Sort {
    Student compare(Student s1, Student s2);
}

📄 来源:Sort.java


四、业务类设计

4.1 NoteBook — USB 设备管理器

public class NoteBook {
    /**
     * 使用USB设备
     * @param usb 接口,实际参数要传入的是实现类对象/匿名内部类对象
     */
    public void useUSB(Usb usb) {
        usb.startUsb();
        usb.closeUsb();
    }
}

📄 来源:NoteBook.java

4.2 Person — 吃饭场景

public class Person {
    /**
     * 吃饭
     * @param tableware 吃饭使用的餐具
     */
    public void eat(Tableware tableware) {
        tableware.openTableware();
        tableware.useTableware();
        System.out.println("开始干饭......");
    }
}

📄 来源:Person.java

4.3 Student — 学生实体类

public class Student {
    private String id;
    private String name;
    private Integer age;

    // 构造方法、getter/setter...
}

📄 来源:Student.java


五、匿名内部类综合案例

5.1 USB 设备接入案例

// 方式一:普通创建(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 餐具使用案例

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 学生比较排序案例

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 + 键盘 + 鼠标)、银行账户系统

八、拓展阅读