编程自学指南:java程序设计开发,Java 内部类与枚举,内部类,枚举

编程自学指南:java程序设计开发,Java 内部类与枚举

(适用:Java 基础已掌握,首次接触内部类 / 枚举的学员)

一、学习目标

  1. 理解内部类的 4 种类型及适用场景
  2. 掌握枚举的定义与核心用法
  3. 能通过内部类 / 枚举优化代码结构
  4. 避免初学者常见误区(如内存泄漏、枚举滥用)

二、第一部分:内部类

1. 为什么需要内部类?(案例引入)

场景:设计一个 "手机" 类,包含 "电池" 类,电池仅属于手机内部使用

class Phone {
    private String brand;
    // 电池类作为内部成员
    class Battery { 
        private int capacity;
        void showInfo() {
            System.out.println(brand + "电池容量:" + capacity); // 直接访问外部类私有属性
        }
    }
    public static void main(String[] args) {
        Phone phone = new Phone("小米");
        Phone.Battery battery = phone.new Battery(); // 成员内部类创建方式
        battery.capacity = 4500;
        battery.showInfo(); // 输出:小米电池容量:4500
    }
    public Phone(String brand) { this.brand = brand; }
}

结论:内部类天然可以访问外部类私有成员,适合 "亲密类" 关系

2. 成员内部类(重点)

  • 特点:依赖外部类实例,不能定义静态成员
  • 内存关系:每个成员内部类对象隐含持有外部类引用(外部类名.this
  • 案例:员工 - 工资条关系
class Employee {
    private String name;
    class SalarySlip { // 成员内部类
        private double salary;
        void print() {
            System.out.println(name + "的工资:" + salary);
        }
    }
    public void createSlip(double salary) {
        SalarySlip slip = new SalarySlip(); // 直接创建
        slip.salary = salary;
        slip.print();
    }
    public Employee(String name) { this.name = name; }
}
// 使用:
new Employee("张三").createSlip(10000); // 输出:张三的工资:10000

3. 静态内部类(对比成员类)

  • 特点:不依赖外部类实例,可定义静态成员
  • 适用场景:工具类、辅助类(如 HashMap 的 Node 内部类)
  • 案例:用户 - 地址管理(地址可独立存在)
class User {
    private String username;
    static class Address { // 静态内部类
        private String city;
        public Address(String city) { this.city = city; }
    }
    public static void main(String[] args) {
        User.Address addr = new User.Address("北京"); // 无需User实例
    }
}

4. 局部内部类(方法内的类)

  • 特点:仅在方法内可见,可访问方法内的 final 变量(JDK8 + 隐含 final)
  • 案例:抽奖算法(类仅在抽奖时使用)
class Lottery {
    public void draw(String[] participants) {
        class Winner { // 局部内部类
            String name;
            void announce() {
                System.out.println("中奖者:" + name);
            }
        }
        // 模拟中奖
        int index = new Random().nextInt(participants.length);
        Winner winner = new Winner();
        winner.name = participants[index];
        winner.announce();
    }
}

5. 匿名内部类(重点难点)

  • 本质:没有名字的局部内部类,直接继承 / 实现抽象类 / 接口
  • 案例 1:按钮点击事件(GUI 编程常见)
import javax.swing.*;
import java.awt.event.*;

public class GUIExample {
    public static void main(String[] args) {
        JButton btn = new JButton("点击我");
        // 匿名内部类实现ActionListener
        btn.addActionListener(new ActionListener() { 
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("按钮被点击!");
            }
        });
        // ... 窗口显示代码
    }
}
  • 案例 2:简化线程创建
new Thread(() -> { // 匿名内部类(Lambda简化版)
    System.out.println("新线程运行中");
}).start();

6. 内部类对比表(总结)

类型是否依赖外部实例作用域常见用途
成员内部类外部类成员亲密关联类
静态内部类外部类静态范围工具类、独立组件
局部内部类方法 / 代码块内临时功能封装
匿名内部类表达式内事件处理、回调函数
课堂练习

题目:设计一个Car类,包含Engine成员内部类(显示转速),Carstart()方法启动引擎。

三、第二部分:枚举

1. 从常量到枚举(痛点引入)

传统常量写法问题

