当前位置: 首页 > news >正文

Java面向对象实战:手把手教你用继承和多态打造租车系统(附完整代码)

Java面向对象实战:从零构建租车系统的继承与多态设计

租车系统是学习面向对象编程(OOP)的绝佳案例。这个看似简单的业务场景,实际上涵盖了类设计、继承体系、多态应用等核心概念。我们将从零开始,构建一个完整的租车系统,重点讲解如何用Java实现优雅的面向对象设计。

1. 系统分析与类设计

在动手编码之前,我们需要对租车业务进行充分分析。一个典型的租车系统包含以下核心要素:

  • 车辆类型:客车、货车、皮卡等不同车型
  • 租赁属性:租金计算、租期管理
  • 载客/载货能力:不同车型的运输特性
  • 业务规则:费用计算、可用性检查等

基于这些分析,我们可以设计出以下类结构:

// 基类:车辆 abstract class Vehicle { private String model; private double dailyRate; public Vehicle(String model, double dailyRate) { this.model = model; this.dailyRate = dailyRate; } public double calculateRentalFee(int days) { return days * dailyRate; } // 抽象方法,子类必须实现 public abstract String getCapacityDescription(); } // 客车类 class PassengerCar extends Vehicle { private int passengerCapacity; public PassengerCar(String model, double dailyRate, int passengerCapacity) { super(model, dailyRate); this.passengerCapacity = passengerCapacity; } @Override public String getCapacityDescription() { return "载客量: " + passengerCapacity + "人"; } } // 货车类 class Truck extends Vehicle { private double cargoCapacity; // 吨 public Truck(String model, double dailyRate, double cargoCapacity) { super(model, dailyRate); this.cargoCapacity = cargoCapacity; } @Override public String getCapacityDescription() { return "载货量: " + cargoCapacity + "吨"; } } // 皮卡类 class PickupTruck extends Vehicle { private int passengerCapacity; private double cargoCapacity; public PickupTruck(String model, double dailyRate, int passengerCapacity, double cargoCapacity) { super(model, dailyRate); this.passengerCapacity = passengerCapacity; this.cargoCapacity = cargoCapacity; } @Override public String getCapacityDescription() { return "载客量: " + passengerCapacity + "人, 载货量: " + cargoCapacity + "吨"; } }

2. 多态在租车系统中的应用

多态是OOP的三大特性之一,它允许我们以统一的方式处理不同类型的对象。在我们的租车系统中,多态主要体现在:

  1. 统一接口:所有车辆都继承自Vehicle基类
  2. 动态绑定:运行时确定调用哪个子类的方法
  3. 扩展性:新增车型不影响现有代码

下面是一个展示多态优势的示例:

public class RentalSystem { private List<Vehicle> fleet = new ArrayList<>(); public void initializeFleet() { fleet.add(new PassengerCar("商务轿车", 500, 5)); fleet.add(new Truck("厢式货车", 800, 3.5)); fleet.add(new PickupTruck("皮卡", 600, 4, 1.5)); } public void displayFleetInfo() { for (Vehicle vehicle : fleet) { System.out.println(vehicle.getModel() + " - " + vehicle.getCapacityDescription()); } } public double calculateTotalRental(Vehicle vehicle, int days) { return vehicle.calculateRentalFee(days); } }

在这个设计中,calculateTotalRental方法可以接受任何Vehicle子类的实例,系统会自动调用正确的计算方法,这就是多态的威力。

3. 系统功能实现与业务逻辑

现在我们来实现租车系统的核心业务逻辑。系统需要处理以下功能:

  1. 车辆选择与组合
  2. 租期计算
  3. 费用汇总
  4. 载客/载货能力统计

以下是核心业务类的实现:

