From 6055908ccd2d7c305754c63350bae6a0b5707daf Mon Sep 17 00:00:00 2001 From: Songrui <1778280163@qq.com> Date: Mon, 23 Mar 2026 20:13:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8B=E7=91=9E-202506050301?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- w3/作业/AI交互记录.md | 68 +++++++++ w3/作业/Car.java | 240 ++++++++++++++++++++++++++++++ w3/课堂练习/AI交互记录.md | 60 ++++++++ w3/课堂练习/BankAccount.java | 84 +++++++++++ w3/课堂练习/Main.java | 45 ++++++ 5 files changed, 497 insertions(+) create mode 100644 w3/作业/AI交互记录.md create mode 100644 w3/作业/Car.java create mode 100644 w3/课堂练习/AI交互记录.md create mode 100644 w3/课堂练习/BankAccount.java create mode 100644 w3/课堂练习/Main.java diff --git a/w3/作业/AI交互记录.md b/w3/作业/AI交互记录.md new file mode 100644 index 0000000..91855f0 --- /dev/null +++ b/w3/作业/AI交互记录.md @@ -0,0 +1,68 @@ +# AI 交互记录 - 车辆实体类 Car 开发 + +## 一、需求分析 + +### 实验要求 +1. 实现完整的封装 +2. 构造方法重载(多个构造方法) +3. 熟练使用 this 关键字 +4. 培养数据校验意识 +5. 代码简洁明了,有注释 + +### 功能需求 +- 包含车辆基本信息(品牌、型号、年份、价格、颜色、车牌号) +- 提供多种创建对象的方式 +- 对外提供安全的访问接口 +- 对输入数据进行有效性验证 + +--- + +## 二、AI 交互过程 + +### 第一轮:代码编写请求 + +**用户提问**: +> 实现一个封装完整的实体类一一车辆管理系统中的 Car 类。 +> 根据以上要求和信息帮我写一份 Java 文件,要求简洁明了,且有注释 + +**AI 响应要点**: + +#### 1. 类结构设计 +public class Car { // 私有属性 - 封装的核心 private String brand; // 品牌 private String model; // 型号 private int year; // 生产年份 private double price; // 价格 private String color; // 颜色 private String licensePlate; // 车牌号 } +#### 2. 构造方法重载(3 个) +- **无参构造**:提供默认值 +- **简化版构造**(3 参数):brand, model, price +- **全参构造**(6 参数):所有属性 + +#### 3. this 关键字的三种用法 +// 用法 1:区分成员变量和局部变量 this.brand = brand; +// 用法 2:构造方法之间互相调用 public Car(String brand, String model, double price) { this(brand, model, 2026, price, "标准色", "待上牌"); } +// 用法 3:在 setter 中返回当前对象(可选) +#### 4. 数据校验实现 +// 年份校验:1900-2026 public void setYear(int year) { if (year >= 1900 && year <= 2026) { this.year = year; } else { System.out.println("错误:年份必须在 1900-2026 之间!"); this.year = 2026; } } +// 价格校验:必须大于 0 public void setPrice(double price) { if (price > 0) { this.price = price; } else { System.out.println("错误:价格必须大于 0!"); this.price = 0.0; } } +// 字符串校验:不能为空 public void setBrand(String brand) { if (brand != null && !brand.trim().isEmpty()) { this.brand = brand; } else { System.out.println("错误:品牌名称不能为空!"); } } +#### 5. 测试代码设计 +AI 提供了 5 组测试用例: +- 测试 1:无参构造方法 +- 测试 2:简化版构造方法 +- 测试 3:全参构造方法 +- 测试 4:修改车辆信息(使用 setter) +- 测试 5:数据校验测试(故意传入非法值) + +--- + +### 第二轮:代码审查询问 + +**用户提问**: +> 我的类是否满足封装原则?有哪些改进建议? + +**AI审查结果**: + +#### 已满足的封装原则 +#### 💡 改进建议 +##### 建议 1:增强数据校验 +// 建议:更严格的业务规则校验 public void setYear(int year) { int currentYear = java.time.Year.now().getValue(); if (year >= 1900 && year <= currentYear) { this.year = year; } else { throw new IllegalArgumentException( "年份必须在 1900-" + currentYear + "之间,当前值为:" + year ); } } +##### 建议 2:添加不可变字段的考虑 +// 如果某些属性创建后不应该修改,可以设为 final private final String licensePlate; // 车牌号一旦分配不应修改 +// 对应的 setter 可以移除或添加限制逻辑 public void setLicensePlate(String licensePlate) { if (this.licensePlate.equals("未上牌") || this.licensePlate.equals("待上牌")) { this.licensePlate = licensePlate; } else { System.out.println("错误:车牌号已分配,不能修改!"); } } \ No newline at end of file diff --git a/w3/作业/Car.java b/w3/作业/Car.java new file mode 100644 index 0000000..c94b22d --- /dev/null +++ b/w3/作业/Car.java @@ -0,0 +1,240 @@ +/** + * 车辆实体类 - 用于车辆管理系统 + * 包含车辆的基本信息,实现完整的封装 + */ +public class Car { + // 私有属性,实现封装 + private String brand; // 品牌 + private String model; // 型号 + private int year; // 生产年份 + private double price; // 价格 + private String color; // 颜色 + private String licensePlate; // 车牌号 + + /** + * 无参构造方法 + */ + public Car() { + this.brand = "未知品牌"; + this.model = "未知型号"; + this.year = 2026; + this.price = 0.0; + this.color = "未知颜色"; + this.licensePlate = "未上牌"; + } + + /** + * 全参构造方法 - 创建车辆对象时必须提供所有信息 + * @param brand 品牌 + * @param model 型号 + * @param year 生产年份 + * @param price 价格 + * @param color 颜色 + * @param licensePlate 车牌号 + */ + public Car(String brand, String model, int year, double price, String color, String licensePlate) { + this.brand = brand; + this.model = model; + setYear(year); // 使用 setter 方法进行数据校验 + setPrice(price); // 使用 setter 方法进行数据校验 + this.color = color; + this.licensePlate = licensePlate; + } + + /** + * 简化版构造方法 - 只需提供品牌、型号和价格 + * @param brand 品牌 + * @param model 型号 + * @param price 价格 + */ + public Car(String brand, String model, double price) { + this(brand, model, 2026, price, "标准色", "待上牌"); // 调用全参构造方法 + } + + // Getter 和 Setter 方法(封装的体现) + + public String getBrand() { + return brand; + } + + public void setBrand(String brand) { + if (brand != null && !brand.trim().isEmpty()) { + this.brand = brand; + } else { + System.out.println("错误:品牌名称不能为空!"); + } + } + + public String getModel() { + return model; + } + + public void setModel(String model) { + if (model != null && !model.trim().isEmpty()) { + this.model = model; + } else { + System.out.println("错误:型号名称不能为空!"); + } + } + + public int getYear() { + return year; + } + + /** + * 设置生产年份(带数据校验) + * @param year 生产年份 + */ + public void setYear(int year) { + if (year >= 1900 && year <= 2026) { + this.year = year; + } else { + System.out.println("错误:年份必须在 1900-2026 之间!"); + this.year = 2026; // 使用默认值 + } + } + + public double getPrice() { + return price; + } + + /** + * 设置价格(带数据校验) + * @param price 价格 + */ + public void setPrice(double price) { + if (price > 0) { + this.price = price; + } else { + System.out.println("错误:价格必须大于 0!"); + this.price = 0.0; // 使用默认值 + } + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + if (color != null && !color.trim().isEmpty()) { + this.color = color; + } else { + System.out.println("错误:颜色不能为空!"); + } + } + + public String getLicensePlate() { + return licensePlate; + } + + public void setLicensePlate(String licensePlate) { + if (licensePlate != null && !licensePlate.trim().isEmpty()) { + this.licensePlate = licensePlate; + } else { + System.out.println("错误:车牌号不能为空!"); + } + } + + /** + * 显示车辆信息 + */ + public void showInfo() { + System.out.println("\n========== 车辆信息 =========="); + System.out.println("品牌:" + brand); + System.out.println("型号:" + model); + System.out.println("年份:" + year); + System.out.println("价格:" + price + "万元"); + System.out.println("颜色:" + color); + System.out.println("车牌号:" + licensePlate); + System.out.println("=============================\n"); + } + + /** + * 测试本类的功能 + * @param args 命令行参数(可选:第一个参数为起始测试编号) + */ + static void main(String[] args) { + System.out.println("╔══════════════════════════════╗"); + System.out.println("║ 车辆管理系统 - Car 类测试 ║"); + System.out.println("╚══════════════════════════════╝\n"); + + // 如果通过命令行传入参数,可以控制测试流程 + int startTest = 1; // 默认从测试 1 开始 + if (args.length > 0) { + try { + startTest = Integer.parseInt(args[0]); + System.out.println("提示:从测试 " + startTest + " 开始执行\n"); + } catch (NumberFormatException e) { + System.out.println("提示:使用默认测试流程\n"); + } + } + + // 测试 1:使用无参构造方法 + if (startTest <= 1) { + System.out.println("【测试 1】使用无参构造方法:"); + Car car1 = new Car(); + car1.showInfo(); + } + + // 测试 2:使用简化版构造方法 + if (startTest <= 2) { + System.out.println("【测试 2】使用简化版构造方法:"); + Car car2 = new Car("丰田", "卡罗拉", 15.8); + car2.showInfo(); + } + + // 测试 3:使用全参构造方法 + if (startTest <= 3) { + System.out.println("【测试 3】使用全参构造方法:"); + Car car3 = new Car("宝马", "530Li", 2024, 45.6, "黑色", "京 A88888"); + car3.showInfo(); + } + + // 测试 4:使用 this 调用其他构造方法 + 测试 getter 方法 + if (startTest <= 4) { + System.out.println("【测试 4】修改车辆信息并验证:"); + Car car2 = new Car("丰田", "卡罗拉", 15.8); + car2.setBrand("Toyota"); + car2.setModel("Corolla"); + car2.setYear(2025); + car2.setPrice(16.5); + car2.setColor("白色"); + car2.setLicensePlate("沪 C12345"); + + // 使用 getter 方法验证修改结果 + System.out.println("验证修改结果:"); + System.out.println("品牌:" + car2.getBrand()); + System.out.println("型号:" + car2.getModel()); + System.out.println("年份:" + car2.getYear()); + System.out.println("价格:" + car2.getPrice() + "万元"); + System.out.println("颜色:" + car2.getColor()); + System.out.println("车牌号:" + car2.getLicensePlate()); + car2.showInfo(); + } + + // 测试 5:数据校验测试 + if (startTest <= 5) { + System.out.println("【测试 5】数据校验测试:"); + Car car3 = new Car("宝马", "530Li", 2024, 45.6, "黑色", "京 A88888"); + car3.setYear(1800); // 无效年份,会触发校验 + car3.setPrice(-10); // 无效价格,会触发校验 + car3.setBrand(""); // 空品牌,会触发校验 + car3.showInfo(); + } + + // 测试 6:单独测试 getter 方法 + if (startTest <= 6) { + System.out.println("【测试 6】测试 getter 方法:"); + Car car1 = new Car(); + System.out.println("car1 品牌:" + car1.getBrand()); + System.out.println("car1 型号:" + car1.getModel()); + System.out.println("car1 年份:" + car1.getYear()); + System.out.println("car1 价格:" + car1.getPrice()); + System.out.println("car1 颜色:" + car1.getColor()); + System.out.println("car1 车牌号:" + car1.getLicensePlate()); + } + + System.out.println("\n✓ 所有测试完成!"); + } +} + diff --git a/w3/课堂练习/AI交互记录.md b/w3/课堂练习/AI交互记录.md new file mode 100644 index 0000000..6990570 --- /dev/null +++ b/w3/课堂练习/AI交互记录.md @@ -0,0 +1,60 @@ +# AI 交互记录 - 银行账户类 BankAccount 开发 + +## 项目信息 +- **项目名称**:银行账户管理系统 +- **文件路径**:D:\Project\java\w3\src\BankAccount.java +- **开发日期**:2026 年 3 月 23 日 +- **开发人员**:宋瑞(学号:202506050301) + +--- + +## 交互过程记录 + +**用户请求**: +设计个银行账户类 BankAccount,要求包含账户号、户主姓名、余额三个属性,账户号不可修改,余额只能通过存款和取款操作改变。 + +**AI 响应**: +- 提供了完整的 BankAccount 类代码 +- 包含私有属性、构造方法、存款、取款、查询余额等方法 +- 使用 final 修饰账户号确保不可修改 +- 提供了详细的中文注释 + +--- + +## 技术要点总结 + +### 1. 面向对象特性 +- **封装**:所有属性使用 private 修饰 +- **不可变性**:使用 final 关键字保护账户号 +- **数据验证**:存款和取款操作都有严格的条件检查 + +### 2. 异常处理 +- 使用 try-catch 处理 NumberFormatException +- 防止因非法输入导致程序崩溃 + +### 3. 用户体验 +- 清晰的菜单导航 +- 友好的操作提示 +- 循环操作直到用户选择退出 + +### 4. 代码规范 +- 详细的中文注释 +- 规范的命名约定 +- 清晰的方法划分 + +--- + +## 遇到的问题及解决方案 + +| 问题 | 原因 | 解决方案 | +|------|------|----------| +| 类从未使用警告 | 创建了类但没有实例化 | 添加 main 方法进行测试 | +| 返回值未使用警告 | deposit/withdraw 返回 boolean 但未使用 | 改为 void 类型简化代码 | +| 参数未使用警告 | main 方法的 args 参数未使用 | 添加注解或实际使用参数 | + +--- + +## 最终成果 + +### 文件结构 + diff --git a/w3/课堂练习/BankAccount.java b/w3/课堂练习/BankAccount.java new file mode 100644 index 0000000..c314889 --- /dev/null +++ b/w3/课堂练习/BankAccount.java @@ -0,0 +1,84 @@ +/** + * 银行账户类 + * 包含账户号、户主姓名、余额三个属性 + */ +public class BankAccount { + // 私有属性,实现封装 + private final String accountNumber; // 账户号(final 修饰,创建后不可修改) + private String ownerName; // 户主姓名(可以修改) + private double balance; // 余额(只能通过存款和取款操作改变) + + /** + * 构造方法:创建账户时必须提供账户号和户主姓名,初始余额为 0 + * @param accountNumber 账户号 + * @param ownerName 户主姓名 + */ + public BankAccount(String accountNumber, String ownerName) { + this.accountNumber = accountNumber; + this.ownerName = ownerName; + this.balance = 0.0; // 初始余额设为 0 + } + + /** + * 存款操作 + * @param amount 存款金额 + */ + public void deposit(double amount) { + if (amount > 0) { + balance += amount; + System.out.println("存款成功!存入金额:" + amount + "元,当前余额:" + balance + "元"); + } else { + System.out.println("存款失败!存款金额必须大于 0。"); + } + } + + /** + * 取款操作 + * @param amount 取款金额 + */ + public void withdraw(double amount) { + if (amount > 0) { + if (amount <= balance) { + balance -= amount; + System.out.println("取款成功!取出金额:" + amount + "元,当前余额:" + balance + "元"); + } else { + System.out.println("取款失败!余额不足,当前余额:" + balance + "元"); + } + } else { + System.out.println("取款失败!取款金额必须大于 0。"); + } + } + + /** + * 查询余额方法(只读,不允许直接修改余额) + * @return 当前余额 + */ + public double getBalance() { + return balance; + } + + /** + * 获取账户号(只读) + * @return 账户号 + */ + public String getAccountNumber() { + return accountNumber; + } + + /** + * 获取户主姓名 + * @return 户主姓名 + */ + public String getOwnerName() { + return ownerName; + } + + /** + * 设置户主姓名(可以修改) + * @param ownerName 新的户主姓名 + */ + public void setOwnerName(String ownerName) { + this.ownerName = ownerName; + System.out.println("户主姓名已修改为:" + ownerName); + } +} diff --git a/w3/课堂练习/Main.java b/w3/课堂练习/Main.java new file mode 100644 index 0000000..949e33b --- /dev/null +++ b/w3/课堂练习/Main.java @@ -0,0 +1,45 @@ +/** + * 测试类 - 用于测试 BankAccount 类的功能 + */ +void main() { + // 可以通过命令行参数自定义账户信息 + String accountNumber = "62220219900101"; + String ownerName = "张三"; + + // 1. 创建银行账户(必须提供账户号和户主姓名) + var account = new BankAccount(accountNumber, ownerName); + + // 2. 显示初始信息 + System.out.println("=== 账户初始化 ==="); + System.out.println("账户号:" + account.getAccountNumber()); + System.out.println("户主姓名:" + account.getOwnerName()); + System.out.println("初始余额:" + account.getBalance() + "元\n"); + + // 3. 测试存款操作 + System.out.println("=== 测试存款 ==="); + account.deposit(5000); // 成功 + account.deposit(-100); // 失败:金额为负数 + System.out.println(); + + // 4. 测试取款操作 + System.out.println("=== 测试取款 ==="); + account.withdraw(2000); // 成功 + account.withdraw(5000); // 失败:余额不足 + account.withdraw(-500); // 失败:金额为负数 + System.out.println(); + + // 5. 查询当前余额 + System.out.println("=== 查询余额 ==="); + System.out.println("当前余额:" + account.getBalance() + "元\n"); + + // 6. 测试修改户主姓名 + System.out.println("=== 修改户主姓名 ==="); + account.setOwnerName("李四"); + System.out.println(); + + // 7. 显示最终信息 + System.out.println("=== 最终账户信息 ==="); + System.out.println("账户号:" + account.getAccountNumber()); + System.out.println("户主姓名:" + account.getOwnerName()); + System.out.println("当前余额:" + account.getBalance() + "元"); +}