JAVA进阶 项目实战:汽车租聘系统
- 某汽车租赁公司出租多种轿车和客车,出租费用以日为单位计算。出租车型及信息如下表所示
抽象出类
- 找出问题中名词
某汽车租赁公司、汽车、轿车、客车、别克、宝马、金杯、金龙、X6、550i、GL8、林荫大道、座位数、日租金、折扣、京NY28588、京CNY3284、京6566754等车牌号
类的属性
类和类的属性
- 汽车类:车牌号、品牌、日租金
- 客车类:车牌号、品牌、日租金、座位数
- 轿车类:车牌号、品牌、日租金、型号
- 汽车业务类:忽略
- 汽车租赁管理类:忽略
类的方法
找出问题中动词
优化设计
-
设计类
汽车设计为抽象类 -
设计方法
计算租金设计为抽象方法
项目结构
Manage类
Manage 类是程序的启动类,包含了 main 方法,作为程序的入口。
在 main 方法中,创建了一个 Business 类的实例 b1,然后通过这个实例调用了 rent() 方法,启动了租车操作。
public class Manage {public static void main(String[] args) {Business b1 = new Business(); // 创建一个 Business 类的对象 b1b1.rent(); // 调用 b1 对象的 rent() 方法}
}
Business类
用户通过 rent() 方法选择车型(轿车或客车),并在接下来的流程中选择具体的车辆类型。
系统会根据用户的选择调用 rentCar() 方法,然后根据车型调用对应的租车方法(rentSaloon 或 rentPassengerCar)。
通过 rentDevise() 方法,系统会计算租车的总费用并输出。
import java.util.Scanner;public class Business {public void rent() {Scanner sc = new Scanner(System.in); // 创建一个扫描器,用来获取用户输入System.out.println("请选择租聘车型");System.out.println("1.轿车");System.out.println("2.客车");System.out.println("输入0退出");int a = sc.nextInt(); // 获取用户输入的车型选择while (a != 0) { // 当用户没有输入0时,继续执行租车流程switch (a) {case 1:System.out.println("请选择租聘信息");System.out.println("1.宝马X6(京NY28588)一天800");System.out.println("2.宝马550i(京CNY3284)一天600");System.out.println("3.别克林荫大道(京NT37465)一天300");System.out.println("4.别克GL8(京NT96968)一天600");int b = sc.nextInt(); // 获取用户选择的轿车rentCar(b, sc, "轿车"); // 调用rentCar方法处理轿车租赁break;case 2:System.out.println("请选择租聘信息");System.out.println("1.宝马X6(京NY28588)一天800");System.out.println("2.宝马550i(京CNY3284)一天800");System.out.println("3.别克林荫大道(京NT37465)一天1500");System.out.println("4.别克GL8(京NT96968)一天1500");int c = sc.nextInt(); // 获取用户选择的客车rentCar(c, sc, "客车"); // 调用rentCar方法处理客车租赁break;default:System.out.println("没有这个操作");}}
}
/*
Scanner:用于读取用户的输入。
while (a != 0):循环体,直到用户选择退出(输入0)。
switch(a):根据用户的选择执行不同的操作,选择车型并展示租赁信息。
case 1:用户选择了轿车,展示轿车的信息并调用 rentCar 方法进行进一步处理。
case 2:用户选择了客车,同样展示客车的信息并调用 rentCar 方法处理。
*/// 通用的租赁方法
private void rentCar(int carOption, Scanner sc, String carType) {if (carType.equals("轿车")) { // 如果是轿车switch (carOption) {case 1 -> rentSaloon("京NY28588", "宝马", 800, "X6", sc);case 2 -> rentSaloon("京CNY3284", "宝马", 600, "550i", sc);case 3 -> rentSaloon("京NT37465", "别克", 300, "林荫大道", sc);case 4 -> rentSaloon("京NT96968", "别克", 600, "GL8", sc);default -> System.out.println("没有这个操作");}} else if (carType.equals("客车")) { // 如果是客车switch (carOption) {case 1 -> rentPassengerCar("京6566754", "金杯", 800, 16, sc);case 2 -> rentPassengerCar("京8696997", "金龙", 800, 16, sc);case 3 -> rentPassengerCar("京9696996", "金杯", 1500, 34, sc);case 4 -> rentPassengerCar("京8696998", "金龙", 1500, 34, sc);default -> System.out.println("没有这个操作");}}
}
/*
if (carType.equals("轿车")):根据车型类型选择不同的租赁逻辑。
switch (carOption):根据用户选择的具体车型(1-4),调用不同的租车方法 (rentSaloon 或 rentPassengerCar)。
default:如果用户输入不在选项范围内,输出"没有这个操作"。
*/// 租轿车的方法private void rentSaloon(String plate, String brand, int dailyRent, String model, Scanner sc) {Saloon sa = new Saloon(plate, brand, dailyRent, model); // 创建轿车对象System.out.println("请输入租聘天数");int days = sc.nextInt(); // 获取用户输入的租赁天数double price = sa.rentDevise(sa.dailyRent, days); // 计算租金System.out.println("您的租聘价格为:" + price); // 输出租金
}
/*
Saloon sa = new Saloon(plate, brand, dailyRent, model);:创建一个轿车对象 sa。
rentDevise(sa.dailyRent, days):调用 Saloon 类的 rentDevise 方法计算租金。
*/// 租客车的方法private void rentPassengerCar(String plate, String brand, int dailyRent, int capacity, Scanner sc) {PassengerCar pC = new PassengerCar(plate, brand, dailyRent, capacity); // 创建客车对象System.out.println("请输入租聘天数");int days = sc.nextInt(); // 获取用户输入的租赁天数double price = pC.rentDevise(pC.dailyRent, days); // 计算租金System.out.println("您的租聘价格为:" + price); // 输出租金
}
/*
PassengerCar pC = new PassengerCar(plate, brand, dailyRent, capacity);:创建一个客车对象 pC。
rentDevise(pC.dailyRent, days):调用 PassengerCar 类的 rentDevise 方法计算租金。
*/}
Car类
Car 类是一个抽象类,无法直接实例化。它作为所有具体车辆类型(例如轿车、客车)的基类。
车辆的基本属性如 ID、brand 和 dailyRent 都在这个抽象类中定义。
rentDevise() 方法被声明为抽象方法,因此每个子类(如 Saloon 或 PassengerCar)必须提供具体的实现,来计算租金。
public abstract class Car {public String ID;public String brand;public int dailyRent;public Car() {}public Car(String ID, String brand, int dailyRent) {this.ID = ID;this.brand = brand;this.dailyRent = dailyRent;}public abstract double rentDevise(int price, int day);
}
PassengerCar类
PassengerCar 类继承自 Car 类,并实现了 rentDevise 方法,根据租赁天数来计算租金,并为不同的天数区间提供了不同的折扣。
该类包含一个 seat 变量来表示座位数量,它可能会在进一步扩展中用于其他功能(比如判断车辆的适用人数等)。
rentDevise 方法根据租赁天数的不同,采用了阶梯式的折扣政策,既能支持短期租赁,也能对长期租赁提供优惠。
public class PassengerCar extends Car {private int seat;public PassengerCar() {}public PassengerCar(String ID, String brand, int dailyRent, int seat) {super(ID, brand, dailyRent);this.seat = seat;}public double rentDevise(int price, int day) {double copy;if (day >= 0 && day < 3) {copy = day * price;} else if (day >= 3 && day < 7) {copy = 0.9 * day * price;} else if (day >= 7 && day < 30) {copy = 0.8 * day * price;} else if (day >= 30 && day < 150) {copy = 0.7 * day * price;} else if (day >= 150) {copy = 0.9 * day * price;} else {System.out.println("你输入的不对");copy = 0;}return copy;}}
Saloon类
Saloon 类继承自 Car 类,并实现了 rentDevise 方法,根据租赁天数的不同,提供了不同的折扣率。它的折扣规则与 PassengerCar 类略有不同,主要针对短期和长期租赁有不同的折扣。
Saloon 类还包括一个 type 变量来表示该车的具体类型,可能在未来的扩展中发挥作用,例如区分不同品牌或功能的轿车类型。
通过多态性,Business 类可以根据不同类型的车(如 Saloon 或 PassengerCar)动态地计算租金,而无需为每种类型的车编写单独的租金计算代码。
public class Saloon extends Car{private String type;public Saloon() {}@Overridepublic double rentDevise(int price, int day) {double copy;if (day >= 0 && day <= 7) {copy = day * price;} else if (day > 7 && day < 30) {copy = 0.9 * day * price;} else if (day > 30 && day <= 150) {copy = 0.8 * day * price;} else if (day > 150) {copy = 0.7 * day * price;} else {System.out.println("你输入的不对");copy = 0;}return copy;}public Saloon(String ID, String brand, int dailyRent, String type) {super(ID, brand, dailyRent);this.type = type;}}