public class RentalService { private List<Vehicle> availableVehicles; private List<RentalItem> currentRental = new ArrayList<>(); public RentalService(List<Vehicle> availableVehicles) { this.availableVehicles = availableVehicles; } public void addToRental(int vehicleIndex, int days) { if (vehicleIndex >= 0 && vehicleIndex < availableVehicles.size()) { currentRental.add(new RentalItem(availableVehicles.get(vehicleIndex), days)); } } public RentalSummary calculateSummary() { int totalPassengers = 0; double totalCargo = 0.0; double totalCost = 0.0; for (RentalItem item : currentRental) { Vehicle vehicle = item.getVehicle(); int days = item.getDays(); totalCost += vehicle.calculateRentalFee(days); if (vehicle instanceof PassengerCar) { totalPassengers += ((PassengerCar) vehicle).getPassengerCapacity() * days; } else if (vehicle instanceof Truck) { totalCargo += ((Truck) vehicle).getCargoCapacity() * days; } else if (vehicle instanceof PickupTruck) { PickupTruck pickup = (PickupTruck) vehicle; totalPassengers += pickup.getPassengerCapacity() * days; totalCargo += pickup.getCargoCapacity() * days; } } return new RentalSummary(totalPassengers, totalCargo, totalCost); } } class RentalItem { private Vehicle vehicle; private int days; public RentalItem(Vehicle vehicle, int days) { this.vehicle = vehicle; this.days = days; } // getters... } class RentalSummary { private int totalPassengers; private double totalCargo; private double totalCost; public RentalSummary(int totalPassengers, double totalCargo, double totalCost) { this.totalPassengers = totalPassengers; this.totalCargo = totalCargo; this.totalCost = totalCost; } @Override public String toString() { return String.format("总载客: %d人, 总载货: %.2f吨, 总费用: %.2f元", totalPassengers, totalCargo, totalCost); } }

4. 用户交互与系统集成

为了让系统真正可用,我们需要实现用户交互层。这里我们采用控制台界面,但设计上保持业务逻辑与界面分离,便于未来扩展。

public class RentalApp { private RentalService rentalService; private Scanner scanner; public RentalApp() { initializeVehicles(); this.scanner = new Scanner(System.in); } private void initializeVehicles() { List<Vehicle> vehicles = new ArrayList<>(); vehicles.add(new PassengerCar("商务轿车", 500, 5)); vehicles.add(new PassengerCar("中巴车", 800, 15)); vehicles.add(new Truck("小型货车", 600, 2.0)); vehicles.add(new Truck("大型货车", 1200, 10.0)); vehicles.add(new PickupTruck("标准皮卡", 450, 4, 1.5)); this.rentalService = new RentalService(vehicles); } public void start() { displayWelcomeMessage(); displayVehicleList(); boolean renting = true; while (renting) { System.out.print("\n请输入要租赁的车辆编号(0结束): "); int choice = scanner.nextInt(); if (choice == 0) { renting = false; } else { System.out.print("请输入租赁天数: "); int days = scanner.nextInt(); rentalService.addToRental(choice - 1, days); } } displayRentalSummary(); } private void displayWelcomeMessage() { System.out.println("=== 欢迎使用租车系统 ==="); System.out.println("以下是可租车辆列表:"); } private void displayVehicleList() { List<Vehicle> vehicles = rentalService.getAvailableVehicles(); for (int i = 0; i < vehicles.size(); i++) { Vehicle v = vehicles.get(i); System.out.printf("%d. %s - %s - 每日租金: %.2f元\n", i + 1, v.getModel(), v.getCapacityDescription(), v.getDailyRate()); } } private void displayRentalSummary() { RentalSummary summary = rentalService.calculateSummary(); System.out.println("\n=== 租赁汇总 ==="); System.out.println(summary); } public static void main(String[] args) { new RentalApp().start(); } }

5. 高级主题与系统扩展

我们的基础系统已经完成,但一个真正的商业系统还需要考虑更多因素。以下是几个可能的扩展方向:

5.1 价格策略模式

不同车型、不同租期可能有不同的计价策略。我们可以使用策略模式来实现灵活的价格计算:

interface PricingStrategy { double calculatePrice(double baseRate, int days); } class StandardPricing implements PricingStrategy { public double calculatePrice(double baseRate, int days) { return baseRate * days; } } class WeeklyDiscountPricing implements PricingStrategy { public double calculatePrice(double baseRate, int days) { int weeks = days / 7; int remainingDays = days % 7; return (weeks * baseRate * 6) + (remainingDays * baseRate); } } class Vehicle { private PricingStrategy pricingStrategy = new StandardPricing(); public void setPricingStrategy(PricingStrategy strategy) { this.pricingStrategy = strategy; } public double calculateRentalFee(int days) { return pricingStrategy.calculatePrice(dailyRate, days); } }

5.2 车辆状态管理

实际租车系统中,车辆可能有多种状态(可用、维修中、已租出等)。我们可以引入状态模式:

interface VehicleState { boolean isAvailable(); VehicleState rent(); VehicleState returnVehicle(); VehicleState sendForMaintenance(); } class AvailableState implements VehicleState { public boolean isAvailable() { return true; } public VehicleState rent() { return new RentedState(); } // 其他方法实现... } class Vehicle { private VehicleState state = new AvailableState(); public boolean isAvailable() { return state.isAvailable(); } public void rent() { state = state.rent(); } }

5.3 数据库集成与持久化

实际应用中,车辆数据应该存储在数据库中。我们可以使用JDBC或JPA来实现:

@Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "vehicle_type") public abstract class Vehicle { @Id @GeneratedValue private Long id; private String model; private double dailyRate; // ... } @Entity @DiscriminatorValue("PASSENGER") public class PassengerCar extends Vehicle { private int passengerCapacity; // ... } public class VehicleRepository { @PersistenceContext private EntityManager em; public List<Vehicle> findAllAvailable() { return em.createQuery( "SELECT v FROM Vehicle v WHERE v.available = true", Vehicle.class) .getResultList(); } }

6. 测试与验证

完善的测试是保证系统质量的关键。我们可以为系统编写单元测试和集成测试:

public class RentalServiceTest { private RentalService rentalService; @Before public void setUp() { List<Vehicle> vehicles = Arrays.asList( new PassengerCar("Test Car", 100, 4), new Truck("Test Truck", 200, 2.0) ); rentalService = new RentalService(vehicles); } @Test public void testPassengerCarRental() { rentalService.addToRental(0, 3); // 租用客车3天 RentalSummary summary = rentalService.calculateSummary(); assertEquals(12, summary.getTotalPassengers()); // 4人×3天 assertEquals(0.0, summary.getTotalCargo(), 0.01); assertEquals(300.0, summary.getTotalCost(), 0.01); } @Test public void testMixedRental() { rentalService.addToRental(0, 2); // 客车2天 rentalService.addToRental(1, 1); // 货车1天 RentalSummary summary = rentalService.calculateSummary(); assertEquals(8, summary.getTotalPassengers()); // 4人×2天 assertEquals(2.0, summary.getTotalCargo(), 0.01); // 2吨×1天 assertEquals(400.0, summary.getTotalCost(), 0.01); // 100×2 + 200×1 } }

在实际项目中,我们还会考虑添加日志记录、异常处理、输入验证等功能,使系统更加健壮。

http://www.cnnetsun.cn/news/1330120.html

相关文章:

  • 影墨·今颜部署教程:Mac M2 Ultra通过CoreML运行轻量版
  • 打造个性化HTML5音乐播放器:从自动解析到动态变色
  • 避开天价邀请码!用MCP协议+Python3.11零成本搭建AI工作流(附Playwright实战)
  • 脑机接口在自闭症治疗中的突破:我们如何用Neurofeedback游戏改善儿童社交能力
  • 深入解析Carry4:从内部结构到加法实现
  • SecGPT-14B实操手册:利用Gradio历史消息功能构建持续进化的安全知识库
  • PyTorch学习笔记|张量的创建和形变
  • ArcMap新手必看:5分钟搞定栅格数据矢量化(附常见错误排查)
  • 坚果云内嵌Zotero同步插件使用指南(适配Zotero 7/8)
  • Stata数据清洗实战:精准定位并处理nonnumeric characters的5种场景
  • Jimeng AI Studio实操手册:LoRA模型兼容性处理与cross_attention优化
  • Phi-3-vision-128k-instruct实际效果:招聘JD截图→岗位核心要求提取→匹配度评分生成
  • Unity游戏开发必备:Reporter插件一键查看日志与性能数据(附手势禁用技巧)
  • 大模型编程:从代码产出者到文档定义者,掌握未来核心竞争力!
  • SecGPT-14B实操手册:WebUI中粘贴1000+行日志后触发截断,如何分段提问保完整性
  • AlexNet网络可视化解析:从ReLU到Dropout的8个关键设计
  • 数据结构学习笔记:冒泡排序(Java)
  • Qwen Pixel Art应用场景:复古电子贺卡、像素化社交媒体Banner动态生成
  • 从存储配置到中文界面:Proxmox VE新手上路全攻略(含ZFS池创建技巧)
  • 联想小新BIOS更新导致PIN失效?手把手教你安全完成系统更新
  • 3-RRR 并联机构奇异位形解析与优化设计
  • 基于LLM(大模型)AI 翻译软件 - 技术架构与功能说明
  • SeaweedFS单机多节点部署实战:从下载到挂载的完整流程(含日志配置)
  • 【蒸汽教育求职分享】美国SDE求职通关秘籍:从技术硬实力到沟通软功夫全解析
  • Phi-3 Forest Laboratory C语言编程辅导:从语法纠错到数据结构实现
  • Qwen3模型训练轮数(epochs)优化指南:从理论到实践
  • Sonic数字人解决音画不同步:参数设置保姆级指南
  • WSL2 SSH配置避坑指南:从systemd启用到防火墙设置全流程
  • 企业微信 RPA 自动化:低代码连接业务与私域
  • 8. TI MSPM0G3507定时器实战:1秒LED闪烁实验详解