为了账号安全,请及时绑定邮箱和手机立即绑定

答答租车系统稳定版 v1.0

标签:
Java

昨天闲来无事,决定要玩一把大的。于是花费几个小时写了这个「答答租车系统稳定版」。该版本具有如下优势:

  1. 该系统读取用户输入的一切内容,并给出相应提示,确保用户输入的内容准确。对用户输入字符串或其他数据类型的情况,有相应的报错及提示重新输入的功能。
  2. 可让用户选择一次性租用多种车辆,并对每一车辆设置单独的租车数目与租车天数。
  3. 可修改代码的initCarList方法,任意添加新车辆,无需修改其他任何代码。可很方便地添加管理员系统(如增加新车、删除旧车、更改现有车辆参数等等),以后我可能会就此写一个更新版。
  4. 当然,作者也是初学,水平有限,欢迎大家提出各类修改意见与新增功能建议。

提醒大家,为了保证该程序的稳定性与可扩展性,主程序的代码超过了200行,但我在关键位置给出了详细注释。
闲话少说,下面放出代码。首先定义了基础的Car类:

package com.imooc;
// 新建Car类

public abstract class Car {
    private String type;
    private int price;
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public int getPrice() {
        return price;
    }
    public void setPrice(int price) {
        this.price = price;
    }
    @Override
    public String toString() {
        return type + "\t" + price;
    }
}

随后定义两个接口,分别对应载客与载货。这两个接口其实不是必须,在这里是为了规定载客与载货车辆必须要有getter与setter方法。

package com.imooc;
// 新建接口IPassenger,保证可载客车辆一定有如下方法

public interface IPassenger {
    public int getPassCapacity ();
    public void setPassCapacity (int passCapacity);
}
package com.imooc;
// 新建接口ICargo,保证可载货车辆一定有如下方法

public interface ICargo {
    public int getCargoCapacity ();
    public void setCargoCapacity (int cargoCapacity);
}

随后,定义了三个Car的子类:

package com.imooc;
// 新建CarBus类,作为客车,仅能载客

public class CarBus extends Car implements IPassenger {
    private int passCapacity;
    public CarBus (String type, int price, int passCapacity) {
        this.setType(type);
        this.setPrice(price);
        this.setPassCapacity(passCapacity);
    }
    public int getPassCapacity() {
        return passCapacity;
    }
    public void setPassCapacity(int passCapacity) {
        this.passCapacity = passCapacity;
    }
    @Override
    public String toString() {
        return super.toString() + "\t" + passCapacity + "\t---";
    }
}
package com.imooc;
// 新建CarTruck类,作为货车,只能载货

public class CarTruck extends Car implements ICargo {
    private int cargoCapacity;
    public CarTruck (String type, int price, int cargoCapacity) {
        this.setType(type);
        this.setPrice(price);
        this.setCargoCapacity(cargoCapacity);
    }
    public int getCargoCapacity() {
        return cargoCapacity;
    }
    public void setCargoCapacity(int cargoCapacity) {
        this.cargoCapacity = cargoCapacity;
    }
    @Override
    public String toString() {
        return super.toString() + "\t---\t" + cargoCapacity;
    }
}
package com.imooc;
// 新建CarPickup类,作为皮卡,既能载客,也能载货

public class CarPickup extends Car implements IPassenger, ICargo{
    private int passCapacity;
    private int cargoCapacity;
    public CarPickup (String type, int price, int passCapacity, int cargoCapacity) {
        this.setType(type);
        this.setPrice(price);
        this.setPassCapacity(passCapacity);
        this.setCargoCapacity(cargoCapacity);
    }
    public int getPassCapacity() {
        return passCapacity;
    }
    public void setPassCapacity(int passCapacity) {
        this.passCapacity = passCapacity;
    }
    public int getCargoCapacity() {
        return cargoCapacity;
    }
    public void setCargoCapacity(int cargoCapacity) {
        this.cargoCapacity = cargoCapacity;
    }
    @Override
    public String toString() {
        return super.toString() + "\t" + passCapacity + "\t" + cargoCapacity;
    }
}

主程序:

package com.imooc;
/* 答答租车系统稳定版 v1.0 by Bambrow
 * 该系统读取用户输入的一切内容,并给出相应提示,确保用户输入的内容准确。
 * 对用户输入字符串或其他数据类型的情况,有相应的报错及提示重新输入的功能。
 * 可让用户选择一次性租用多种车辆,并对每一车辆设置单独的租车数目与租车天数。
 * 可修改代码的initCarList方法,任意添加新车辆,无需修改其他任何代码。
 * 作者会继续进行维护和改进,可能以后会增加管理员系统。
 * 可任意参考,转载请注明作者或保留该注释。
 */

