• 我的Java之旅——答答租车系统的改进


    之前的答答租车系统虽然可以实现项目的要求,但是没有用Java面向对象,今天用面向对象的三大特性封装继承多态来改进原来的代码。题目和之前的代码参考上篇博客,这里不再述说。




    改进后的代码:

    Vehicle.java

    /*车的父类,包含:
    车名和租金两个私有属性name和rent;
    访问属性的对应方法setter和getter;
    带参数的构造方法;
    打印属性值的方法Display();
     */
    
    public class Vehicle {
        private String name;         //车名
        private int rent;            //租金
    
        public Vehicle(String name, int rent) {
            this.name = name;
            this.rent = rent;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setRent(int rent) {
            this.rent = rent;
        }
    
        public int getRent() {
            return rent;
        }
    
        public void Display(int num) {
            System.out.println(num + "           " + this.getName() +
                    "            " + this.getRent());
        }
    }
    

    Cars.java

    /*汽车类,车的子类,包含:
    父类继承的属性和方法;
    新添加的私有属性载人数seatingCapacity;
    seatingCapacity对应的访问方法;
    Display()方法的重写;
    含参构造方法;
     */
    
    public class Cars extends Vehicle {
        private int seatingCapacity; //载人量
    
        public Cars(String name, int rent, int seatingCapacity) {
            super(name, rent);  //父类构造方法带参数,要用super显示调用
            this.setName(name);
            this.setRent(rent);
            this.seatingCapacity = seatingCapacity;
        }
    
        public int getSeatingCapacity() {
            return seatingCapacity;
        }
    
        public void Display(int num) {
            System.out.println(num + "           " + this.getName() +
                    "            " + this.getRent() + "          " +
                    "载人:" + seatingCapacity + "人" + "  ");
        }
    }
    

    Trucks.java

    /*卡车类,车的子类,包含:
    父类继承的属性和方法;
    新添加的私有属性载货数cargoCapacity;
    cargoCapacity对应的访问方法;
    Display()方法的重写;
    含参构造方法
     */
    
    public class Trucks extends Vehicle {
        private int cargoCapacity;   //载货量
    
        public int getCargoCapacity() {
            return cargoCapacity;
        }
    
        public Trucks(String name, int rent, int cargoCapacity) {
            super(name, rent);   //父类构造方法带参数,要用super显示调用
            this.setName(name);
            this.setRent(rent);
            this.cargoCapacity = cargoCapacity;
        }
    
        public void Display(int num) {
            System.out.println(num + "           " + this.getName() +
                    "            " + this.getRent() + "          " +
                    "载货:" + cargoCapacity + "吨");
        }
    }
    

    PickUpCars.java

    /*皮卡车类,车的子类,包含:
    父类继承的属性和方法;
    新添加的私有属性载人数seatingCapacity;
    seatingCapacity对应的访问方法;
    新添加的私有属性载货数cargoCapacity;
    cargoCapacity对应的访问方法;
    Display()方法的重写;
    含参构造方法
     */
    
    public class PickUpCars extends Vehicle {
        private int seatingCapacity; //载人量
        private int cargoCapacity;   //载货量
    
        public int getSeatingCapacity() {
            return seatingCapacity;
        }
    
        public int getCargoCapacity() {
            return cargoCapacity;
        }
    
        public PickUpCars(String name, int rent, int seatingCapacity, int cargoCapacity) {
            super(name, rent);  //父类构造方法带参数,要用super显示调用
            this.setName(name);
            this.setRent(rent);
            this.seatingCapacity = seatingCapacity;
            this.cargoCapacity = cargoCapacity;
        }
    
        public void Display(int num) {
            System.out.println(num + "           " + this.getName() +
                    "            " + this.getRent() + "          " +
                    "载人:" + seatingCapacity + "人" +
                    "  " + "载货:" + cargoCapacity + "吨");
        }
    }
    

    VehicleInfo.java

    /*车的信息类,记录可租用车的相关信息,
    包括车名,租金,载人数,载货量
    包含:
    记录车信息的方法information();
    私有常量KINDS,记录车的种类;
    KINDS的访问方法
     */
    
    public class VehicleInfo {
        Vehicle[] vehicle = new Vehicle[7];
        private final int KINDS = 6;
    
        public int getKINDS() {
            return KINDS;
        }
    
        /*添加可租用的车的信息*/
        public void information() {
            vehicle[1] = new Cars("奥迪A4 ", 500, 4);
            vehicle[2] = new Cars("马自达6", 400, 4);
            vehicle[3] = new PickUpCars("皮卡雪6", 450, 4, 2);
            vehicle[4] = new Cars("金龙   ", 800, 20);
            vehicle[5] = new Trucks("松花江 ", 400, 4);
            vehicle[6] = new Trucks("依维柯", 1000, 20);
        }
    }
    

    printInfo.java

    /*打印车的信息类,车的信息类的子类
    包含一个打印车信息的方法printInfo()
     */
    
    public class PrintInfo extends VehicleInfo {
    
        /*打印可租用的车的信息*/
        public void printInfo() {
            super.information();
            System.out.println("您可租车的类型及其价目表:");
            System.out.println("序号" + "        " + "汽车名称" + "        "
                    + "租金(元/天)" + "        " + "容量");
            int i;
            for (i = 1; i <= super.getKINDS(); i++) {
                vehicle[i].Display(i);
            }
        }
    }
    

    Renting.java

    /*租车类,包含:
    私有属性租车数量rentNum;
    私有属性租期rentDays;
    属性对应的访问方法;
    描述用户租车过程方法renting()
     */
    
    import java.util.Scanner;
    
    public class Renting {
        private int rentNum;       //记录租车的总数量
        private int rentDays;        //租期
        int[] record = {0, 0, 0, 0, 0, 0, 0};   //记录各种车的被租数量
    
        public int getRentNum() {
            return rentNum;
        }
    
        public int getRentDays() {
            return rentDays;
        }
    
        /*用户的租车过程*/
        public void renting() {
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入您要租车的数量:");
    
            if (scanner.hasNextInt()) {
                rentNum = scanner.nextInt();
            }
    
            int carNO = 0;    //选择的车序号
    
            for (int i = 1; i <= rentNum; i++) {
                System.out.println("请输入您要租的第" + i + "辆车的序号");
                if (scanner.hasNextInt()) {
                    carNO = scanner.nextInt();
                }
                record[carNO]++;
            }
    
            System.out.println("请输入租车天数:");
            if (scanner.hasNextInt()) {
                rentDays = scanner.nextInt();
            }
        }
    }
    

    PrintBills.java

    /*打印账单类,车信息类的子类,包含:
    私有属性总载人数totalPerson;
    私有属性总载货数totalCargo;
    私有属性总租金rental;
    打印账单的方法printBills()
     */
    
    public class PrintBills extends VehicleInfo {
        private int totalPerson = 0;   //总载人数
        private int totalCargo = 0;    //总载货数
        private int rental = 0;        //总租金
    
        /*打印账单*/
        public void printBills() {
            super.information();
            Renting rentobj = new Renting();
            rentobj.renting();
    
            System.out.println("************************************");
            System.out.println("您本次租车的账单如下:");
            System.out.println("******你本次共租车" + rentobj.getRentNum() + "辆:");
    
            System.out.println("汽车名字       出租数量");
            for (int i = 1; i <= super.getKINDS(); i++) {
                if (rentobj.record[i] != 0) {
                    System.out.println(vehicle[i].getName() + "            " + rentobj.record[i]);
                }
            }
    
            System.out.println("*****可载人的有:");
            for (int i = 1; i <= super.getKINDS(); i++) {
                if (rentobj.record[i] != 0) {
    
                    rental += vehicle[i].getRent();              //计算租一天总费用
    
                    if (vehicle[i] instanceof Cars) {
                        Cars car = (Cars) vehicle[i];
                        System.out.println(vehicle[i].getName());
                        totalPerson += car.getSeatingCapacity();
                    } else if (vehicle[i] instanceof PickUpCars) {
                        PickUpCars pickUpCar = (PickUpCars) vehicle[i];
                        System.out.println(vehicle[i].getName());
                        totalPerson += pickUpCar.getSeatingCapacity();
                    }
                }
            }
            System.out.println("共可载人:" + totalPerson + "人");
    
            System.out.println("*****可载货的有:");
            for (int i = 1; i <= super.getKINDS(); i++) {
                if (rentobj.record[i] != 0) {
                    if (vehicle[i] instanceof Trucks) {
                        Trucks truck = (Trucks) vehicle[i];
                        System.out.println(vehicle[i].getName());
                        totalCargo += truck.getCargoCapacity();
                    } else if (vehicle[i] instanceof PickUpCars) {
                        PickUpCars pickUpCar = (PickUpCars) vehicle[i];
                        System.out.println(vehicle[i].getName());
                        totalCargo += pickUpCar.getCargoCapacity();
                    }
                }
            }
    
            rental *= rentobj.getRentDays();                 //全部费用
    
            System.out.println("共可载货:" + totalCargo + "吨");
            System.out.println("*****租车总价格:" + rental + "元");
            System.out.println("************************************");
    
        }
    }
    

    Main.java

    import java.util.Scanner;
    
    public class Main {
        public static void main(String[] args) {
            Scanner scan = new Scanner(System.in);
    
            System.out.println("欢迎使用嗒嗒租车系统!");
            System.out.println("您是否需要租车?");
            System.out.println("是:请输入数字1  不是:请输入数字2");
    
            int ensure = 0;
            if (scan.hasNextInt()) {
                ensure = scan.nextInt();
            }
    
            //对错误输入的处理
            while (ensure != 1 && ensure != 2) {
                System.out.println("您的输入有误!请重新输入!");
                System.out.println("您是否需要租车?");
                System.out.println("是:请输入数字1  不是:请输入数字2");
                if (scan.hasNextInt()) {
                    ensure = scan.nextInt();
                }
            }
    
            //若用户输入数字1,则进入租车流程
            if (ensure == 1) {
                PrintInfo print = new PrintInfo();          //打印可租用的车的类型及价目表
                print.printInfo();
    
                PrintBills printBill = new PrintBills();    //打印账单
                printBill.printBills();
            }
        }
    }
    



    遇到的问题:

    在修改的过程中,一开始是把VehicleInfo类里的information()方法和Renting类里的renting()方法放在main()方法里面调用,然后调用两个打印方法printInfo()和printBills(),结果发现,这样在打印的时候vehicle[]和record[]数据丢失了,无法打印相关数据。后来几经尝试,把information()方法放在printInfo()里调用,同时在printBills()里面调用information()和renting()方法,在main()方法里只调用两个打印方法,这样就可以。也就是说,information()方法和renting()方法所产生的数据没有被保存,当要使用到相关数据时,都要再次调用这两个方法,重新生成数据。不知道这是为什么,求解答。


    关于上述问题的解答:

    vehicle[]和record[]的生存周期只在本类中,要打印时,之前的数据已经被回收,所以必须再次调用information()和renting()方法,重新生成数据。另一个解决办法是把vehicle[]和record[]用static修饰,这样生存周期就扩展到整个应用结束,数据也就不会丢失。



  • 相关阅读:
    systemd 启动 logstash 报错 找不到 JAVA_HOME
    Spring boot内置Tomcat的临时目录被删除导致文件上传不了-问题解析
    git error: Your local changes to the following files would be overwritten by merge:xxxxxx ,Please commit your changes or stash them before you merge.的phpstorm解决办法
    thinkcmf 忘记后台登陆密码的解决办法
    thinkcmf 5关闭后台验证码
    centos 7 IP不能访问nginx Failed connect to 185.239.226.111:80; No route to host解决办法
    thinphp5框架遇到 mkdir() Permission denied 解决办法
    mysql 命令行 备份 恢复数据
    centos 7 查询mysql 安装 运行位置
    pycharm 2018.1 激活
  • 原文地址:https://www.cnblogs.com/jiuweilinghu/p/7232256.html
Copyright © 2020-2023  润新知