public static final int SEASON_SPRING = 1;
public static final int SEASON_SUMMER = 2;
// 问题1:类型不安全(可传入任意int)
// 问题2:无扩展性(新增季节需改代码)

枚举解决方案

enum Season { 
    SPRING, SUMMER, AUTUMN, WINTER; // 常量实例
    // 自定义方法
    public String getDesc() {
        switch(this) {
            case SPRING: return "春暖花开";
            // ... 其他季节
        }
    }
}
// 使用
Season s = Season.SPRING;
System.out.println(s.getDesc()); // 输出:春暖花开

2. 枚举基础语法

  • 定义enum 枚举名 { 常量1, 常量2, ...; }
  • 特性
    • 所有枚举类默认继承java.lang.Enum
    • 常量默认是public static final
    • 构造方法必须私有(隐式或显式)
  • 案例:星期枚举(含构造方法)
enum Weekday {
    MONDAY("周一"), TUESDAY("周二"); // 调用构造方法
    private String chineseName;
    // 私有构造
    Weekday(String chineseName) { this.chineseName = chineseName; }
    public String getChineseName() { return chineseName; }
}
// 遍历所有常量
for(Weekday day : Weekday.values()) {
    System.out.println(day + ":" + day.getChineseName());
}

3. 枚举高级用法

  • 实现接口
interface Behavior {
    void action();
}
enum Animal implements Behavior {
    DOG { 
        @Override public void action() { System.out.println("汪汪叫"); }
    },
    CAT { 
        @Override public void action() { System.out.println("喵喵叫"); }
    };
}
// 使用
Animal.DOG.action(); // 输出:汪汪叫
  • switch 增强(JDK12 + 模式匹配):
void handle(Season season) {
    switch(season) {
        case SPRING, AUTUMN -> System.out.println("舒适季节");
        case SUMMER -> System.out.println("炎热");
        case WINTER -> System.out.println("寒冷");
    }
}

4. 枚举 vs 常量接口(面试高频)

对比项枚举常量接口(public static final)
类型安全是(编译期检查)否(可传入任意 int)
扩展性好(新增常量不影响已有逻辑)差(需修改所有使用处的 switch)
内存占用小(全局唯一实例)无特殊优化
常用场景状态机、有限选项集合少量固定数值(如 HTTP 状态码)
课堂练习

题目:设计订单状态枚举(WAIT_PAY, PAID, DELIVERED),每个状态包含中文描述和处理方法(如 PAID 状态可发货)。

四、初学者常见误区

  1. 内部类内存泄漏:成员内部类持有外部类引用,若外部类是 Activity(Android),可能导致内存泄漏

    class Outer {
        private byte[] bigData = new byte[1024*1024]; // 大对象
        class Inner { }
        void leak() {
            new Inner(); // 即使Outer不再使用,Inner仍持有Outer引用
        }
    }
    

    解决方案:静态内部类 + 弱引用,或及时置空外部类引用

  2. 枚举构造方法 public:枚举构造方法必须私有,否则编译报错

  3. 匿名内部类重写方法:必须实现抽象类 / 接口的所有抽象方法

  4. 枚举常量命名:必须全大写(规范),如STATUS_SUCCESS而非statusSuccess

五、课程总结

知识点核心价值典型案例
成员内部类封装亲密关系类,访问外部类私有成员手机 - 电池、员工 - 工资条
匿名内部类简化回调 / 事件处理代码按钮点击、线程启动
枚举类型安全的常量集合,替代 int 常量季节、订单状态、星期

口诀
内部类,类中类,成员局部静态匿;
枚举常量强类型,构造私有方法齐;
场景记牢别滥用,代码整洁又安全!

六、课后作业(必做 + 选做)

  1. 必做:用内部类实现一个Person类,包含Heart成员内部类(模拟心跳),Personrun()方法时心跳加速。
  2. 必做:用枚举实现一个Color枚举,包含 RGB 值(如 RED (255,0,0))和获取十六进制字符串的方法。
  3. 选做:用匿名内部类优化 Java 集合的Comparator(如Collections.sort(list, new Comparator<>(){...}))。

学习说明:所有案例可直接复制到 IDEA 运行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zl515035644

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值