Просмотр исходного кода

docs: 新增20260727内部类练习(成员内部类/私有内部类/静态内部类/局部内部类),更新README记录

WanJL 18 часов назад
Родитель
Сommit
56edf4c11c
2 измененных файлов с 502 добавлено и 0 удалено
  1. 1 0
      README.md
  2. 501 0
      课堂练习题/20260727-内部类练习.md

+ 1 - 0
README.md

@@ -62,4 +62,5 @@
 | 2026-07-22 | [继承练习](./课堂练习题/20260722-继承练习.md) | 继承概念与格式、多层继承、super() 调用父类构造方法、方法重写、is...a 关系判断、继承+构造方法+对象数组+排序+多态综合 |
 | 2026-07-23 | [抽象类与接口练习](./课堂练习题/20260723-抽象类与接口练习.md) | 抽象类定义与特点、抽象方法重写、抽象类计算周长与面积(Shape体系)、抽象类+对象数组+排序+多态综合、模板方法设计模式;接口入门(Playable播放器接口、Charger充电规范继承+实现、SmartPhone实现多接口) |
 | 2026-07-24 | [多态练习](./课堂练习题/20260724-多态练习.md) | 多态概念与三前提、多态成员访问特点(编译看左运行看右)、向上转型/向下转型、instanceof运算符、多态+对象数组+排序综合(员工绩效管理系统)、接口多态+Usb设备管理器 |
+| 2026-07-27 | [内部类练习](./课堂练习题/20260727-内部类练习.md) | 成员内部类、内部类直接访问外部类私有成员、私有内部类设计原则、静态成员内部类创建格式、局部内部类作用域与访问规则、三种内部类综合运用(计算机外设+银行账户系统) |
 

+ 501 - 0
课堂练习题/20260727-内部类练习.md

