我的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修饰,这样生存周期就扩展到整个应用结束,数据也就不会丢失。



posted @ 2017-07-25 09:25  JackinHu  阅读(227)  评论(0编辑  收藏  举报