// 导入包
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.stream.IntStream;

public class Demo {
    public static void main(String[] args) {
        System.out.println("欢迎来到答答租车系统!");
        List carList = initCarList(); // 为了保证随时添加与删除项目,使用List功能
        for( ; ; ) { // 设置无条件循环
            System.out.println("若您是租车客户,请输入1;"
                    + "退出请输入0。");
            int choice;
            try{
                choice = Integer.parseInt(getInput());
            }catch(Exception e){
                System.out.println("指令有误!请输入正确的指令。");
                continue;
            } // 确保输入的为数字,而不是别的字符
            if(choice == 0) break; // 若输入0,结束循环
            else if(choice == 1) {
                rentCars(carList); // 若输入1,开始租车
                System.out.println();
            }
            else{
                System.out.println("指令有误!请输入正确的指令。");
                continue;
            } // 若输入其他数字,重新开始循环
        }
        System.out.println("感谢您使用答答租车系统!");
    }

    // 生成初始化的可租车列表
    private static List initCarList() {
        List<Car> carList = new ArrayList<Car>(); // 初始化List,确保每一项都是Car类
        carList.add(new CarBus("小型客车", 500, 6));
        carList.add(new CarBus("大型客车", 1000, 15));
        carList.add(new CarTruck("小型货车", 400, 2));
        carList.add(new CarTruck("大型货车", 800, 10));
        carList.add(new CarPickup("小型皮卡", 500, 2, 1));
        carList.add(new CarPickup("大型皮卡", 900, 4, 2));
        return carList; // 添加完每一辆车后返回List
    } // 可以随时使用carList.add添加新车辆,而无需修改其他任何代码

    // 输出租车列表,用到了每一类中重写的toString方法
    private static void printCarList(List carList) {
        System.out.println("以下是可用车型:");
        System.out.println("序号\t车型\t租金\t载客量\t载货量");
        for(int i = 0; i < carList.size(); i++) {
            System.out.println((i + 1) + "\t" + (carList.get(i)).toString());
        }
    }

    // 客户选车功能,该功能无需用户提前输入租车的类型数目,因此全部使用无需预先确定长度的List功能
    private static List selectCars(List carList) {
        List<Integer> rentArray = new ArrayList<Integer>(); // 储存客户选过的序号
        List<Car> selectCars = new ArrayList<Car>(); // 储存用户选过的车
        System.out.println("请输入租车序号,以回车分隔。输入0结束输入:");
        for( ; ; ) {
            System.out.println("请输入车辆序号(1-" + carList.size() + "):");
            boolean repeated = false;
            int carNum;
            try{
                carNum = Integer.parseInt(getInput());
            }catch(Exception e){
                System.out.println("输入不正确!请输入正确的序号。");
                continue;
            } // 确保输入的为数字,而不是其他字符
            if(carNum == 0) break; // 输入0,退出循环
            else if(carNum > 0 && carNum <= carList.size()) { // 确保输入的数字在范围内
                for(int i = 0; i < rentArray.size(); i++){
                    if(carNum == rentArray.get(i)) {
                        System.out.println("您已输入过该车型!请重新输入序号。");
                        repeated = true;
                        break; // 若输入的序号已经选择过,则输出选择重复信息并重新选择
                    }
                }
                if(!repeated) {
                    rentArray.add(carNum);
                    selectCars.add((Car) carList.get(carNum - 1));
                } // 若输入的序号不重复,则加入选择的车辆列表
            }
            else{
                System.out.println("输入不正确!请输入正确的序号。");
                continue;
            } // 确保输入的数字在范围内
        }
        return selectCars; // 返回选好的车辆List
    }

    // 读取租车数目功能
    private static int rentCount() {
        for( ; ; ) {
            System.out.println("请输入租车数(1-50):");
            int rentCount;
            try{
                rentCount = Integer.parseInt(getInput());
            }catch(Exception e){
                System.out.println("输入不正确!请输入正确的租车数。");
                continue;
            } // 确保输入的为数字,而不是其他字符
            if(rentCount >= 1 && rentCount <= 50) return rentCount; // 输入正确
            else System.out.println("输入不正确!请输入正确的租车数。"); // 输入不正确
        }
    }

    // 对每一种选好的车辆,读取相应的租车数目
    private static int[] rentNumArray(List carList) {
        int[] rentNumArray = new int[carList.size()]; // 使用数组存储每一种车辆的数目
        for(int i = 0; i < carList.size(); i++) {
            System.out.println("请输入选定列表里,第" + (i+1) + "辆车的租车数量:");
            rentNumArray[i] = rentCount(); // 调用读取租车数目方法
        }
        return rentNumArray; // 返回租车数目数组
    }

