|
|
@@ -0,0 +1,257 @@
|
|
|
+# 2026-07-27 JavaSE 课后作业
|
|
|
+
|
|
|
+> **课程内容**:匿名内部类(Anonymous Inner Class)、Java API(String / StringBuffer / StringBuilder / Math / LocalDate / LocalTime / LocalDateTime / DateTimeFormatter)
|
|
|
+>
|
|
|
+> **涉及前序知识**:接口、抽象类、继承、封装、构造方法、方法重写
|
|
|
+>
|
|
|
+> **提交方式**:在 `提交\姓名\` 目录下创建对应的 Java 源文件
|
|
|
+>
|
|
|
+> **截止时间**:下次上课前
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 📌 本次作业重要说明
|
|
|
+
|
|
|
+### 命名要求
|
|
|
+
|
|
|
+| 项目 | 要求 |
|
|
|
+|------|------|
|
|
|
+| **包名** | **必须按题目指定的包名创建**(全小写) |
|
|
|
+| **类名** | 自由命名,但需**见名知意** |
|
|
|
+| **测试类** | 建议命名为 `TestXxx` 或 `XxxTest` |
|
|
|
+| **文件名** | 必须与类名一致 |
|
|
|
+
|
|
|
+### 提交目录结构示例
|
|
|
+
|
|
|
+```
|
|
|
+提交\
|
|
|
+└─ 张三\
|
|
|
+ ├─ p1_payment\ ← 第 1 题的包
|
|
|
+ │ ├─ Payment.java ← 接口
|
|
|
+ │ ├─ OrderService.java ← 业务类
|
|
|
+ │ └─ TestPayment.java ← 测试类(匿名内部类)
|
|
|
+ ├─ p2_stringtool\ ← 第 2 题的包
|
|
|
+ │ └─ StringUtilTest.java ← 测试类(String / StringBuilder)
|
|
|
+ └─ p3_datamath\ ← 第 3 题的包
|
|
|
+ └─ DataMathTest.java ← 测试类(Math / 日期时间)
|
|
|
+```
|
|
|
+
|
|
|
+> ⚠ **注意**:包名必须严格按题目要求书写(全小写),目录结构必须与包结构一致。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 第 1 题:匿名内部类——支付系统 ⭐⭐⭐
|
|
|
+
|
|
|
+**包名**:`p1_payment`
|
|
|
+
|
|
|
+**知识点**:接口定义、匿名内部类(变量赋值 / 方法参数传递 / 匿名对象直接调用)、匿名内部类继承普通类
|
|
|
+
|
|
|
+### 需求说明
|
|
|
+
|
|
|
+某电商平台需要开发一个**支付系统**。不同的支付方式(微信支付、支付宝支付、银行卡支付)支付流程不同,但都遵循统一的规范:**支付 → 退款**。请使用 **匿名内部类** 来实现不同的支付方式,要求每种支付方式**不创建独立的实现类文件**。
|
|
|
+
|
|
|
+### 接口设计
|
|
|
+
|
|
|
+#### Payment 接口
|
|
|
+
|
|
|
+| 方法 | 说明 |
|
|
|
+|------|------|
|
|
|
+| `void pay(double amount)` | 支付,amount 为支付金额 |
|
|
|
+| `void refund(double amount)` | 退款,amount 为退款金额 |
|
|
|
+
|
|
|
+### 业务类设计
|
|
|
+
|
|
|
+#### OrderService 类
|
|
|
+
|
|
|
+| 成员 | 说明 |
|
|
|
+|------|------|
|
|
|
+| 方法 | `void processPayment(Payment payment, double amount)` |
|
|
|
+| 行为 | 先调用 `payment.pay(amount)`,再模拟处理(输出处理中...),再调用 `payment.refund(amount * 0.1)` — 退款 10% |
|
|
|
+
|
|
|
+### 测试类要求
|
|
|
+
|
|
|
+**`TestPayment` 类**(测试类,含 main 方法),要求通过 **匿名内部类** 实现以下功能:
|
|
|
+
|
|
|
+1. **方式一(变量赋值)**:创建 Payment 的匿名内部类对象,实现**微信支付**:
|
|
|
+ - `pay()` 输出:`"微信支付:已支付 xxx 元"`
|
|
|
+ - `refund()` 输出:`"微信支付:已退款 xxx 元"`
|
|
|
+ - 通过变量调用 pay() 和 refund()
|
|
|
+
|
|
|
+2. **方式二(方法参数传递)**:直接创建匿名内部类作为 `processPayment` 方法的参数,实现**支付宝支付**:
|
|
|
+ - `pay()` 输出:`"支付宝支付:已支付 xxx 元"`
|
|
|
+ - `refund()` 输出:`"支付宝支付:已退款 xxx 元"`
|
|
|
+
|
|
|
+3. **方式三(匿名对象直接调用)**:在匿名内部类中定义**特有方法** `showBonus()`,输出 `"银行卡支付:本次消费赠送 10 积分"`,然后通过匿名对象直接调用 `showBonus()`:
|
|
|
+ - 需同时实现 `pay()` 和 `refund()` 方法
|
|
|
+ - `pay()` 输出:`"银行卡支付:已支付 xxx 元"`
|
|
|
+ - `refund()` 输出:`"银行卡支付:已退款 xxx 元"`
|
|
|
+ - 最后通过 `.showBonus()` 直接调用特有方法
|
|
|
+
|
|
|
+4. **额外挑战(选做)**:模拟**继承普通类的匿名内部类**——创建一个 `String` 或 `Object` 的匿名内部类子类,重写 `toString()` 方法返回 `"这是匿名内部类继承普通类的示例"`,并打印输出。
|
|
|
+
|
|
|
+### 参考执行效果
|
|
|
+
|
|
|
+```
|
|
|
+微信支付:已支付 199.0 元
|
|
|
+微信支付:已退款 19.9 元
|
|
|
+--- 分割线 ---
|
|
|
+支付宝支付:已支付 299.0 元
|
|
|
+支付宝支付:已退款 29.9 元
|
|
|
+--- 分割线 ---
|
|
|
+银行卡支付:已支付 99.0 元
|
|
|
+银行卡支付:已退款 9.9 元
|
|
|
+银行卡支付:本次消费赠送 10 积分
|
|
|
+--- 分割线(选做) ---
|
|
|
+这是匿名内部类继承普通类的示例
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 第 2 题:String + StringBuilder——字符串处理工具 ⭐⭐
|
|
|
+
|
|
|
+**包名**:`p2_stringtool`
|
|
|
+
|
|
|
+**知识点**:String 常用方法(split / substring / contains / replace / join / trim / equalsIgnoreCase)、StringBuilder 的 append / toString、String 不可变性
|
|
|
+
|
|
|
+### 需求说明
|
|
|
+
|
|
|
+开发一个**字符串处理工具**,对给定的学生信息字符串进行各种处理操作。
|
|
|
+
|
|
|
+### 测试类要求
|
|
|
+
|
|
|
+**`StringUtilTest` 类**(测试类,含 main 方法),要求实现以下功能:
|
|
|
+
|
|
|
+#### 准备数据
|
|
|
+
|
|
|
+```java
|
|
|
+String data = " 张三, 李四, 王五, 赵六, 张三, 钱七 ";
|
|
|
+String names = "张三,李四,王五,赵六,钱七";
|
|
|
+```
|
|
|
+
|
|
|
+#### 功能要求
|
|
|
+
|
|
|
+1. **去重处理**:将 `data` 按逗号分割成字符串数组,去除每个姓名前后的空格(使用 `trim()`),然后统计每个姓名出现的次数。输出格式:
|
|
|
+ ```
|
|
|
+ 张三:2 次
|
|
|
+ 李四:1 次
|
|
|
+ 王五:1 次
|
|
|
+ 赵六:1 次
|
|
|
+ 钱七:1 次
|
|
|
+ ```
|
|
|
+
|
|
|
+2. **关键词搜索**:使用 `contains()` 判断 `names` 中是否包含 "张三",使用 `indexOf()` 查找 "王五" 的位置,使用 `startsWith()` 和 `endsWith()` 判断是否以特定字符开头/结尾。输出格式:
|
|
|
+ ```
|
|
|
+ 是否包含张三:true
|
|
|
+ 王五的位置:4
|
|
|
+ 是否以"张"开头:true
|
|
|
+ 是否以"七"结尾:true
|
|
|
+ ```
|
|
|
+
|
|
|
+3. **子串提取 + 替换**:从 `names` 中提取前三个姓名("张三,李四,王五"),然后将 "王五" 替换为 "周八"。输出格式:
|
|
|
+ ```
|
|
|
+ 提取的前三个姓名:张三,李四,王五
|
|
|
+ 替换后:张三,李四,周八,赵六,钱七
|
|
|
+ ```
|
|
|
+
|
|
|
+4. **StringBuilder 拼接(核心)**:使用 `StringBuilder` 从头构建一个 HTML 格式的学生列表。要求:
|
|
|
+ - 从 `names` 中 `split()` 出每个姓名
|
|
|
+ - 使用 `StringBuilder` 的 `append()` 方法逐条拼接
|
|
|
+ - 最后转换为 String 输出
|
|
|
+ ```
|
|
|
+ <ul>
|
|
|
+ <li>张三</li>
|
|
|
+ <li>李四</li>
|
|
|
+ <li>王五</li>
|
|
|
+ <li>赵六</li>
|
|
|
+ <li>钱七</li>
|
|
|
+ </ul>
|
|
|
+ ```
|
|
|
+
|
|
|
+5. **String.join 拼接**:使用 `String.join()` 将姓名数组用 `" | "` 连接起来输出:
|
|
|
+ ```
|
|
|
+ 姓名列表:张三 | 李四 | 王五 | 赵六 | 钱七
|
|
|
+ ```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 第 3 题:Math + 日期时间——数据分析小工具 ⭐⭐
|
|
|
+
|
|
|
+**包名**:`p3_datamath`
|
|
|
+
|
|
|
+**知识点**:Math 类(PI / pow / sqrt / ceil / floor / round / random / abs / max / min)、LocalDate / LocalTime / LocalDateTime / DateTimeFormatter
|
|
|
+
|
|
|
+### 需求说明
|
|
|
+
|
|
|
+开发一个**数据分析小工具**,结合 Math 类和日期时间 API 完成一些实用功能。
|
|
|
+
|
|
|
+### 测试类要求
|
|
|
+
|
|
|
+**`DataMathTest` 类**(测试类,含 main 方法),要求实现以下功能:
|
|
|
+
|
|
|
+#### 1. Math 数学计算
|
|
|
+
|
|
|
+```java
|
|
|
+// 准备数据
|
|
|
+double radius = 5.0; // 半径
|
|
|
+double base = 2.0; // 底数
|
|
|
+double exponent = 10.0; // 指数
|
|
|
+double[] scores = {85.5, 92.3, 78.8, 88.0, 95.5}; // 成绩数组
|
|
|
+```
|
|
|
+
|
|
|
+| 编号 | 功能 | 要求 | 示例输出 |
|
|
|
+|------|------|------|---------|
|
|
|
+| 1.1 | 计算圆的面积 | 使用 `Math.PI` 和 `Math.pow()` | 圆的面积:78.53981633974483 |
|
|
|
+| 1.2 | 计算圆的周长 | 使用 `Math.PI` | 圆的周长:31.41592653589793 |
|
|
|
+| 1.3 | 计算 2¹⁰ | 使用 `Math.pow()` | 2 的 10 次方:1024.0 |
|
|
|
+| 1.4 | 计算 √16 | 使用 `Math.sqrt()` | 16 的平方根:4.0 |
|
|
|
+| 1.5 | 成绩统计 | 使用 `Math.max()` 和 `Math.min()` 找出最高分和最低分 | 最高分:95.5,最低分:78.8 |
|
|
|
+| 1.6 | 平均分取整 | 计算平均分后分别用 `ceil()` / `floor()` / `round()` 取整 | 平均分:88.02,向上取整:89.0,向下取整:88.0,四舍五入:88 |
|
|
|
+| 1.7 | 生成随机验证码 | 使用 `Math.random()` 生成一个 6 位随机数字验证码(每位 0-9) | 验证码:483591 |
|
|
|
+| 1.8 | 绝对值应用 | 计算温差:昨天温度 25℃,今天温度 18℃,用 `abs()` 求温差绝对值 | 温差:7℃ |
|
|
|
+
|
|
|
+#### 2. 日期时间处理
|
|
|
+
|
|
|
+| 编号 | 功能 | 要求 | 示例输出 |
|
|
|
+|------|------|------|---------|
|
|
|
+| 2.1 | 获取当前日期 | 使用 `LocalDate.now()` | 当前日期:2026-07-27 |
|
|
|
+| 2.2 | 创建指定日期 | 使用 `LocalDate.of()` 创建 2025-01-01 | 指定日期:2025-01-01 |
|
|
|
+| 2.3 | 计算天数差 | 计算当前日期距离 2026-12-31 还有多少天(用 `until()` 或 `toEpochDay()`) | 距离 2026-12-31 还有:157 天 |
|
|
|
+| 2.4 | 日期加减 | 当前日期加 100 天、减 30 天 | 100 天后:2026-11-04,30 天前:2026-06-27 |
|
|
|
+| 2.5 | 获取当前时间 | 使用 `LocalTime.now()`,输出当前时间 | 当前时间:14:30:25.123 |
|
|
|
+| 2.6 | 指定时间 | 使用 `LocalTime.of()` 创建上课时间 08:30:00 | 上课时间:08:30 |
|
|
|
+| 2.7 | 格式化日期时间 | 使用 `LocalDateTime.now()` + `DateTimeFormatter.ofPattern()`,格式为 `"yyyy年MM月dd日 HH时mm分ss秒"` | 当前日期时间:2026年07月27日 14时30分25秒 |
|
|
|
+
|
|
|
+#### 3. 综合应用(选做)
|
|
|
+
|
|
|
+结合 Math 和 LocalDate,生成一个**随机日期**:
|
|
|
+- 使用 `Math.random()` 生成随机的年(2020~2026)、月(1~12)、日(1~28)
|
|
|
+- 使用 `LocalDate.of()` 创建该日期
|
|
|
+- 判断该日期是星期几
|
|
|
+- 输出格式:`"随机日期:2023-05-15,是星期一"`
|
|
|
+
|
|
|
+### 参考执行效果
|
|
|
+
|
|
|
+```
|
|
|
+===== Math 数学计算 =====
|
|
|
+圆的面积:78.53981633974483
|
|
|
+圆的周长:31.41592653589793
|
|
|
+2 的 10 次方:1024.0
|
|
|
+16 的平方根:4.0
|
|
|
+最高分:95.5,最低分:78.8
|
|
|
+平均分:88.02,向上取整:89.0,向下取整:88.0,四舍五入:88
|
|
|
+验证码:483591
|
|
|
+温差:7℃
|
|
|
+
|
|
|
+===== 日期时间处理 =====
|
|
|
+当前日期:2026-07-27
|
|
|
+指定日期:2025-01-01
|
|
|
+距离 2026-12-31 还有:157 天
|
|
|
+100 天后:2026-11-04
|
|
|
+30 天前:2026-06-27
|
|
|
+当前时间:14:30:25.123
|
|
|
+上课时间:08:30
|
|
|
+当前日期时间:2026年07月27日 14时30分25秒
|
|
|
+
|
|
|
+===== 综合应用(选做) =====
|
|
|
+随机日期:2023-05-15,是星期一
|
|
|
+```
|