Browse Source

feat: 新增20260723课后作业——Printer打印机体系(抽象类+接口)和Notification通知体系(接口JDK8默认方法/静态方法)

WanJL 1 day ago
parent
commit
d4ee20981a
1 changed files with 225 additions and 0 deletions
  1. 225 0
      课后作业/2026年7月23日-作业.md

+ 225 - 0
课后作业/2026年7月23日-作业.md

@@ -0,0 +1,225 @@
+# 2026-07-23 JavaSE 课后作业
+
+> **课程内容**:抽象类(abstract)、final 关键字、模板方法设计模式、代码块(局部/构造/静态)、接口(Interface)、接口 JDK8+ 新特性(默认方法/静态方法/私有方法)
+>
+> **涉及前序知识**:继承、构造方法、方法重写、多态、封装
+>
+> **提交方式**:在 `提交\姓名\` 目录下创建对应的 Java 源文件
+>
+> **截止时间**:下次上课前
+
+---
+
+## 📌 本次作业重要说明
+
+### 命名要求
+
+| 项目 | 要求 |
+|------|------|
+| **包名** | **必须按题目指定的包名创建**(全小写) |
+| **类名** | 自由命名,但需**见名知意**(如实体类用 `Printer`、`EmailNotifier` 等均可) |
+| **测试类** | 建议命名为 `TestXxx` 或 `XxxTest` |
+| **文件名** | 必须与类名一致 |
+
+### 提交目录结构示例
+
+```
+提交\
+└─ 张三\
+    ├─ p1_printer\              ← 第 1 题的包
+    │   ├─ Printer.java           ← 抽象父类
+    │   ├─ Connectable.java       ← 接口
+    │   ├─ LaserPrinter.java      ← 子类(继承 + 实现)
+    │   ├─ InkjetPrinter.java     ← 子类(继承 + 实现)
+    │   └─ TestPrinter.java       ← 测试类
+    └─ p2_notification\          ← 第 2 题的包
+        ├─ Notifiable.java        ← 接口(含默认方法)
+        ├─ EmailNotifier.java     ← 实现类
+        ├─ SMSNotifier.java       ← 实现类
+        └─ TestNotification.java ← 测试类
+```
+
+> ⚠ **注意**:包名必须严格按题目要求书写(全小写),目录结构必须与包结构一致。
+
+---
+
+## 第 1 题:抽象类 + 接口——Printer 打印机体系 ⭐⭐
+
+**包名**:`p1_printer`
+
+**知识点**:抽象类定义与使用、接口定义与实现、类同时继承抽象类并实现接口、方法重写、多态
+
+### 需求说明
+
+某公司需要开发一个打印机管理系统。不同类型的打印机有 **共有的属性**(品牌、型号),也有 **共同的连接规范**(连接、打印、关闭)。请使用 **抽象类 + 接口** 来设计这个体系。
+
+### 类设计
+
+#### Connectable 接口
+- **抽象方法**:`void connect()` —— 连接设备
+- **抽象方法**:`void print(String content)` —— 执行打印(参数为待打印内容)
+- **抽象方法**:`void close()` —— 关闭设备
+
+#### Printer 抽象类
+- **私有属性**:`brand`(品牌,String)、`model`(型号,String)
+- **有参构造方法**:`Printer(String brand, String model)`
+- **getter/setter**
+- **普通方法**:`showInfo()` —— 输出 `"打印机:xxx 品牌:xxx"`(xxx 为型号和品牌)
+- **抽象方法**:`void maintenance()` —— 维护保养(不同打印机保养方式不同)
+
+#### LaserPrinter 类(激光打印机)
+- **继承** `Printer` 抽象类,**实现** `Connectable` 接口
+- **新增私有属性**:`tonerLevel`(碳粉余量,int,百分比 0~100)
+- **构造方法**:`LaserPrinter(String brand, String model, int tonerLevel)`
+- **实现** `connect()` —— 输出 `"激光打印机已连接"`
+- **实现** `print(String content)` —— 输出 `"激光打印机打印:xxx"`(xxx 为 content)
+- **实现** `close()` —— 输出 `"激光打印机已关闭"`
+- **重写** `maintenance()` —— 输出 `"激光打印机保养:检查碳粉,当前余量:xxx%"`
+
+#### InkjetPrinter 类(喷墨打印机)
+- **继承** `Printer` 抽象类,**实现** `Connectable` 接口
+- **新增私有属性**:`inkLevel`(墨水余量,int,百分比 0~100)
+- **构造方法**:`InkjetPrinter(String brand, String model, int inkLevel)`
+- **实现** `connect()` —— 输出 `"喷墨打印机已连接"`
+- **实现** `print(String content)` —— 输出 `"喷墨打印机打印:xxx"`
+- **实现** `close()` —— 输出 `"喷墨打印机已关闭"`
+- **重写** `maintenance()` —— 输出 `"喷墨打印机保养:检查墨水,当前余量:xxx%"`
+
+### 测试类要求
+
+**`TestPrinter` 类**(置于 `p1_printer` 包下):
+
+1. 创建 `LaserPrinter` 对象(品牌:"惠普",型号:"HP1010",碳粉余量:80)
+2. 创建 `InkjetPrinter` 对象(品牌:"爱普生",型号:"L3153",墨水余量:60)
+3. 调用每个对象的 `showInfo()` 方法
+4. 调用每个对象的 `connect()` → `print("Hello World")` → `close()` 三步操作
+5. 调用每个对象的 `maintenance()` 方法
+
+### 思考题(不需编码,口头回答)
+
+1. 如果把 `Connectable` 改为抽象类,让 `LaserPrinter` 直接继承它,会出现什么问题?(提示:Java 的单继承限制)
+2. `Printer` 中使用抽象方法 `maintenance()` 的好处是什么?能否用普通方法代替?
+3. `showInfo()` 方法是在抽象类中定义的普通方法,它在测试时表现出了什么特性?
+
+### 预期输出
+
+```
+========== 激光打印机 ==========
+打印机:HP1010 品牌:惠普
+激光打印机已连接
+激光打印机打印:Hello World
+激光打印机已关闭
+激光打印机保养:检查碳粉,当前余量:80%
+
+========== 喷墨打印机 ==========
+打印机:L3153 品牌:爱普生
+喷墨打印机已连接
+喷墨打印机打印:Hello World
+喷墨打印机已关闭
+喷墨打印机保养:检查墨水,当前余量:60%
+```
+
+> 💡 **提示**:
+> - 子类构造方法中要调用 `super(brand, model)` 初始化父类属性
+> - 实现接口时使用 `implements` 关键字,继承抽象类时使用 `extends` 关键字,两者用逗号分隔:`extends Printer implements Connectable`
+> - 抽象类 Printer 中的 `maintenance()` 和接口 Connectable 中的三个方法 **都需要重写**
+
+---
+
+## 第 2 题:接口 + JDK8 默认方法——Notification 通知体系 ⭐⭐⭐
+
+**包名**:`p2_notification`
+
+**知识点**:接口定义、接口 JDK8 默认方法(default)、接口 JDK8 静态方法(static)、实现类重写抽象方法、通过接口名调用静态方法
+
+### 需求说明
+
+某系统需要发送多种类型的通知(邮件、短信、微信)。每种通知的 **发送逻辑不同**,但 **发送前需要校验参数**、**发送后需要记录日志**,这部分是公共行为。请使用 **接口 + JDK8 默认方法** 来设计。
+
+### 接口设计
+
+#### Notifiable 接口
+
+**抽象方法**(实现类必须重写):
+- `void doSend(String recipient, String message)` —— 执行具体的发送逻辑
+
+**默认方法**(JDK8,不强制重写,实现类可直接继承使用):
+- `default boolean validateParams(String recipient, String message)` —— 校验参数
+  - 如果 `recipient` 或 `message` 为 `null` 或空字符串,输出 `"参数校验失败:收件人或消息不能为空"`,返回 `false`
+  - 否则输出 `"参数校验通过"`,返回 `true`
+
+- `default void log(String level, String msg)` —— 记录日志
+  - 输出 `"[等级] 消息:内容"`(例如:`"[INFO] 消息:邮件发送成功"`)
+
+- `default void send(String recipient, String message)` —— **模板方法**(`final` 不能用在接口方法中,所以此处用 default 模拟)
+  - 步骤①:调用 `validateParams(recipient, message)` 校验参数,如果返回 `false` 则直接结束
+  - 步骤②:调用 `doSend(recipient, message)` 执行具体发送
+  - 步骤③:调用 `log("INFO", "发送成功")` 记录日志
+  - 步骤④:输出 `"--- 发送流程结束 ---"`
+
+**静态方法**(JDK8,通过 `接口名.方法名()` 调用):
+- `static void printNotificationType()` —— 输出 `"通知系统 v1.0——支持邮件/短信/微信通知"`
+
+### 实现类要求
+
+#### EmailNotifier 类(实现 Notifiable)
+- **实现** `doSend(String recipient, String message)` —— 输出 `"发送邮件给 xxx:内容 - yyy"`(xxx 为 recipient,yyy 为 message)
+- **可选重写** `log(String level, String msg)` —— 输出 `"[邮件][等级] 消息:内容"`
+
+#### SMSNotifier 类(实现 Notifiable)
+- **实现** `doSend(String recipient, String message)` —— 输出 `"发送短信给 xxx:内容 - yyy"`
+- 默认方法 `log()` 和 `validateParams()` **不重写**,直接继承接口的默认实现
+
+### 测试类要求
+
+**`TestNotification` 类**(置于 `p2_notification` 包下):
+
+1. 调用 `Notifiable.printNotificationType()` 输出系统信息(静态方法调用)
+2. 创建 `EmailNotifier` 对象,分别测试:
+   - 调用 `send("admin@example.com", "系统升级通知")` —— 正常发送
+   - 调用 `send("", "测试")` —— 参数为空,应校验失败
+3. 创建 `SMSNotifier` 对象,测试:
+   - 调用 `send("13800138000", "您的验证码是1234")` —— 正常发送
+
+### 思考题(不需编码,口头回答)
+
+1. 接口中的 `send()` 方法为什么不能像模板方法模式一样用 `final` 修饰?如果想让子类不能修改发送流程,有什么替代方案?
+2. `EmailNotifier` 重写了 `log()` 方法,而 `SMSNotifier` 没有重写。测试时两者的日志输出有什么不同?这体现了接口默认方法的什么特性?
+3. 接口中的静态方法 `printNotificationType()` 能否通过实现类对象调用?为什么?
+
+### 预期输出
+
+```
+通知系统 v1.0——支持邮件/短信/微信通知
+
+========== 邮件通知(正常) ==========
+参数校验通过
+发送邮件给 admin@example.com:内容 - 系统升级通知
+[邮件][INFO] 消息:发送成功
+--- 发送流程结束 ---
+
+========== 邮件通知(参数为空) ==========
+参数校验失败:收件人或消息不能为空
+
+========== 短信通知 ==========
+参数校验通过
+发送短信给 13800138000:内容 - 您的验证码是1234
+[INFO] 消息:发送成功
+--- 发送流程结束 ---
+```
+
+> 💡 **提示**:
+> - 接口中的方法默认是 `public`,实现类重写时也必须用 `public`
+> - 默认方法用 `default` 关键字修饰,可以有方法体
+> - 静态方法用 `static` 修饰,必须通过 `接口名.静态方法名()` 调用
+> - 默认方法和静态方法都是 JDK8 新增的特性
+> - `String` 类型判断空或空字符串:`recipient == null || recipient.isEmpty()`
+
+---
+
+## 📋 题目总览
+
+| 序号 | 包名 | 核心知识点 | 难度 |
+|------|------|-----------|------|
+| 第 1 题 | `p1_printer` | 抽象类定义与使用、接口定义与实现、类同时继承抽象类并实现接口、方法重写 | ⭐⭐ |
+| 第 2 题 | `p2_notification` | 接口定义、JDK8 默认方法(default)、JDK8 静态方法(static)、模拟模板方法、方法重写 vs 默认继承 | ⭐⭐⭐ |