Z
ZHANK
面向对象基础

内部类与枚举

学习成员内部类、静态内部类、匿名类、enum 枚举

内部类与枚举

Java 允许在一个类里面再定义一个类——这就是内部类。它有 4 种形式,各自适用不同场景。

学完本章你将: 区分 4 种内部类的用途、匿名类的实战、enum 枚举。


四种内部类概览

类型定义位置能访问外部成员常用场景
成员内部类类里面紧密关联的辅助类
静态内部类类里面 + static独立于外部实例的辅助类
局部类方法里面方法内临时封装逻辑
匿名类new 后面直接写一次性接口实现(Lambda 简化了它)

成员内部类 —— 访问外部类的一切

编译后会产生 Outer$Inner.class 文件。内部类对象持有对外部类对象的隐式引用。

java
public class Outer {
    private String name = "Outer";

    public class Inner {
        public void print() {
            System.out.println(name); // 直接访问外部类的 private 成员
        }
    }
}

Outer outer = new Outer();
Outer.Inner inner = outer.new Inner(); // 必须先有外部对象
inner.print(); // "Outer"

匿名内部类 —— 一次性实现

不需要单独定义类名,直接 new 接口/父类 { 实现 }。它是 Lambda 出现前的主要回调方式。

java
// 传统匿名类
Runnable task = new Runnable() {
    @Override
    public void run() {
        System.out.println("匿名类执行");
    }
};
new Thread(task).start();

// Lambda 简化后(等价)
new Thread(() -> System.out.println("Lambda 执行")).start();

// 匿名类还能用双括号初始化集合
List<String> list = new ArrayList<>() {{
    add("A"); add("B"); add("C");
}}; // ⚠️ 这实际创建了 ArrayList 的子类,不是普通 ArrayList

枚举 —— 有限的常量集合

当变量只能取几个固定值(星期、季节、状态),用 enum 比 int 常量更安全——编译器会检查是否传了非法值。

java
public enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

Day today = Day.WEDNESDAY;
// Day x = Day.HELLO; // ❌ 编译错误,没有这个值

// 枚举可以带属性和方法
public enum Planet {
    MERCURY(3.303e+23, 2.4397e6),
    EARTH(5.976e+24, 6.378e6);

    private final double mass;
    private final double radius;

    Planet(double mass, double radius) { this.mass = mass; this.radius = radius; }
    public double surfaceGravity() { return 6.673E-11 * mass / (radius * radius); }
}

System.out.println(Planet.EARTH.surfaceGravity());

💡 enum vs 常量类: enum 天生不可变、自带 values() 遍历、switch 友好。用 public static final int 表示状态则是旧式写法,容易传错值。

public double surfaceGravity() {
    return 6.67300E-11 * mass / (radius * radius);
}

}

System.out.println(Planet.EARTH.surfaceGravity());