|
@@ -0,0 +1,358 @@
|
|
|
|
|
+# 2026-07-24 JavaSE 课后作业
|
|
|
|
|
+
|
|
|
|
|
+> **课程内容**:多态(Polymorphism)、多态中的转型(向上转型/向下转型)、instanceof 运算符、抽象类与多态结合、接口多态案例(USB + 笔记本)、内部类(成员内部类/静态成员内部类/局部内部类)
|
|
|
|
|
+>
|
|
|
|
|
+> **涉及前序知识**:继承、抽象类、接口、封装、构造方法、方法重写
|
|
|
|
|
+>
|
|
|
|
|
+> **提交方式**:在 `提交\姓名\` 目录下创建对应的 Java 源文件
|
|
|
|
|
+>
|
|
|
|
|
+> **截止时间**:下次上课前
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 📌 本次作业重要说明
|
|
|
|
|
+
|
|
|
|
|
+### 命名要求
|
|
|
|
|
+
|
|
|
|
|
+| 项目 | 要求 |
|
|
|
|
|
+|------|------|
|
|
|
|
|
+| **包名** | **必须按题目指定的包名创建**(全小写) |
|
|
|
|
|
+| **类名** | 自由命名,但需**见名知意** |
|
|
|
|
|
+| **测试类** | 建议命名为 `TestXxx` 或 `XxxTest` |
|
|
|
|
|
+| **文件名** | 必须与类名一致 |
|
|
|
|
|
+
|
|
|
|
|
+### 提交目录结构示例
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+提交\
|
|
|
|
|
+└─ 张三\
|
|
|
|
|
+ ├─ p1_zoo\ ← 第 1 题的包
|
|
|
|
|
+ │ ├─ Animal.java ← 抽象父类
|
|
|
|
|
+ │ ├─ Lion.java ← 子类
|
|
|
|
|
+ │ ├─ Penguin.java ← 子类
|
|
|
|
|
+ │ ├─ Parrot.java ← 子类
|
|
|
|
|
+ │ └─ ZooGuide.java ← 测试类(多态 + instanceof)
|
|
|
|
|
+ ├─ p2_smarthome\ ← 第 2 题的包
|
|
|
|
|
+ │ ├─ SmartDevice.java ← 接口
|
|
|
|
|
+ │ ├─ Light.java ← 实现类
|
|
|
|
|
+ │ ├─ AirConditioner.java ← 实现类
|
|
|
|
|
+ │ ├─ RobotVacuum.java ← 实现类
|
|
|
|
|
+ │ └─ SmartHomeController.java ← 测试类
|
|
|
|
|
+ └─ p3_computer\ ← 第 3 题的包
|
|
|
|
|
+ ├─ Computer.java ← 外部类(含内部类)
|
|
|
|
|
+ └─ TestComputer.java ← 测试类
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+> ⚠ **注意**:包名必须严格按题目要求书写(全小写),目录结构必须与包结构一致。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 第 1 题:多态 + 转型 + instanceof——动物园导游系统 ⭐⭐⭐
|
|
|
|
|
+
|
|
|
|
|
+**包名**:`p1_zoo`
|
|
|
|
|
+
|
|
|
|
|
+**知识点**:多态、向上转型/向下转型、instanceof 运算符、抽象类、调用子类特有方法
|
|
|
|
|
+
|
|
|
|
|
+### 需求说明
|
|
|
|
|
+
|
|
|
|
|
+某动物园需要开发一个**导游讲解系统**。动物园里有多种动物,每种动物都有**共同的行为**(进食、睡觉),也有**各自的特有行为**(有的会吼叫、有的会游泳、有的会模仿说话)。导游需要根据不同动物类型进行不同的讲解。
|
|
|
|
|
+
|
|
|
|
|
+请使用 **抽象父类 + 多态 + instanceof + 向下转型** 来设计。
|
|
|
|
|
+
|
|
|
|
|
+### 类设计
|
|
|
|
|
+
|
|
|
|
|
+#### Animal 抽象类(父类)
|
|
|
|
|
+
|
|
|
|
|
+| 成员 | 说明 |
|
|
|
|
|
+|------|------|
|
|
|
|
|
+| 私有属性 | `name`(名称,String)、`age`(年龄,int) |
|
|
|
|
|
+| 构造方法 | `Animal(String name, int age)` |
|
|
|
|
|
+| 抽象方法 | `void eat()` |
|
|
|
|
|
+| 抽象方法 | `void sleep()` |
|
|
|
|
|
+| 普通方法 | `void showInfo()` —— 输出 `"动物:xxx,年龄:xxx岁"` |
|
|
|
|
|
+
|
|
|
|
|
+#### Lion 类(狮子——继承 Animal)
|
|
|
|
|
+
|
|
|
|
|
+| 成员 | 说明 |
|
|
|
|
|
+|------|------|
|
|
|
|
|
+| 构造方法 | `Lion(String name, int age)` |
|
|
|
|
|
+| 重写 `eat()` | 输出 `"狮子 xxx 正在吃肉..."` |
|
|
|
|
|
+| 重写 `sleep()` | 输出 `"狮子 xxx 在洞穴里睡觉..."` |
|
|
|
|
|
+| **特有** `roar()` | 输出 `"狮子 xxx 发出吼叫:嗷呜~~"` |
|
|
|
|
|
+
|
|
|
|
|
+#### Penguin 类(企鹅——继承 Animal)
|
|
|
|
|
+
|
|
|
|
|
+| 成员 | 说明 |
|
|
|
|
|
+|------|------|
|
|
|
|
|
+| 构造方法 | `Penguin(String name, int age)` |
|
|
|
|
|
+| 重写 `eat()` | 输出 `"企鹅 xxx 正在吃鱼..."` |
|
|
|
|
|
+| 重写 `sleep()` | 输出 `"企鹅 xxx 站着睡觉..."` |
|
|
|
|
|
+| **特有** `swim()` | 输出 `"企鹅 xxx 在水中游泳..."` |
|
|
|
|
|
+
|
|
|
|
|
+#### Parrot 类(鹦鹉——继承 Animal)
|
|
|
|
|
+
|
|
|
|
|
+| 成员 | 说明 |
|
|
|
|
|
+|------|------|
|
|
|
|
|
+| 私有属性 | `vocabulary`(词汇量,int) |
|
|
|
|
|
+| 构造方法 | `Parrot(String name, int age, int vocabulary)` |
|
|
|
|
|
+| 重写 `eat()` | 输出 `"鹦鹉 xxx 正在啄食谷物..."` |
|
|
|
|
|
+| 重写 `sleep()` | 输出 `"鹦鹉 xxx 挂在树枝上睡觉..."` |
|
|
|
|
|
+| **特有** `imitate()` | 输出 `"鹦鹉 xxx 模仿人类说话:你好!词汇量:xxx个"` |
|
|
|
|
|
+
|
|
|
|
|
+### 测试类要求
|
|
|
|
|
+
|
|
|
|
|
+**`ZooGuide` 类**:
|
|
|
|
|
+
|
|
|
|
|
+1. **创建动物数组**:`Animal[]` 数组,包含至少 4 种动物
|
|
|
|
|
+
|
|
|
|
|
+ ```java
|
|
|
|
|
+ Animal a1 = new Lion("辛巴", 5);
|
|
|
|
|
+ Animal a2 = new Penguin("乐乐", 2);
|
|
|
|
|
+ Animal a3 = new Parrot("小彩虹", 1, 50);
|
|
|
|
|
+ Animal a4 = new Lion("娜娜", 4);
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+2. **遍历执行通用行为**:调用每个元素的 `showInfo()`、`eat()`、`sleep()`
|
|
|
|
|
+
|
|
|
|
|
+3. **遍历执行特有行为**:使用 `instanceof` 判断类型后向下转型
|
|
|
|
|
+ - `Lion` → `roar()`
|
|
|
|
|
+ - `Penguin` → `swim()`
|
|
|
|
|
+ - `Parrot` → `imitate()`
|
|
|
|
|
+
|
|
|
|
|
+### 思考题
|
|
|
|
|
+
|
|
|
|
|
+1. 为什么 `Animal` 要设计为抽象类?用普通父类可以吗?
|
|
|
|
|
+2. 如果不用 `instanceof` 直接向下转型,传入 `Penguin` 时强转为 `(Lion)` 会怎样?
|
|
|
|
|
+3. 如果新增 `Elephant` 类,需要修改 `ZooGuide` 吗?这符合什么设计原则?
|
|
|
|
|
+
|
|
|
|
|
+### 预期输出
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+========== 动物园导游系统 ==========
|
|
|
|
|
+动物:辛巴,年龄:5岁
|
|
|
|
|
+狮子 辛巴 正在吃肉...
|
|
|
|
|
+狮子 辛巴 在洞穴里睡觉...
|
|
|
|
|
+狮子 辛巴 发出吼叫:嗷呜~~
|
|
|
|
|
+
|
|
|
|
|
+动物:乐乐,年龄:2岁
|
|
|
|
|
+企鹅 乐乐 正在吃鱼...
|
|
|
|
|
+企鹅 乐乐 站着睡觉...
|
|
|
|
|
+企鹅 乐乐 在水中游泳...
|
|
|
|
|
+
|
|
|
|
|
+动物:小彩虹,年龄:1岁
|
|
|
|
|
+鹦鹉 小彩虹 正在啄食谷物...
|
|
|
|
|
+鹦鹉 小彩虹 挂在树枝上睡觉...
|
|
|
|
|
+鹦鹉 小彩虹 模仿人类说话:你好!词汇量:50个
|
|
|
|
|
+
|
|
|
|
|
+动物:娜娜,年龄:4岁
|
|
|
|
|
+狮子 娜娜 正在吃肉...
|
|
|
|
|
+狮子 娜娜 在洞穴里睡觉...
|
|
|
|
|
+狮子 娜娜 发出吼叫:嗷呜~~
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 第 2 题:接口多态——智能家居控制系统 ⭐⭐⭐
|
|
|
|
|
+
|
|
|
|
|
+**包名**:`p2_smarthome`
|
|
|
|
|
+
|
|
|
|
|
+**知识点**:接口定义、implements 实现接口、接口多态、多态参数、多态数组
|
|
|
|
|
+
|
|
|
|
|
+### 需求说明
|
|
|
|
|
+
|
|
|
|
|
+开发一个**智能家居控制系统**。不同家电的开关方式和运行逻辑不同,但都遵循统一的控制规范:**打开 → 运行 → 关闭**。
|
|
|
|
|
+
|
|
|
|
|
+请使用 **接口多态** 来设计,要求控制器不依赖具体家电类型。
|
|
|
|
|
+
|
|
|
|
|
+### 类设计
|
|
|
|
|
+
|
|
|
|
|
+#### SmartDevice 接口
|
|
|
|
|
+
|
|
|
|
|
+| 方法 | 说明 |
|
|
|
|
|
+|------|------|
|
|
|
|
|
+| `void turnOn()` | 打开设备 |
|
|
|
|
|
+| `void doWork()` | 执行工作 |
|
|
|
|
|
+| `void turnOff()` | 关闭设备 |
|
|
|
|
|
+
|
|
|
|
|
+#### Light 类(灯——实现 SmartDevice)
|
|
|
|
|
+
|
|
|
|
|
+| 成员 | 说明 |
|
|
|
|
|
+|------|------|
|
|
|
|
|
+| 私有属性 | `location`(位置,String,如 "客厅" / "卧室") |
|
|
|
|
|
+| 构造方法 | `Light(String location)` |
|
|
|
|
|
+| 实现 `turnOn()` | 输出 `"xxx 的灯已打开"` |
|
|
|
|
|
+| 实现 `doWork()` | 输出 `"xxx 的灯照明中..."` |
|
|
|
|
|
+| 实现 `turnOff()` | 输出 `"xxx 的灯已关闭"` |
|
|
|
|
|
+
|
|
|
|
|
+#### AirConditioner 类(空调——实现 SmartDevice)
|
|
|
|
|
+
|
|
|
|
|
+| 成员 | 说明 |
|
|
|
|
|
+|------|------|
|
|
|
|
|
+| 私有属性 | `roomName`(房间名,String)、`temperature`(温度,int) |
|
|
|
|
|
+| 构造方法 | `AirConditioner(String roomName, int temperature)` |
|
|
|
|
|
+| 实现 `turnOn()` | 输出 `"xxx 空调已打开,设定温度:xxx℃"` |
|
|
|
|
|
+| 实现 `doWork()` | 输出 `"xxx 空调制冷中,当前室温正降至 xxx℃..."` |
|
|
|
|
|
+| 实现 `turnOff()` | 输出 `"xxx 空调已关闭"` |
|
|
|
|
|
+
|
|
|
|
|
+#### RobotVacuum 类(扫地机器人——实现 SmartDevice)
|
|
|
|
|
+
|
|
|
|
|
+| 成员 | 说明 |
|
|
|
|
|
+|------|------|
|
|
|
|
|
+| 私有属性 | `model`(型号,String)、`batteryLevel`(电量,int,百分比) |
|
|
|
|
|
+| 构造方法 | `RobotVacuum(String model, int batteryLevel)` |
|
|
|
|
|
+| 实现 `turnOn()` | 输出 `"扫地机器人 xxx 已启动,当前电量:xxx%"` |
|
|
|
|
|
+| 实现 `doWork()` | 输出 `"扫地机器人 xxx 开始清扫地面..."` |
|
|
|
|
|
+| 实现 `turnOff()` | 输出 `"扫地机器人 xxx 已完成清扫,自动关闭"` |
|
|
|
|
|
+
|
|
|
|
|
+### 测试类要求
|
|
|
|
|
+
|
|
|
|
|
+**`SmartHomeController` 类**:
|
|
|
|
|
+
|
|
|
|
|
+1. **创建设备数组**:`SmartDevice[]` 数组,包含至少 4 个设备
|
|
|
|
|
+
|
|
|
|
|
+ ```java
|
|
|
|
|
+ SmartDevice light1 = new Light("客厅");
|
|
|
|
|
+ SmartDevice ac = new AirConditioner("主卧", 26);
|
|
|
|
|
+ SmartDevice robot = new RobotVacuum("石头T10", 80);
|
|
|
|
|
+ SmartDevice light2 = new Light("书房");
|
|
|
|
|
+ ```
|
|
|
|
|
+
|
|
|
|
|
+2. **遍历执行工作流程**:对每个设备依次调用 `turnOn()` → `doWork()` → `turnOff()`
|
|
|
|
|
+
|
|
|
|
|
+3. **编写静态方法** `startDevice(SmartDevice device, int seconds)`:
|
|
|
|
|
+ - 调用 `device.turnOn()`
|
|
|
|
|
+ - 输出 `"设备工作中,请等待" + seconds + "秒..."`
|
|
|
|
|
+ - 调用 `device.doWork()`
|
|
|
|
|
+ - 调用 `device.turnOff()`
|
|
|
|
|
+ - 在 `main` 中用不同类型设备调用该方法
|
|
|
|
|
+
|
|
|
|
|
+### 思考题
|
|
|
|
|
+
|
|
|
|
|
+1. 方法参数 `SmartDevice device` 可以传入哪些类型的对象?这体现了多态的什么好处?
|
|
|
|
|
+2. 如果新增 `SmartSpeaker` 实现 `SmartDevice`,控制器需要修改吗?
|
|
|
|
|
+3. 对比课堂 `NoteBook.useUsb(Usb usb)` 案例,设计思路有什么相似之处?
|
|
|
|
|
+
|
|
|
|
|
+### 预期输出
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+========== 智能家居启动 ==========
|
|
|
|
|
+客厅的灯已打开
|
|
|
|
|
+客厅的灯照明中...
|
|
|
|
|
+客厅的灯已关闭
|
|
|
|
|
+
|
|
|
|
|
+主卧空调已打开,设定温度:26℃
|
|
|
|
|
+主卧空调制冷中,当前室温正降至 26℃...
|
|
|
|
|
+主卧空调已关闭
|
|
|
|
|
+
|
|
|
|
|
+扫地机器人 石头T10 已启动,当前电量:80%
|
|
|
|
|
+扫地机器人 石头T10 开始清扫地面...
|
|
|
|
|
+扫地机器人 石头T10 已完成清扫,自动关闭
|
|
|
|
|
+
|
|
|
|
|
+书房的灯已打开
|
|
|
|
|
+书房的灯照明中...
|
|
|
|
|
+书房的灯已关闭
|
|
|
|
|
+
|
|
|
|
|
+========== 测试 startDevice 方法 ==========
|
|
|
|
|
+客厅的灯已打开
|
|
|
|
|
+设备工作中,请等待10秒...
|
|
|
|
|
+客厅的灯照明中...
|
|
|
|
|
+客厅的灯已关闭
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 第 3 题:内部类——计算机硬件体系 ⭐⭐⭐
|
|
|
|
|
+
|
|
|
|
|
+**包名**:`p3_computer`
|
|
|
|
|
+
|
|
|
|
|
+**知识点**:成员内部类、私有内部类、内部类访问外部类私有成员、外部类通过方法暴露内部类
|
|
|
|
|
+
|
|
|
|
|
+### 需求说明
|
|
|
|
|
+
|
|
|
|
|
+一台计算机由多个硬件组成,如 **CPU(处理器)** 和 **内存**。这些硬件**只能作为计算机的一部分存在**,不能脱离计算机单独使用。同时,CPU 有自己的属性和行为,内存也有自己的属性和行为。
|
|
|
|
|
+
|
|
|
|
|
+请使用 **内部类** 来设计这个计算机硬件体系。
|
|
|
|
|
+
|
|
|
|
|
+### 类设计
|
|
|
|
|
+
|
|
|
|
|
+#### Computer 类(外部类)
|
|
|
|
|
+
|
|
|
|
|
+| 成员 | 说明 |
|
|
|
|
|
+|------|------|
|
|
|
|
|
+| 私有属性 | `brand`(品牌,String)、`model`(型号,String) |
|
|
|
|
|
+| 构造方法 | `Computer(String brand, String model)` |
|
|
|
|
|
+| 方法 | `void showInfo()` —— 输出 `"计算机:xxx 品牌:xxx"` |
|
|
|
|
|
+| 方法 | `void startComputer()` —— 输出启动信息,依次调用 CPU 和 Memory 的方法 |
|
|
|
|
|
+| 方法 | `CPU getCPU()` —— 返回 CPU 对象 |
|
|
|
|
|
+| 方法 | `Memory getMemory()` —— 返回 Memory 对象 |
|
|
|
|
|
+
|
|
|
|
|
+#### CPU 内部类(成员内部类——不私有化)
|
|
|
|
|
+
|
|
|
|
|
+| 成员 | 说明 |
|
|
|
|
|
+|------|------|
|
|
|
|
|
+| 私有属性 | `name`(型号,String)、`frequency`(主频,double) |
|
|
|
|
|
+| 构造方法 | `CPU(String name, double frequency)` |
|
|
|
|
|
+| 方法 | `void calculate()` —— 输出 `"计算机 xxx xxx 的 CPU xxx(xxx GHz)正在计算..."`(访问外部类私有属性) |
|
|
|
|
|
+| 方法 | `void showCPUInfo()` —— 输出 `"CPU:xxx,主频:xxx GHz"` |
|
|
|
|
|
+
|
|
|
|
|
+#### Memory 内部类(私有内部类)
|
|
|
|
|
+
|
|
|
|
|
+| 成员 | 说明 |
|
|
|
|
|
+|------|------|
|
|
|
|
|
+| 私有属性 | `capacity`(容量,int,单位 GB) |
|
|
|
|
|
+| 构造方法 | `Memory(int capacity)` |
|
|
|
|
|
+| 方法 | `void readData()` —— 输出 `"内存(xxx GB)正在读取数据..."` |
|
|
|
|
|
+| 方法 | `void writeData()` —— 输出计算机信息 + `"内存(xxx GB)正在写入数据..."`(调用外部类 `showInfo()`) |
|
|
|
|
|
+
|
|
|
|
|
+### 测试类要求
|
|
|
|
|
+
|
|
|
|
|
+**`TestComputer` 类**:
|
|
|
|
|
+
|
|
|
|
|
+1. 创建 `Computer` 对象("联想", "ThinkPad X1"),构造方法中创建 CPU("酷睿 i7", 3.2)和 Memory(16)
|
|
|
|
|
+2. 调用 `computer.showInfo()`
|
|
|
|
|
+3. 通过 `computer.getCPU()` 获取 CPU,调用 `showCPUInfo()` 和 `calculate()`
|
|
|
|
|
+4. 尝试直接创建 `Memory` 对象(应编译报错,验证私有内部类限制)
|
|
|
|
|
+5. 通过 `computer.getMemory()` 获取 Memory,调用 `readData()` 和 `writeData()`
|
|
|
|
|
+6. 调用 `computer.startComputer()` 完整启动流程
|
|
|
|
|
+
|
|
|
|
|
+```java
|
|
|
|
|
+// 这行应编译报错——Memory 是 Computer 的私有内部类
|
|
|
|
|
+// Memory mem = new Memory(16); // ❌
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 思考题
|
|
|
|
|
+
|
|
|
|
|
+1. 为什么 Memory 要设计为 `private` 内部类?如果改为非私有会怎样?
|
|
|
|
|
+2. CPU 内部类直接访问外部类 `private` 属性,这说明了内部类的什么特点?
|
|
|
|
|
+3. 如果将 CPU 改为 `static class CPU`,还能直接访问外部类的 `brand` 和 `model` 吗?为什么?
|
|
|
|
|
+
|
|
|
|
|
+### 预期输出
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+========== 计算机信息 ==========
|
|
|
|
|
+计算机:ThinkPad X1 品牌:联想
|
|
|
|
|
+
|
|
|
|
|
+========== 获取 CPU ==========
|
|
|
|
|
+CPU:酷睿 i7,主频:3.2 GHz
|
|
|
|
|
+计算机 联想 ThinkPad X1 的 CPU 酷睿 i7(3.2 GHz)正在计算...
|
|
|
|
|
+
|
|
|
|
|
+========== 获取内存 ==========
|
|
|
|
|
+内存(16 GB)正在读取数据...
|
|
|
|
|
+计算机:ThinkPad X1 品牌:联想
|
|
|
|
|
+内存(16 GB)正在写入数据...
|
|
|
|
|
+
|
|
|
|
|
+========== 启动计算机 ==========
|
|
|
|
|
+计算机启动中...
|
|
|
|
|
+计算机 联想 ThinkPad X1 的 CPU 酷睿 i7(3.2 GHz)正在计算...
|
|
|
|
|
+内存(16 GB)正在读取数据...
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 📋 题目总览
|
|
|
|
|
+
|
|
|
|
|
+| 题号 | 名称 | 核心知识点 | 难度 |
|
|
|
|
|
+|------|------|-----------|------|
|
|
|
|
|
+| 第 1 题 | 动物园导游系统 | 抽象类、多态、向上转型/向下转型、instanceof、调用子类特有方法 | ⭐⭐⭐ |
|
|
|
|
|
+| 第 2 题 | 智能家居控制系统 | 接口多态、多态参数、多态数组、开闭原则 | ⭐⭐⭐ |
|
|
|
|
|
+| 第 3 题 | 计算机硬件体系 | 成员内部类、私有内部类、内部类访问外部类私有成员 | ⭐⭐⭐ |
|