枚举与内部类
本课学习枚举和内部类,了解Java中的特殊类。
枚举
枚举用于定义一组固定的常量。
定义枚举
JAVA
public enum Season {
SPRING, SUMMER, AUTUMN, WINTER
}
使用枚举
JAVA
public class EnumDemo {
public static void main(String[] args) {
Season season = Season.SPRING;
switch (season) {
case SPRING:
System.out.println("春天");
break;
case SUMMER:
System.out.println("夏天");
break;
case AUTUMN:
System.out.println("秋天");
break;
case WINTER:
System.out.println("冬天");
break;
}
}
}
枚举的属性和方法
JAVA
public enum Season {
SPRING("春天", 1),
SUMMER("夏天", 2),
AUTUMN("秋天", 3),
WINTER("冬天", 4);
private String name;
private int order;
// 构造方法
Season(String name, int order) {
this.name = name;
this.order = order;
}
// getter
public String getName() {
return name;
}
public int getOrder() {
return order;
}
}
枚举常用方法
| 方法 | 说明 | 示例 |
|---|---|---|
values() |
所有枚举值 | Season.values() |
valueOf() |
字符串转枚举 | Season.valueOf("SPRING") |
ordinal() |
枚举索引 | Season.SPRING.ordinal() → 0 |
name() |
枚举名称 | Season.SPRING.name() → "SPRING" |
示例:枚举方法
JAVA
public class EnumMethodDemo {
public static void main(String[] args) {
// 遍历所有枚举值
for (Season s : Season.values()) {
System.out.println(s.ordinal() + ": " + s.getName());
}
// 字符串转枚举
Season spring = Season.valueOf("SPRING");
System.out.println(spring.getName()); // 春天
// 比较枚举
System.out.println(Season.SPRING == Season.SPRING); // true
System.out.println(Season.SPRING.equals(Season.SPRING)); // true
}
}
示例:星期枚举
JAVA
public enum Weekday {
MONDAY("星期一", true),
TUESDAY("星期二", true),
WEDNESDAY("星期三", true),
THURSDAY("星期四", true),
FRIDAY("星期五", true),
SATURDAY("星期六", false),
SUNDAY("星期日", false);
private String chinese;
private boolean isWorkday;
Weekday(String chinese, boolean isWorkday) {
this.chinese = chinese;
this.isWorkday = isWorkday;
}
public String getChinese() {
return chinese;
}
public boolean isWorkday() {
return isWorkday;
}
}
public class WeekdayDemo {
public static void main(String[] args) {
for (Weekday day : Weekday.values()) {
String type = day.isWorkday() ? "工作日" : "周末";
System.out.println(day.getChinese() + " - " + type);
}
}
}
内部类
内部类是定义在另一个类内部的类。
成员内部类
JAVA
public class Outer {
private int x = 10;
// 成员内部类
public class Inner {
public void show() {
// 可以访问外部类的私有成员
System.out.println("x = " + x);
}
}
public void test() {
Inner inner = new Inner();
inner.show();
}
}
public class InnerClassDemo {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.show(); // x = 10
}
}
静态内部类
JAVA
public class Outer {
private static int x = 10;
private int y = 20;
// 静态内部类
public static class StaticInner {
public void show() {
// 只能访问外部类的静态成员
System.out.println("x = " + x);
// System.out.println("y = " + y); // 编译错误!
}
}
}
public class StaticInnerDemo {
public static void main(String[] args) {
// 不需要创建外部类对象
Outer.StaticInner inner = new Outer.StaticInner();
inner.show(); // x = 10
}
}
局部内部类
JAVA
public class Outer {
public void method() {
// 局部内部类:定义在方法中
class LocalInner {
public void show() {
System.out.println("局部内部类");
}
}
LocalInner inner = new LocalInner();
inner.show();
}
}
匿名内部类
JAVA
public interface Greeting {
void greet(String name);
}
public class AnonymousDemo {
public static void main(String[] args) {
// 匿名内部类
Greeting hello = new Greeting() {
@Override
public void greet(String name) {
System.out.println("Hello, " + name + "!");
}
};
hello.greet("Alice"); // Hello, Alice!
// Lambda简写(函数式接口)
Greeting hi = name -> System.out.println("Hi, " + name + "!");
hi.greet("Bob"); // Hi, Bob!
}
}
示例:匿名内部类实现事件处理
JAVA
public interface OnClickListener {
void onClick(String button);
}
public class Button {
private String text;
private OnClickListener listener;
public Button(String text) {
this.text = text;
}
public void setOnClickListener(OnClickListener listener) {
this.listener = listener;
}
public void click() {
if (listener != null) {
listener.onClick(text);
}
}
}
public class ButtonDemo {
public static void main(String[] args) {
Button btn = new Button("提交");
// 匿名内部类
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(String button) {
System.out.println(button + "被点击了");
}
});
btn.click(); // 提交被点击了
}
}
内部类对比
| 类型 | 位置 | 访问外部类 | 创建方式 |
|---|---|---|---|
| 成员内部类 | 类中 | 所有成员 | outer.new Inner() |
| 静态内部类 | 类中 | 静态成员 | new Outer.Inner() |
| 局部内部类 | 方法中 | 所有成员+局部final | 在方法中创建 |
| 匿名内部类 | 任意位置 | 同局部内部类 | new Interface(){} |
❓ 常见问题
Q 什么时候用枚举?
A 定义固定常量集合时,如季节、星期、状态等。
Q 什么时候用匿名内部类?
A 实现接口的简单逻辑,特别是事件回调。Java 8后推荐用Lambda。
Q 内部类有什么用?
A 实现回调机制、访问外部类私有成员、组织相关类。
📖 小节
- 枚举定义固定常量,可以有属性和方法
- 内部类分为:成员、静态、局部、匿名
- 匿名内部类可以简写为Lambda(函数式接口)
- 枚举常用方法:values、valueOf、ordinal
📝 作业
- 季节枚举: 定义Season枚举,包含季节名称和温度范围
- 状态机: 用枚举实现订单状态(待付款、已付款、已发货、已完成)
- 匿名内部类: 用匿名内部类实现Comparator排序
下一课
下一课我们将学习 异常处理,了解如何处理程序中的错误。



