Sfoglia il codice sorgente

docs: 更新20260724课堂笔记,同步homework目录新增作业题目文档——Notifiable通知体系课后作业要求(含SMSNotifier、思考题、预期输出)

WanJL 19 ore fa
parent
commit
17739d2ba5

+ 92 - 0
授课代码/c260724/src/homework/题目.md

@@ -0,0 +1,92 @@
+# 2026-07-23 JavaSE 课后作业
+
+## 第 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()`
+
+---

+ 12 - 1
课堂笔记/01-JavaSE基础-笔记/20260724-笔记.md

@@ -421,6 +421,17 @@ public class TestNotification {
 ```
 > 📄 来源:`TestNotification.java`
 
+### 5.4 作业题目文档
+
+课后作业的完整题目要求、预期输出及思考题已整理为独立文档:
+
+📄 **`homework/题目.md`** → [查看作业题目](../../授课代码/c260724/src/homework/题目.md)
+
+该文档包含:
+- 完整的接口设计与实现类要求(含 `SMSNotifier` 短信通知实现)
+- 详细的预期输出对照
+- 3 道思考题(final 与接口方法的限制、默认方法重写的意义、静态方法调用方式)
+
 ---
 
 ## 六、随堂练习要点
@@ -431,7 +442,7 @@ public class TestNotification {
 | 多态中的转型 | 向上转型、向下转型、instanceof 运算符 | `Demo02.java`、`Test03.java` |
 | 抽象类多态综合 | 抽象父类 Person、多态参数、向下转型调特有方法 | `Test03.java`、`Person.java` |
 | 接口多态 | Usb 接口、笔记本接入多设备 | `Test02.java`、`NoteBook.java` |
-| 通知系统(作业) | 接口默认方法、静态方法、模板方法设计模式 | 作业包 `homework` |
+| 通知系统(作业) | 接口默认方法、静态方法、模板方法设计模式 | 作业包 `homework` + [`题目.md`](../../授课代码/c260724/src/homework/题目.md) |
 
 ---