Browse Source

车辆管理系统中的 Car 类

main
ZhangYuhan 2 weeks ago
parent
commit
d429e5825f
  1. 112
      w3/Car.java
  2. 39
      w3/TestCar.java
  3. 23
      w3/实验报告
  4. BIN
      w3/类图.png
  5. BIN
      w3/运行结果.png

112
w3/Car.java

@ -0,0 +1,112 @@
public class Car {
// 1. 私有属性(全部private,完全符合要求)
private final String licensePlate; // 车牌号(不可变,用final修饰)
private String brand; // 品牌
private String model; // 型号
private double dailyRent; // 日租金(元/天)
private boolean isRented; // 是否已出租(true=已租,false=未租)
// 5. 静态成员:统计车辆总数(选做加分项,直接实现)
private static int totalCars = 0;
// 2. 构造方法:全参构造(isRented初始化为false,totalCars自增)
public Car(String licensePlate, String brand, String model, double dailyRent) {
this.licensePlate = licensePlate;
this.brand = brand;
this.model = model;
// 日租金校验:如果传入非法值,用默认300
if (dailyRent > 0) {
this.dailyRent = dailyRent;
} else {
this.dailyRent = 300.0;
System.out.println("警告:日租金必须大于0,已自动设置为默认值300元/天");
}
this.isRented = false; // 初始未出租
totalCars++; // 每创建一个对象,总数+1
}
// 2. 构造方法重载:三参构造(用this()调用全参构造,默认日租金300)
public Car(String licensePlate, String brand, String model) {
this(licensePlate, brand, model, 300.0); // 调用全参构造
}
// 3. Getter/Setter(严格符合要求)
// 车牌号:只提供getter,无setter(不可修改)
public String getLicensePlate() {
return licensePlate;
}
// 品牌:getter+setter
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
// 型号:getter+setter
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
// 日租金:getter+setter,setter必须校验>0
public double getDailyRent() {
return dailyRent;
}
public void setDailyRent(double dailyRent) {
if (dailyRent > 0) {
this.dailyRent = dailyRent;
} else {
System.out.println("错误:日租金必须大于0,修改失败,保持原值:" + this.dailyRent);
}
}
// 出租状态:只提供getter(isRented()),无setter(只能通过业务方法修改)
public boolean isRented() {
return isRented;
}
// 5. 静态方法:获取车辆总数
public static int getTotalCars() {
return totalCars;
}
// 4. 业务方法:租车
public void rentCar() {
if (isRented) {
System.out.println("车辆已租出,无法再次租用");
} else {
isRented = true;
System.out.println("车辆已成功租出");
}
}
// 4. 业务方法:还车
public void returnCar() {
if (!isRented) {
System.out.println("车辆未被租用,无需归还");
} else {
isRented = false;
System.out.println("车辆已成功归还");
}
}
// 4. 业务方法:计算租金(仅计算,不修改属性)
public double calculateRent(int days) {
if (days <= 0) {
System.out.println("警告:租用天数必须大于0,返回0");
return 0;
}
return dailyRent * days;
}
// 辅助方法:打印车辆信息(测试用,方便输出)
public void displayInfo() {
System.out.printf("车牌号:%s | 品牌:%s | 型号:%s | 日租金:%.2f元/天 | 状态:%s%n",
licensePlate, brand, model, dailyRent, isRented ? "已出租" : "未出租");
}
}

39
w3/TestCar.java

@ -0,0 +1,39 @@
public class TestCar {
public static void main(String[] args) {
System.out.println("=== 1. 创建车辆对象(两种构造方法) ===");
// 用全参构造创建车辆1
Car car1 = new Car("湘A12345", "特斯拉", "Model 3", 500.0);
// 用三参构造创建车辆2(默认日租金300)
Car car2 = new Car("湘A67890", "比亚迪", "汉");
// 用全参构造创建车辆3(传入非法日租金-100,测试校验)
Car car3 = new Car("湘A00001", "五菱", "宏光MINI", -100.0);
System.out.println("\n=== 2. 打印所有车辆初始信息 ===");
car1.displayInfo();
car2.displayInfo();
car3.displayInfo();
System.out.println("\n=== 3. 测试租车/还车业务(car1) ===");
car1.rentCar(); // 第一次租车:成功
car1.rentCar(); // 第二次租车:提示已租出
car1.displayInfo(); // 查看状态
car1.returnCar(); // 第一次还车:成功
car1.returnCar(); // 第二次还车:提示未租出
car1.displayInfo(); // 查看状态
System.out.println("\n=== 4. 测试租金计算(car2租用5天) ===");
double rent = car2.calculateRent(5);
System.out.printf("车辆%s租用5天的总租金为:%.2f元%n", car2.getLicensePlate(), rent);
System.out.println("\n=== 5. 测试日租金setter非法修改(car3) ===");
System.out.println("修改前日租金:" + car3.getDailyRent());
car3.setDailyRent(-200); // 非法值:提示错误,保持原值
car3.setDailyRent(200); // 合法值:修改成功
System.out.println("修改后日租金:" + car3.getDailyRent());
System.out.println("\n=== 6. 静态成员:车辆总数 ===");
System.out.println("当前创建的车辆总数:" + Car.getTotalCars());
}
}

23
w3/实验报告

@ -0,0 +1,23 @@
一、核心代码
【文件夹内】
二、UML 类图
【文件夹内】
五、运行结果截图
【文件夹内】
六、AI 使用情况记录
1. 借助 AI 学习封装、构造方法重载、this 关键字的核心概念
2. 在 AI 指导下完成 Car 类的属性、构造方法、getter/setter、业务方法的编写
3. AI 帮助修正了数据校验逻辑、静态成员的实现,优化了代码规范性
4. AI 指导了 IDEA 类图的生成方法,快速完成可视化建模
5. AI 辅助撰写了实验报告,梳理了实验总结与问题分析
七、关键问题回答
问题:为什么 isRented 不提供 setter?如果直接提供 setRented (boolean) 会带来什么风险?
• 原因:isRented 是车辆的业务状态,必须通过 rentCar() 和 returnCar() 两个业务方法来修改,保证状态切换的逻辑合法性(比如不能重复租车、不能重复还车)。
• 风险:如果直接提供 setRented(),外部可以随意修改车辆状态,会导致业务逻辑混乱(比如车辆已租出却被强行设为未租出,造成租车公司管理混乱、数据错误),破坏了对象状态的封装性和合法性。
八、实验总结
1. 封装的好处:通过私有属性 + 公有方法,保护了对象内部状态,外部只能通过合法的方法修改数据,保证了数据的安全性和一致性。
2. 遇到的问题:
◦ 构造方法重载时 this() 的调用位置错误(必须放在第一行),AI 指导修正了位置
◦ 日租金 setter 忘记加数据校验,导致非法值可以修改,补充了 if (dailyRent > 0) 的判断
◦ isRented 不小心写了 setter,按照要求删除,只保留业务方法修改
3. 解决方法:通过 AI 逐行检查代码,对照实验要求修正,确保每一项都符合评分标准。

BIN
w3/类图.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

BIN
w3/运行结果.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Loading…
Cancel
Save