租賃公司提供轎車、大巴兩類車輛,不同車型、座位數計費規則不同。利用多態機制,實現靈活可擴展的租金計算。
public abstract class MotoVehicle {
protected String no; // 車牌號
protected String brand; // 品牌
protected String color; // 顏色
protected String mileage; // 里程
protected int days; // 租賃天數
public MotoVehicle() {}
public MotoVehicle(String no, String brand, String color, String mileage, int days) {
this.no = no;
this.brand = brand;
this.color = color;
this.mileage = mileage;
this.days = days;
}
/** 核心抽象方法:子類實現具體計費邏輯 */
public abstract float calcRent(int days);
// Getter/Setter 省略...
}
public final class Car extends MotoVehicle {
private String type; // 車型
public Car() {}
public Car(String type) { this.type = type; }
@Override
public float calcRent(int days) {
float rent = 0;
switch (type) {
case "別克商務艙GL8": rent = 600 * days; break;
case "寶馬550i": rent = 500 * days; break;
case "別克林蔭大道": rent = 300 * days; break;
default: throw new IllegalArgumentException("不支持的車型: " + type);
}
return rent;
}
// Getter/Setter 省略...
}
public final class Bus extends MotoVehicle {
private int seatCount; // 座位數
public Bus() {}
public Bus(int seatCount) { this.seatCount = seatCount; }
@Override
public float calcRent(int days) {
if (seatCount <= 16) {
return 800 * days;
} else {
return 1500 * days;
}
}
// Getter/Setter 省略...
}
import java.util.Scanner;
public class MotoVehicleTest {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
float rent = 0;
System.out.println("=== 租車系統 ===");
System.out.print("請輸入車輛類型 (car/bus): ");
String kind = input.next().toLowerCase();
MotoVehicle vehicle = null;
if ("car".equals(kind)) {
Car car = new Car();
System.out.print("請輸入租賃天數: ");
car.setDays(input.nextInt());
System.out.print("請輸入車型 (別克商務艙GL8/寶馬550i/別克林蔭大道): ");
car.setType(input.next());
vehicle = car;
} else if ("bus".equals(kind)) {
Bus bus = new Bus();
System.out.print("請輸入租賃天數: ");
bus.setDays(input.nextInt());
System.out.print("請輸入座位數: ");
bus.setSeatCount(input.nextInt());
vehicle = bus;
} else {
System.out.println("無效類型");
input.close();
return;
}
rent = vehicle.calcRent(vehicle.getDays());
System.out.println("您的租車費用為: " + rent + " 元");
input.close();
}
}
=== 租車系統 === 請輸入車輛類型 (car/bus): car 請輸入租賃天數: 3 請輸入車型 (別克商務艙GL8/寶馬550i/別克林蔭大道): 寶馬550i 您的租車費用為: 1500.0 元
| 原則 | 體現 |
|---|---|
| 開閉原則 | 新增車型(如 Truck)只需新增子類,無需修改現有代碼 |
| 單一職責 | 計費邏輯封裝在各子類,測試類僅負責交互 |
| 里氏替換 | 主程序針對 MotoVehicle 編程,運行時動態綁定具體實現 |
VehicleFactory 根據輸入創建具體車輛對象,解耦創建邏輯。enum CarType,編譯期保證類型安全。BigDecimal。本例展示了多態在「同一接口、不同實現」場景下的威力:主流程對抽象類編程,具體規則分散在子類中,新增業務零侵入。這正是面向對象設計應對變化的核心價值。