@@ -0,0 +1,501 @@
+# 2026-07-27 内部类(Inner Class)基础练习(课堂练习用)
+
+> **说明**:以下习题围绕今日授课核心内容——**内部类(Inner Class)** 展开,涵盖成员内部类、私有内部类的设计原则、静态成员内部类、局部内部类等知识点。
+>
+> 题目分为两部分:**随堂练习**(内部类基础,4 题)和 **进阶练习**(综合挑战,2 题)。
+
+---
+
+# 第一部分:随堂练习
+
+> 以下练习围绕内部类的基础概念和用法,由浅入深。
+
+---
+
+## 练习 1:内部类入门——汽车与发动机
+
+**难度**:⭐  
+**知识点**:内部类概念、成员内部类定义、内部类访问外部类成员
+
+**场景描述**:汽车(`Car`)包含发动机(`Engine`),发动机是汽车的内部组成部分,离开汽车无法独立存在。发动机有自己的行为(启动、熄火),同时需要知道所属汽车的信息。
+
+**`Car` 类**(外部类):
+
+- **私有属性**:`brand`(品牌,String)、`model`(型号,String)
+- **构造方法**:`Car(String brand, String model)`
+- **成员内部类** `Engine`:
+  - **普通方法**:`void start()` —— 输出 `"发动机启动:{brand} {model} 轰鸣声..."`(直接访问外部类的私有属性)
+  - **普通方法**:`void stop()` —— 输出 `"发动机熄火:{brand} {model} 安静了..."`
+- **外部类方法**:`void drive()` —— 创建 `Engine` 对象并调用 `start()`,然后输出 `"{brand} {model} 正在行驶..."`,再调用 `stop()`
+
+**测试类 `CarTest` 要求**:
+
+```java
+public class CarTest {
+    public static void main(String[] args) {
+        // 1. 创建 Car 对象
+        Car car = new Car("宝马", "X5");
+        
+        // 2. 调用外部类方法——内部由 Car 自己完成
+        car.drive();
+        
+        // 3. (思考)如果 Engine 不是内部类,而是独立类,
+        //    需要如何修改才能让 Engine 访问 Car 的 brand 和 model?
+    }
+}
+```
+
+**预期输出**:
+```
+发动机启动:宝马 X5 轰鸣声...
+宝马 X5 正在行驶...
+发动机熄火:宝马 X5 安静了...
+```
+
+**思考题**:
+1. 从上述代码看,内部类访问外部类的私有成员时,是否需要 getter 方法?
+2. 如果 `Engine` 改为私有内部类,外界(如 `CarTest`)能否直接创建 `Engine` 对象?
+3. 本练习中 `Engine` 对象的创建是在 `Car` 的内部方法 `drive()` 中完成的,这符合「外部类访问内部类必须创建对象」的特点吗?
+
+---
+
+## 练习 2:私有内部类设计——人(Person)与心脏(Heart)
+
+**难度**:⭐⭐  
+**知识点**:私有内部类、外部类提供公共方法暴露内部类功能、设计原则
+
+**场景描述**:人有心脏,心脏离开人体无法独立存在。按照 **私有内部类设计原则**,心脏应该作为人的私有内部类,外界必须通过人的公共方法才能使用心脏的功能。
+
+**`Person` 类**(外部类):
+
+- **私有属性**:`name`(姓名,String)
+- **构造方法**:`Person(String name)`
+- **私有内部类** `Heart`:
+  - **普通方法**:`void beat()` —— 输出 `"{name} 的心脏在跳动:咚咚咚..."`(直接访问外部类私有属性)
+  - **普通方法**:`void rest()` —— 输出 `"{name} 的心脏在休息:咚...咚...咚..."`
+- **公共方法**:`void heartbeat()` —— 在方法内部创建 `Heart` 对象并调用 `beat()` 和 `rest()`
+
+**测试类 `PersonTest` 要求**:
+
+```java
+public class PersonTest {
+    public static void main(String[] args) {
+        // 1. 创建 Person 对象
+        Person person = new Person("张三");
+        
+        // 2. 通过 Person 的公共方法访问心脏功能
+        person.heartbeat();
+        
+        // 3. ❌ 思考:能直接这样创建心脏对象吗?
+        //    Person.Heart h = new Person().new Heart();  // 编译能通过吗?为什么?
+    }
+}
+```
+
+**预期输出**:
+```
+张三 的心脏在跳动:咚咚咚...
+张三 的心脏在休息:咚...咚...咚...
+```
+
+**请回答以下问题**:
+
+1. 将 `Heart` 类设为 `private` 的好处是什么?
+2. 如果 `Person` 类想对外提供「获取心脏对象」的能力,应该如何修改代码?(参考课堂笔记中 `getHeart()` 方法的设计)
+3. 如果不使用私有内部类,而是将 `Heart` 写成一个独立类,让 `Person` 持有 `Heart` 成员变量,会有什么弊端?(提示:外界可能跳过 `Person` 直接创建 `Heart` 对象)
+
+**代码补充挑战**:请将 `Person` 类补充完整:
+
+```java
+public class Person {
+    private String name;
+    
+    // 构造方法
+    public Person(String name) {
+        this.name = name;
+    }
+    
+    // 私有内部类 Heart
+    // 请补充代码
+    
+    
+    // 公共方法 heartbeat()
+    // 请补充代码
+    
+    
+}
+```
+
+---
+
+## 练习 3:静态成员内部类——学校与学生证打印
+
+**难度**:⭐⭐  
+**知识点**:静态成员内部类、静态内部类创建格式、静态内部类与外部类的关系
+
+**场景描述**:每所学校(`School`)都有统一格式的学生证(`StudentCard`),其中包含学校名称和学生的个人信息。学生证的模板格式由学校统一规定(静态内部类),不依赖某个具体的学校对象。
+
+**`School` 类**(外部类):
+
+- **私有静态属性**:`schoolName`(学校名称,static String)—— 所有学校对象共享
+- **静态代码块**:初始化 `schoolName` 为 `"四福科技大学"`
+- **静态成员内部类** `StudentCard`:用 `static` 修饰
+  - **私有属性**:`studentName`(学生姓名,String)、`studentId`(学号,String)
+  - **构造方法**:`StudentCard(String studentName, String studentId)`
+  - **普通方法**:`void showCard()` —— 输出学生证信息(学校名称使用外部类的静态属性)
+
+**测试类 `SchoolTest` 要求**:
+
+```java
+public class SchoolTest {
+    public static void main(String[] args) {
+        // 1. 创建静态内部类对象——格式:外部类名.内部类名 变量 = new 外部类名.内部类名(...)
+        School.StudentCard card1 = new School.StudentCard("张三", "2024001");
+        School.StudentCard card2 = new School.StudentCard("李四", "2024002");
+        
+        // 2. 输出学生证信息
+        card1.showCard();
+        card2.showCard();
+        
+        // 3. 思考:创建静态内部类对象时,需不需要先创建 School 对象?为什么?
+    }
+}
+```
+
+**预期输出**:
+```
+========== 四福科技大学 学生证 ==========
+姓名:张三
+学号:2024001
+
+========== 四福科技大学 学生证 ==========
+姓名:李四
+学号:2024002
+```
+
+**思考题**:
+1. 静态内部类和普通成员内部类在创建对象时的格式有什么区别?
+2. 静态内部类能否访问外部类的 **非静态** 成员(如实例变量)?为什么?
+3. 如果 `schoolName` 不是 `static` 的,上面的代码能否正常运行?应该如何修改?
+
+---
+
+## 练习 4:局部内部类——餐厅点餐系统
+
+**难度**:⭐⭐⭐  
+**知识点**:局部内部类、定义在方法内部的类、局部内部类的作用域
+
+**场景描述**:餐厅(`Restaurant`)中有多种点餐方式(如堂食、外卖)。每种点餐方式的实现细节(如输出欢迎语、计算价格等)各不相同,且只在点餐方法内部使用,故设计为局部内部类。
+
+**`Restaurant` 类**(外部类):
+
+- **私有属性**:`name`(餐厅名称,String)
+- **构造方法**:`Restaurant(String name)`
+- **方法** `void dineIn()` —— 堂食点餐
+  - **局部内部类** `DineInOrder`:
+    - **构造方法**:输出 `"【堂食】xxx 餐厅欢迎您入座!"`(xxx 为餐厅名称)
+    - **普通方法**:`void orderFood(String dish)` —— 输出 `"【堂食】已点餐:{dish},请稍候..."`
+    - **普通方法**:`void pay(double amount)` —— 输出 `"【堂食】支付:{amount} 元,感谢惠顾!"`
+  - 在 `dineIn()` 方法内创建 `DineInOrder` 对象,调用 `orderFood("红烧肉")` 和 `pay(68.0)`
+- **方法** `void takeout()` —— 外卖点餐
+  - **局部内部类** `TakeoutOrder`:
+    - **构造方法**:输出 `"【外卖】感谢您选择 xxx 餐厅!"`(xxx 为餐厅名称)
+    - **普通方法**:`void orderFood(String dish)` —— 输出 `"【外卖】已接单:{dish},正在准备..."`
+    - **普通方法**:`void pay(double amount)` —— 输出 `"【外卖】在线支付:{amount} 元,等待配送..."`
+  - 在 `takeout()` 方法内创建 `TakeoutOrder` 对象,调用 `orderFood("宫保鸡丁")` 和 `pay(38.0)`
+
+**测试类 `RestaurantTest` 要求**:
+
+```java
+public class RestaurantTest {
+    public static void main(String[] args) {
+        Restaurant restaurant = new Restaurant("幸福小馆");
+        
+        // 堂食
+        restaurant.dineIn();
+        System.out.println();
+        
+        // 外卖
+        restaurant.takeout();
+        
+        // 思考:在外界能否直接创建 DineInOrder 或 TakeoutOrder 对象?为什么?
+    }
+}
+```
+
+**预期输出**:
+```
+【堂食】幸福小馆 餐厅欢迎您入座!
+【堂食】已点餐:红烧肉,请稍候...
+【堂食】支付:68.0 元,感谢惠顾!
+
+【外卖】感谢您选择 幸福小馆 餐厅!
+【外卖】已接单:宫保鸡丁,正在准备...
+【外卖】在线支付:38.0 元,等待配送...
+```
+
+**思考题**:
+1. 局部内部类的作用范围是什么?方法外部能否访问?
+2. 局部内部类除了可以访问外部类的成员,还可以访问所在方法内的 **局部变量**。请在 `dineIn()` 方法中添加一个局部变量 `String welcome = "欢迎光临";`,尝试在 `DineInOrder` 内部类中访问它,观察是否能编译通过。
+3. 局部内部类和成员内部类在使用场景上有什么本质区别?
+
+---
+
+# 第二部分:进阶练习
+
+> 以下为综合挑战题,融合多种内部类类型、内部类访问规则、设计原则等知识点。
+
+---
+
+## 第 1 题:综合应用——计算机与外设(成员内部类 + 静态内部类)⭐⭐⭐⭐
+
+### 需求说明
+
+模拟计算机(`Computer`)的组成结构。计算机包含:
+- **CPU** —— 计算机的核心处理部件,每台计算机有自己的 CPU,CPU 的行为与具体的计算机相关(**成员内部类**)
+- **USB 接口规范** —— 所有计算机的 USB 接口规范是统一的,不依赖具体的计算机实例(**静态内部类**)
+- **内存条** —— 计算机的内存,可更换升级(**普通成员内部类**,但设计为私有)
+
+### 类设计
+
+**`Computer` 类**(外部类):
+
+**私有属性**:
+
+| 属性 | 类型 | 说明 |
+|------|------|------|
+| `brand` | String | 品牌 |
+| `model` | String | 型号 |
+| `ram` | Memory | 内存条对象(内部类) |
+
+**构造方法**:`Computer(String brand, String model, int ramSize)` —— 初始化品牌、型号,并创建 `Memory` 对象(内存大小为 `ramSize` GB)
+
+#### 内部类 1:CPU(成员内部类,非私有)
+
+**`CPU` 类**(成员内部类):
+- **私有属性**:`cores`(核心数,int)、`frequency`(主频,double,单位 GHz)
+- **构造方法**:`CPU(int cores, double frequency)`
+- **普通方法**:`void process()` —— 输出 `"{brand} {model} CPU 正在计算:{cores} 核 {frequency}GHz 全速运行..."`(访问外部类私有属性)
+
+#### 内部类 2:UsbSpec(静态成员内部类)
+
+**`UsbSpec` 类**(静态成员内部类):
+- **静态常量**:`USB_VERSION = "3.0"`(String)
+- **静态常量**:`MAX_SPEED = "5Gbps"`(String)
+- **静态方法**:`void showSpec()` —— 输出 `"USB 接口规范:版本 {USB_VERSION},最大速度 {MAX_SPEED}"`
+- **普通方法**:`void connectDevice(String deviceName)` —— 输出 `"已连接 {deviceName},使用 USB {USB_VERSION} 协议传输数据"`
+
+#### 内部类 3:Memory(私有成员内部类)
+
+**`Memory` 类**(私有成员内部类):
+- **私有属性**:`size`(容量,int,单位 GB)
+- **构造方法**:`Memory(int size)`
+- **普通方法**:`void loadData()` —— 输出 `"{brand} {model} 正在加载数据到内存({size}GB)..."`
+
+#### 外部类方法
+
+| 方法 | 说明 |
+|------|------|
+| `void startUp()` | 启动计算机:创建 CPU 对象(4 核,3.2GHz),调用 CPU 的 `process()` 方法,再调用 `Memory` 的 `loadData()` 方法 |
+| `void replaceMemory(int newSize)` | 更换内存条:重新创建 `Memory` 对象,输出 `"内存已升级为 {newSize}GB"` |
+| `CPU getCpu()` | 获取 CPU 对象(返回 CPU 类型,演示外部类返回内部类对象) |
+
+### 测试类要求
+
+**`ComputerTest` 类**:
+
+```java
+public class ComputerTest {
+    public static void main(String[] args) {
+        // 1. 创建 Computer 对象(品牌:联想,型号:ThinkPad,内存:16GB)
+        Computer computer = new Computer("联想", "ThinkPad", 16);
+        
+        // 2. 启动计算机
+        computer.startUp();
+        System.out.println();
+        
+        // 3. 更换内存(升级到 32GB)
+        computer.replaceMemory(32);
+        System.out.println();
+        
+        // 4. 使用静态内部类 UsbSpec
+        //    4.1 调用静态内部类的静态方法(无需创建对象)
+        Computer.UsbSpec.showSpec();
+        System.out.println();
+        
+        //    4.2 创建静态内部类对象,调用普通方法
+        Computer.UsbSpec usb = new Computer.UsbSpec();
+        usb.connectDevice("移动硬盘");
+        usb.connectDevice("键盘");
+        System.out.println();
+        
+        // 5. 通过外部类方法获取 CPU 对象(演示外部类返回内部类对象)
+        Computer.CPU cpu = computer.getCpu();
+        cpu.process();
+    }
+}
+```
+
+### 预期输出
+
+```
+联想 ThinkPad CPU 正在计算:4 核 3.2GHz 全速运行...
+联想 ThinkPad 正在加载数据到内存(16GB)...
+
+内存已升级为 32GB
+
+USB 接口规范:版本 3.0,最大速度 5Gbps
+
+已连接 移动硬盘,使用 USB 3.0 协议传输数据
+已连接 键盘,使用 USB 3.0 协议传输数据
+
+联想 ThinkPad CPU 正在计算:4 核 3.2GHz 全速运行...
+```
+
+### 思考题
+
+1. 本练习中为什么 `UsbSpec` 设计为 **静态内部类**?USB 接口规范和具体的计算机实例有关吗?
+2. 为什么 `Memory` 设计为 **私有内部类**?外界可以直接更换内存吗?(提示:通过 `replaceMemory()` 方法)
+3. 成员内部类 `CPU` 没有被 `private` 修饰,外界可以直接创建 `Computer.CPU` 对象吗?如果可以,创建格式是什么?
+4. 如果将 `UsbSpec` 改为普通成员内部类(去掉 `static`),创建 `UsbSpec` 对象的格式会变成什么样?
+
+---
+
+## 第 2 题:综合应用——银行账户系统(私有内部类 + 局部内部类 + 静态内部类)⭐⭐⭐⭐⭐
+
+### 需求说明
+
+模拟银行账户系统。一个银行(`Bank`)管理多个账户(`Account`),每个账户包含交易记录(`Transaction`)。要求:
+- **账户** 作为银行的 **私有成员内部类** —— 外界不能直接创建账户对象,必须通过银行创建
+- **交易记录** 作为账户方法的 **局部内部类** —— 只在存款/取款方法内部使用
+- **利率信息** 作为银行的 **静态内部类** —— 所有银行共享利率规范
+
+### 类设计
+
+**`Bank` 类**(外部类):
+
+**私有静态属性**:
+
+| 属性 | 类型 | 说明 |
+|------|------|------|
+| `bankName` | String | 银行名称(静态) |
+
+**静态代码块**:初始化 `bankName = "四福银行"`
+
+**私有成员内部类 `Account`**:
+
+- **私有属性**:`accountId`(账号,String)、`holderName`(户主姓名,String)、`balance`(余额,double)
+- **构造方法**:`Account(String accountId, String holderName, double initialBalance)`
+- **方法** `void deposit(double amount)` —— 存款
+  - 方法内部定义 **局部内部类** `DepositTransaction`:
+    - **构造方法**:无参,输出 `"【存款交易】开始..."`
+    - **方法**:`void execute()` —— 增加余额,输出 `"{holderName} 存入 {amount} 元,余额:{balance} 元(银行:{bankName})"`(注意:局部内部类可访问外部类所有成员,也可访问所在方法的局部变量 `amount`)
+  - 方法内部创建 `DepositTransaction` 对象并调用 `execute()`
+- **方法** `void withdraw(double amount)` —— 取款
+  - 如果余额不足,输出 `"取款失败:{holderName} 余额不足(当前余额:{balance} 元)"`
+  - 否则,方法内部定义 **局部内部类** `WithdrawTransaction`:
+    - **构造方法**:无参,输出 `"【取款交易】开始..."`
+    - **方法**:`void execute()` —— 减少余额,输出 `"{holderName} 取出 {amount} 元,余额:{balance} 元"`
+  - 余额足够时创建 `WithdrawTransaction` 对象并调用 `execute()`
+
+**方法** `Account openAccount(String holderName, double initialBalance)` —— 开户
+
+- 自动生成账号(格式:`"AC" + System.currentTimeMillis()`)
+- 创建 `Account` 对象并返回
+- 输出 `"开户成功!欢迎 {holderName} 成为 {bankName} 的客户"`
+
+**静态内部类 `RateInfo`**:
+
+- **静态常量**:`SAVING_RATE = 0.025`(年利率 2.5%)
+- **静态常量**:`LOAN_RATE = 0.045`(贷款利率 4.5%)
+- **静态方法**:`void showRate()` —— 输出利率信息
+- **普通方法**:`double calculateInterest(double principal, int years)` —— 计算存款利息(复利:`principal * Math.pow(1 + SAVING_RATE, years) - principal`)
+
+### 测试类要求
+
+**`BankTest` 类**:
+
+```java
+public class BankTest {
+    public static void main(String[] args) {
+        // 1. 查看银行利率(静态内部类的静态方法)
+        Bank.RateInfo.showRate();
+        System.out.println();
+        
+        // 2. 创建利率计算器对象(静态内部类)
+        Bank.RateInfo calculator = new Bank.RateInfo();
+        double interest = calculator.calculateInterest(10000, 3);
+        System.out.println("1 万元存 3 年,利息:" + String.format("%.2f", interest) + " 元");
+        System.out.println();
+        
+        // 3. 到银行开户
+        Bank bank = new Bank();
+        // 注意:openAccount 返回的是 Bank.Account 类型(私有内部类),
+        // 但因为 Account 是 private 的,这里需要思考怎么接收返回值?
+        // 提示:可以用 var(Java 10+)或 Object 类型接收,或者让 Bank 提供其他方法来操作账户
+        
+        // ❓ 问题:由于 Account 是私有内部类,BankTest 中无法声明 Bank.Account 类型的变量!
+        // 那么应该如何设计 Bank 类,让外界能够操作账户?
+        //
+        // 提示方案:
+        // 方案 A:在 Bank 中存储账户,并提供存款/取款的公共方法(通过账号索引)
+        // 方案 B:定义一个接口,让 Account 实现该接口,Bank 返回接口类型
+        //
+        // 请选择一种方案完成设计,并在测试类中完成以下操作:
+        //   - 张三开户,存入 5000 元
+        //   - 张三存款 2000 元
+        //   - 张三取款 1000 元
+        //   - 张三尝试取款 10000 元(余额不足)
+    }
+}
+```
+
+### 思考与设计挑战
+
+本题的关键在于:**私有内部类 `Account` 的类型在外界不可见**,如何让外界操作账户?
+
+请选择以下方案之一完成设计:
+
+**方案 A**(推荐):在 `Bank` 类中使用数组或集合存储账户,对外提供 `deposit(String accountId, double amount)` 和 `withdraw(String accountId, double amount)` 等公共方法,外界通过账号来操作。
+
+**方案 B**:定义一个 `Accountable` 接口(包含 `deposit`、`withdraw` 方法),让 `Account` 实现该接口,`openAccount()` 方法返回 `Accountable` 类型。
+
+### 预期输出(方案 A 参考)
+
+```
+========== 四福银行 利率信息 ==========
+储蓄年利率:2.5%
+贷款年利率:4.5%
+
+1 万元存 3 年,利息:768.91 元
+
+========== 开户与交易 ==========
+开户成功!欢迎 张三 成为 四福银行 的客户
+【存款交易】开始...
+张三 存入 5000.0 元,余额:5000.0 元(银行:四福银行)
+【存款交易】开始...
+张三 存入 2000.0 元,余额:7000.0 元(银行:四福银行)
+【取款交易】开始...
+张三 取出 1000.0 元,余额:6000.0 元
+取款失败:张三 余额不足(当前余额:6000.0 元)
+```
+
+### 思考题
+
+1. 为什么 `Account` 设计为 `Bank` 的私有内部类?这体现了什么设计原则?(参考课堂笔记中 `Heart` 私有化的原因)
+2. 局部内部类 `DepositTransaction` 和 `WithdrawTransaction` 为什么定义在方法内部,而不是定义为成员内部类?
+3. 静态内部类 `RateInfo` 中的 `showRate()` 是静态方法,不需要创建对象就能调用;而 `calculateInterest()` 是普通方法,需要创建对象才能调用。这两种方式分别适用于什么场景?
+4. 如果去掉 `RateInfo` 的 `static` 修饰,上面的代码中 `Bank.RateInfo.showRate()` 还能编译通过吗?`new Bank.RateInfo()` 还能编译通过吗?
+
+---
+
+## 📋 题目总览
+
+| 序号 | 所属部分 | 核心知识点 | 难度 |
+|------|---------|-----------|------|
+| 练习 1 | 随堂 | 成员内部类概念、内部类访问外部类成员 | ⭐ |
+| 练习 2 | 随堂 | 私有内部类设计原则、外部类提供公共方法暴露内部类功能 | ⭐⭐ |
+| 练习 3 | 随堂 | 静态成员内部类、创建格式、与外部类的关系 | ⭐⭐ |
+| 练习 4 | 随堂 | 局部内部类、定义在方法内部、作用域限制 | ⭐⭐⭐ |
+| 进阶 1 | 进阶 | 成员内部类 + 静态内部类 + 私有内部类综合运用 | ⭐⭐⭐⭐ |
+| 进阶 2 | 进阶 | 私有内部类 + 局部内部类 + 静态内部类 + 设计模式综合 | ⭐⭐⭐⭐⭐ |