之前的答答租车系统虽然可以实现项目的要求,但是没有用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修饰,这样生存周期就扩展到整个应用结束,数据也就不会丢失。



我的Java之旅——答答租车系统的改进的更多相关文章

  1. 我的Java之旅——答答租车系统

    今天试着写了一个新的程序,叫做"答答租车系统",是慕课网上的一个综合练习,戳我看原题. 项目要求截图如下: 我的代码(简单粗暴版): Vehicle.java public cla ...

  2. Java练习 SDUT-3349_答答租车系统(面向对象综合练习)

    答答租车系统(面向对象综合练习) Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 各位面向对象的小伙伴们,在学习了面向对 ...

  3. [代码审计]某租车系统JAVA代码审计[前台sql注入]

    0x00 前言 艰难徘徊这么久,终于迈出第一步,畏畏缩缩是阻碍大多数人前进的绊脚石,共勉. 系统是租车系统,这个系统是Adog师傅之前发在freebuf(http://www.freebuf.com/ ...

  4. Java学习笔记三十:Java小项目之租车系统

    Java小项目之租车系统 一:项目背景介绍: 根据所学知识,编写一个控制台版的“呱呱租车系统” 功能: 1.展示所有可租车辆: 2.选择车型.租车量: 3.展示租车清单,包含:总金额.总载货量以及其车 ...

  5. 基于JSP+Servlet开发在线租车系统 java 源码

    运行环境: 最好是java jdk 1.8,我们在这个平台上运行的.其他版本理论上也可以.IDE环境: Eclipse,Myeclipse,IDEA都可以tomcat环境: Tomcat 7.x,8. ...

  6. java学习之租车系统

    ​背景:有三种类型的车供给用户来租用​ ​要求:控制台用户交互界面,根据用户需求输出租车价格,结果如下: 创建租车类主要设计过程: 创建租车类 创建Car父类,包含四种属性成员,重写构造方法 创建三种 ...

  7. Java学习笔记(四)——好记性不如烂键盘(答答租车)

    根据所学知识,编写一个控制台版的租车系统. 功能: 1. 展示所有可租车辆 2. 选择车型.租车辆 3. 展示租车清单,包含:总金额.总载货量及其车型.总载人量及其车型 代码参考imooc中Java课 ...

  8. JAVA之旅(三十五)——完结篇,终于把JAVA写完了,真感概呐!

    JAVA之旅(三十五)--完结篇,终于把JAVA写完了,真感概呐! 这篇博文只是用来水经验的,写这个系列是因为我自己的java本身也不是特别好,所以重温了一下,但是手比较痒于是就写出了这三十多篇博客了 ...

  9. JAVA之旅(三十四)——自定义服务端,URLConnection,正则表达式特点,匹配,切割,替换,获取,网页爬虫

    JAVA之旅(三十四)--自定义服务端,URLConnection,正则表达式特点,匹配,切割,替换,获取,网页爬虫 我们接着来说网络编程,TCP 一.自定义服务端 我们直接写一个服务端,让本机去连接 ...

随机推荐

  1. 单击GridView进入编辑模式

    一直以来,Insus.NET在实现GridView编辑时,均是在每笔记录第一列或是最后一列放置编辑铵钮,点击编辑铵钮之后,进行编辑模式.本博文是使用另外方式,即是点击GridView记录行任一位置,进 ...

  2. COM线程模型的行为

    原文:https://msdn.microsoft.com/library/ms809971.aspx Behavior of the COM Threading Models COM线程模型的行为 ...

  3. SPA应用部署时首屏启动慢问题解决方案

    SPA应用部署时首屏启动慢问题解决方案 使用vuejs开发的单页应用,打包部署上线后,发现首屏启动时间达到了惊人的10s左右,于是开始优化,目前使用到的总结如下: 巧用webpack插件 1.抽取cs ...

  4. MFC动态时间表示法——strtime函数

    %a 星期几的简写 %A 星期几的全称 %b 月分的简写 %B 月份的全称 %c 标准的日期的时间串 %C 年份的后两位数字 %d 十进制表示的每月的第几天 %D 月/天/年 %e 在两字符域中,十进 ...

  5. 并发编程之ThreadLocal源码分析

    当访问共享的可变数据时,通常需要使用同步.一种避免同步的方式就是不共享数据,仅在单线程内部访问数据,就不需要同步.该技术称之为线程封闭. 当数据封装到线程内部,即使该数据不是线程安全的,也会实现自动线 ...

  6. 深入理解java虚拟机---java内存区域与内存溢出异常---1内存结构

    本文来源于翁舒航的博客,点击即可跳转原文观看!!!(被转载或者拷贝走的内容可能缺失图片.视频等原文的内容) 若网站将链接屏蔽,可直接拷贝原文链接到地址栏跳转观看,原文链接:https://www.cn ...

  7. JAVA非静态成员变量之死循环

    1.非静态成员变量 当成员变量为非静态成员变量且对当前类进行实例化时,将会产生死循环 例子: public class ConstructorCls { private ConstructorCls ...

  8. Invoke 和 BeginInvoke 的区别

    在Invoke或者BeginInvoke的使用中无一例外地使用了委托Delegate 一.为什么Control类提供了Invoke和BeginInvoke机制? 关于这个问题的最主要的原因已经是dot ...

  9. element-ui中使用font-awesome字体图标

    element-ui提供的字体图标是很少的,所以我们需要集成其它图标来使用,nodejs的集成官方有说明,这里说明一下非nodejs开发集成图标 首先下载fontawesome,需要更改里面图标前缀, ...

  10. vue如何实现代码打包分离(按需加载)

    在vue中使用import()来代替require.ensure()实现代码打包分离 一.require.ensure() 方法来实现代码打包分离 require.ensure() 是 webpack ...