5 changed files with 497 additions and 0 deletions
@ -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("错误:车牌号已分配,不能修改!"); } } |
|||
@ -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✓ 所有测试完成!"); |
|||
} |
|||
} |
|||
|
|||
@ -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 参数未使用 | 添加注解或实际使用参数 | |
|||
|
|||
--- |
|||
|
|||
## 最终成果 |
|||
|
|||
### 文件结构 |
|||
|
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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() + "元"); |
|||
} |
|||
Loading…
Reference in new issue