    // 读取租车天数功能
    private static int rentDays() {
        for( ; ; ) {
            System.out.println("请输入租车天数(1-365):");
            int rentDays;
            try{
                rentDays = Integer.parseInt(getInput());
            }catch(Exception e){
                System.out.println("输入不正确!请输入正确的租车天数。");
                continue;
            } // 确保输入的为数字,而不是其他字符
            if(rentDays >= 1 && rentDays <= 365) return rentDays; // 输入正确
            else System.out.println("输入不正确!请输入正确的租车天数。"); // 输入不正确
        }
    }

    // 对每一种选好的车辆,读取相应的租车天数
    private static int[] rentDayArray(List carList) {
        int[] rentDayArray = new int[carList.size()]; // 使用数组存储每一种车辆的天数
        for(int i = 0; i < carList.size(); i++) {
            System.out.println("请输入选定列表里,第" + (i+1) + "辆车的租车天数:");
            rentDayArray[i] = rentDays(); // 调用读取租车天数方法
        }
        return rentDayArray; // 返回租车天数数组
    }

    // 打印订单
    private static void printOrder(List carList, 
            int[] rentNumArray, int[] rentDayArray) {
        int[] rentSinglePriceTotal = new int[carList.size()];
        int[] rentSinglePassTotal = new int[carList.size()];
        int[] rentSingleCargoTotal = new int[carList.size()];
        // 三个数组分别存储总价、总载客量与总载货量
        System.out.println("以下是您的订单:");
        System.out.println("序号\t车型\t租金\t载客量\t载货量"
                + "\t租用数量\t租用天数\t消费数额");
        for(int i = 0; i < carList.size(); i++) {
            rentSinglePriceTotal[i] = ((Car) carList.get(i)).getPrice() 
                    * rentNumArray[i] * rentDayArray[i]; // 计算每一种车的总价
            System.out.println((i + 1) + "\t" + (carList.get(i)).toString() 
                    + "\t" + rentNumArray[i] + "\t" + rentDayArray[i]
                            + "\t" + rentSinglePriceTotal[i]);
            try{
                rentSinglePassTotal[i] = 
                        ((CarBus) carList.get(i)).getPassCapacity() 
                        * rentNumArray[i];
            }catch(Exception eCarBus){
                try{
                    rentSinglePassTotal[i] = 
                            ((CarPickup) carList.get(i)).getPassCapacity() 
                            * rentNumArray[i];
                }catch(Exception eCarPickup){
                    rentSinglePassTotal[i] = 0;
                }
            } // 双重try嵌套,如果车辆有载客功能,则存储一天的总载客量,否则存储0
            try{
                rentSingleCargoTotal[i] = 
                        ((CarTruck) carList.get(i)).getCargoCapacity() 
                        * rentNumArray[i];
            }catch(Exception eCarTruck){
                try{
                    rentSingleCargoTotal[i] = 
                            ((CarPickup) carList.get(i)).getCargoCapacity() 
                            * rentNumArray[i];
                }catch(Exception eCarPickup){
                    rentSingleCargoTotal[i] = 0;
                }
            } // 双重try嵌套,如果车辆有载货功能,则存储一天的总载货量,否则存储0
        }
        int rentTotal = IntStream.of(rentSinglePriceTotal).sum();
        int passCapacityTotal = IntStream.of(rentSinglePassTotal).sum();
        int cargoCapacityTotal = IntStream.of(rentSingleCargoTotal).sum();
        // 将三个数组的值分别相加求和
        System.out.println("总载客量(人/天):" + passCapacityTotal);
        System.out.println("总载货量(人/天):" + cargoCapacityTotal);
        System.out.println("订单总价(元):" + rentTotal); // 所有车的订单总价
    }

    // 读取用户输入方法
    private static String getInput() {
        Scanner input = new Scanner(System.in); // 新建Scanner
        try{
            return input.next();
        }catch (Exception e){
            return null; // 确保用户输入了内容
        }finally{
            input.nextLine(); // 防止下次调用时出现读取错误
        }
    }

    // 开始租车
    private static void rentCars(List carList) {
        printCarList(carList); // 打印现有的车辆列表
        List selectCars = selectCars(carList); // 用户开始选车
        System.out.println("这是您选定的租车列表:");
        printCarList(selectCars); // 打印选定的车辆列表
        int[] rentNumArray = rentNumArray(selectCars); // 用户对每一种车输入租车数量
        int[] rentDayArray = rentDayArray(selectCars); // 用户对每一种车输入租车天数
        printOrder(selectCars, rentNumArray, rentDayArray); // 打印最终订单
    }
}

各位有什么不明白的,可以留言。有什么改进建议,也可以留言。Thanks!

点击查看更多内容
87人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消