一、实验目标
本实验的目标是将面向对象基础和高级开发融合起来,让学生能运用所学知识解决复杂工程问题。支撑计算机类专业基础实践能力、专业核心能力、综合创新能力的培养。
二、实验要求
本实验要求掌握基于面向对象的综合软件开发流程和相关技术。完成面向对象综合实验的实验内容,掌握计算机及相关方法对复杂的工程问题进行分析的方法,具备使用现代技术及相关工具的能力;掌握设计相应的实验方案的方法,具备应用复杂计算系统开发的能力, 并在设计和开发过程中体现出创新意识。
三、汽车租赁系统
1、请设计并实现一个汽车租赁系统V4.0(题目可以自拟),需求如下。
1)系统分为管理员和用户角色登录,不同的角色有不同的权限操作;
2)管理员功能:查看、添加、修改和删除车辆信息,查看营业额;
3)用户功能(VIP用户):登录后,可以查看车辆、租车、换车,模拟付款等;
4)车辆:基础版(只考虑小汽车Car),高级版(考虑三种车型Car,Bus, Trunk);
5)存储:用文件或数据库进行数据存储。
2、提交材料清单和评分细则
1)系统说明书(50分)
继承、多态、集合框架、异常处理、多线程、工厂模式
Account类
package com.test.carRentalSystem;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
public class Account implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
int ID;
String name;
String passwd;
boolean power;
List<Car> borrowList;
public Account(int ID, String name, String passwd, boolean power, List<Car> borrowList) {
this.ID = ID;
this.name = name;
this.passwd = passwd;
this.power = power;
this.borrowList = borrowList;
}
public int getID() {
return ID;
}
public void setID(int ID) {
this.ID = ID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public boolean isPower() {
return power;
}
public void setPower(boolean power) {
this.power = power;
}
public List<Car> getBorrowList() {
return borrowList;
}
public void setBorrowList(List<Car> borrowList) {
this.borrowList = borrowList;
}
@Override
public String toString() {
return "Account{" +
"ID='" + ID + '\'' +
", name='" + name + '\'' +
", passwd='" + passwd + '\'' +
", power=" + power +
", borrowList=" + borrowList +
'}';
}
}
Car类
package com.test.carRentalSystem;
import java.io.Serial;
import java.io.Serializable;
public class Car implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private String number;//车牌
private String brand;//品牌
private int rent;//租金
private boolean isRented;//是否出租
private String rentalTime;//出租时间
private double totalRent;//出租后的租金
public double getTotalRent() {
return totalRent;
}
public void setTotalRent(double totalRent) {
this.totalRent = totalRent;
}
public boolean isRented() {
return isRented;
}
public void setRented(boolean rented) {
isRented = rented;
}
public String getRentalTime() {
return rentalTime;
}
public void setRentalTime(String rentalTime) {
this.rentalTime = rentalTime;
}
public String getNumber() {
return number;
}
public void setNumber(String index) {
this.number = index;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public int getRent() {
return rent;
}
public void setRent(int index) {
this.rent = index;
}
}
FileHelper类
package com.test.carRentalSystem;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class FileHelper {
private String fileName;// ./carRentalSystem/?
public FileHelper(){
}
public FileHelper(String fileName){
this.fileName=fileName;
}
/*
* 将car对象保存到文件中
* params:
* car:Car类对象
*/
public void saveObjToFileBus(List<Bus> cars){
try {
//写对象流的对象
ObjectOutputStream oos;
for(Bus car : cars) {
oos = new ObjectOutputStream(new FileOutputStream(fileName + "\\" + car.getBrand() + " - " + car.getNumber() + ".ser"));
oos.writeObject(car);
oos.close(); //关闭文件流
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void saveObjToFileSedan(List<Sedan> cars){
try {
//写对象流的对象
ObjectOutputStream oos;
for(Sedan car : cars) {
oos = new ObjectOutputStream(new FileOutputStream(fileName + "\\" + car.getBrand() + " - " + car.getNumber() + ".ser"));
oos.writeObject(car);
oos.close(); //关闭文件流
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void saveObjToFileAccount(List<Account> accounts){
try {
//写对象流的对象
ObjectOutputStream oos;
for(Account account : accounts) {
oos = new ObjectOutputStream(new FileOutputStream(fileName + "\\" + account.getID() + " - " + account.getName() + ".ser"));
oos.writeObject(account);
oos.close(); //关闭文件流
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
* 从文件中读出对象,并且返回Car对象
*/
public List<?> getObjFromFile(){
File src = new File(fileName);
File[] files = src.listFiles();
if(fileName.endsWith("n")) {
List<Sedan> list = new ArrayList<>();
try {
ObjectInputStream ois;
assert files != null;
for(File file : files) {
ois = new ObjectInputStream(new FileInputStream(fileName + "\\" + file.getName()));
Sedan sedan = (Sedan) ois.readObject(); //读出对象
ois.close();
list.add(sedan);
}
return list; //返回对象
} catch (ClassNotFoundException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else if(fileName.endsWith("s")) {
List<Bus> list = new ArrayList<>();
try {
ObjectInputStream ois;
assert files != null;
for(File file : files) {
ois = new ObjectInputStream(new FileInputStream(fileName + "\\" + file.getName()));
Bus bus = (Bus) ois.readObject(); //读出对象
ois.close();
list.add(bus);
}
return list; //返回对象
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else {
List<Account> list = new ArrayList<>();
try {
ObjectInputStream ois;
assert files != null;
for(File file : files) {
ois = new ObjectInputStream(new FileInputStream(fileName + "\\" + file.getName()));
Account account = (Account) ois.readObject(); //读出对象
ois.close();
list.add(account);
}
return list; //返回对象
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
}
Sedan类
package com.test.carRentalSystem;
public class Sedan extends Car{
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Bus类
package com.test.carRentalSystem;
public class Bus extends Car{
private int seats;
public int getSeats() {
return seats;
}
public void setSeats(int seats) {
this.seats = seats;
}
}
Cilent端
package com.test.carRentalSystem;
import javax.xml.crypto.Data;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Date;
public class Client {
// TODO 第一次使用时:
// 此处应从Bus/Sedan处复制绝对路径
static final String busFileName = "com\\test\\carRentalSystem\\Bus";
static final String sedanFileName = "com\\test\\carRentalSystem\\Sedan";
static final String accountClient = "com\\test\\carRentalSystem\\Account";
static List<Sedan> sedans;
static List<Bus> buses;
static List<Account> accounts;
static int index;
static {
FileHelper fileHelperSedan = new FileHelper(sedanFileName);
FileHelper fileHelperBus = new FileHelper(busFileName);
FileHelper fileHelperAccount = new FileHelper(accountClient);
SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");
// 判断是否租赁时间到期,到期则设置车辆信息为未租赁
try {
Class<?> fileHelperClass = FileHelper.class;
Method getObjFromFile = fileHelperClass.getMethod("getObjFromFile");
sedans = (List<Sedan>) getObjFromFile.invoke(fileHelperSedan);
buses = (List<Bus>) getObjFromFile.invoke(fileHelperBus);
accounts = (List<Account>) getObjFromFile.invoke(fileHelperAccount);
// 获取全局ID以自增.
index = accounts.get(accounts.size() - 1).ID;
Date date0 = new Date();
if(sedans != null) for (Sedan sedan : sedans) {
String[] split = new String[0];
if(sedan.getRentalTime() != null) split = sedan.getRentalTime().split("---");
if(sedan.getRentalTime() != null && sdf.parse(split[1]).compareTo(date0) < 0) {
sedan.setRented(false);
sedan.setRentalTime("");
}
}
if(buses != null) for (Bus bus : buses) {
String[] split = new String[0];
if(bus.getRentalTime() != null) split = bus.getRentalTime().split("---");
if(bus.getRentalTime() != null) split = bus.getRentalTime().split("---");
if(bus.getRentalTime() != null && sdf.parse(split[1]).compareTo(date0) < 0) {
bus.setRented(false);
bus.setRentalTime("");
}
}
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException | ParseException e) {
throw new RuntimeException(e);
}
}
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
System.out.println("=========欢迎光临秋名山汽车租赁公司=========");
System.out.println("请先登录或者注册:");
System.out.print("1.登录 ");
System.out.print("2.注册 ");
System.out.println("'其他'.退出");
Account ac = null;
String in = sc.next();
if(in.equals("1")) {
String ID;
String password;
boolean flag = true;
while (flag) {
System.out.println("请输入账号:");
ID = sc.next();
System.out.println("请输入密码:");
password = sc.next();
for (Account account : accounts) {
if(account.name.equals(ID) && account.passwd.equals(password)) {
System.out.println("登陆成功!");
flag = false;
ac = account;
break;
}
}
if(flag) {
System.out.println("账号或密码错误!");
System.out.println("输入0退出或继续输入");
try{
if(sc.next().equals("0")) System.exit(0);
}
catch (Exception e) {}
}
}
}
else if(in.equals("2")) {
String name = "";
String passwd = "";
String rePasswd = "1";
boolean flag = true;
while (flag) {
System.out.println("请输入账号:");
name = sc.next();
flag = false;
for (Account account : accounts) {
if(account.name.equals(name)) {
System.out.println("该账号已存在!");
flag = true;
break;
}
}
}
while (!passwd.equals(rePasswd)) {
System.out.println("请输入密码:");
passwd = sc.next();
System.out.println("请再次输入密码:");
rePasswd = sc.next();
if(!passwd.equals(rePasswd)) System.out.println("密码前后不一致");
}
System.out.println("注册成功!");
Account account = new Account(++index, name, passwd, false, null);
Class<?> fileHelperClass = FileHelper.class;
accounts.add(account);
FileHelper fileHelper = new FileHelper(accountClient);
Method saveObjToFileAccount = fileHelperClass.getMethod("saveObjToFileAccount", List.class);
saveObjToFileAccount.invoke(fileHelper, accounts);
}else System.exit(0);
System.out.print("请选择你要租赁的汽车类型:");
System.out.print("1.轿车 ");
System.out.print("2.客车 ");
System.out.println("0.退出");
int input = sc.nextInt();
if (input == 1){
int cnt = 0;
for(int i = 1; i <= sedans.size(); i++) {
if(!sedans.get(i - 1).isRented()) {
System.out.println(i + ". " + sedans.get(i - 1).getBrand() + "\t\t" + sedans.get(i - 1).getType() + "\t\t" + sedans.get(i - 1).getRent() + "元/天");
cnt ++;
}
}
if(cnt == 0) {
System.out.println("目前没有车辆被租赁!");
System.out.println("按任意键继续...");
try{System.in.read();}
catch (Exception e) {}
return;
}
System.out.println("请输入要租赁的车辆编号:");
int index = sc.nextInt();
Sedan sedan = sedans.get(index - 1);
if(sedan.isRented()) {
System.out.println("该车已被租赁!");
return;
}
System.out.println("==========================");
System.out.println("租赁时间 >= 7 DAYS | 10% OFF!");
System.out.println("租赁时间 >= 30 DAYS | 20% OFF!");
System.out.println("租赁时间 >= 150 DAYS | 30% OFF!");
System.out.println("==========================");
int days;
double cost;
while (true) {
System.out.println("请输入租用时间(天):");
days = sc.nextInt();
if(days >= 7 && days < 30) {
cost = sedan.getRent() * days * 0.9;
break;
}else if(days >= 30 && days < 150) {
cost = sedan.getRent() * days * 0.8;
break;
}else if(days >= 150) {
cost = sedan.getRent() * days * 0.7;
break;
}else {
System.out.println("请输入正确时间!");
System.out.println("按任意键继续...");
try{System.in.read();}
catch (Exception e) {}
}
}
System.out.println("您的费用是:" + cost);
while (true) {
System.out.println("是(1)否(0)支付?");
int isPay = sc.nextInt();
if(isPay == 1) {
ObjectOutputStream oos;
System.out.println("支付成功!");
SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");
Date date0 = new Date();
Date date1 = new Date(date0.getTime() + 86400000L * days); //86400000
sedan.setRentalTime(sdf.format(date0) + "---" + sdf.format(date1));
System.out.println("您的车牌号是" + sedan.getNumber() + "\n" + "租赁时间是" + sedan.getRentalTime());
assert ac != null;
ac.getBorrowList().add(sedan);
sedan.setRented(true);
sedan.setTotalRent(cost);
Class<?> fileHelperClass = FileHelper.class;
// 保存
/*oos = new ObjectOutputStream(new FileOutputStream(sedanFileName + "\\" + sedan.getBrand() + " - " + sedan.getNumber() + ".txt"));*/
FileHelper fileHelper = new FileHelper(sedanFileName);
Method saveObjToFile = fileHelperClass.getMethod("saveObjToFileSedan", List.class);
saveObjToFile.invoke(fileHelper, sedans);
/* oos.writeObject(sedan);
oos.close();*/
System.out.println(sedan.getBrand() + " - " + sedan.getType() + " 成功保存!");
System.out.println("按任意键继续...");
try{System.in.read();}
catch (Exception e) {}
break;
}else if(isPay == 0) {
System.out.println("未支付!");
System.out.println("按任意键继续...");
try{System.in.read();}
catch (Exception e) {}
break;
}else {
System.out.println("请输入正确数字!");
System.out.println("按任意键继续...");
try{System.in.read();}
catch (Exception e) {}
}
}
}else if(input == 2) {
int cnt = 0;
for(int i = 1; i <= buses.size(); i++) {
if(!buses.get(i - 1).isRented()) {
System.out.println(i + ". " + buses.get(i - 1).getBrand() + "\t\t" + buses.get(i - 1).getSeats() + "\t\t" + buses.get(i - 1).getRent() + "元/天");
cnt ++;
}
}
if(cnt == 0) {
System.out.println("目前没有车辆被租赁!");
System.out.println("按任意键继续...");
try{System.in.read();}
catch (Exception e) {}
return;
}
System.out.println("请输入要租赁的车辆编号:");
int index = sc.nextInt();
Bus bus = buses.get(index - 1);
System.out.println("============================");
System.out.println("租赁时间 >= 3 DAYS | 10% OFF!");
System.out.println("租赁时间 >= 7 DAYS | 20% OFF!");
System.out.println("租赁时间 >= 30 DAYS | 30% OFF!");
System.out.println("租赁时间 >= 150 DAYS | 40% OFF!");
System.out.println("============================");
System.out.println("请输入租用时间(天):");
int days = sc.nextInt();
double cost;
while (true) {
if(days >= 3 && days < 7) {
cost = bus.getRent() * days * 0.9;
break;
}else if(days >= 7 && days < 30) {
cost = bus.getRent() * days * 0.8;
break;
}else if(days >= 30 && days < 150) {
cost = bus.getRent() * days * 0.7;
break;
}else if(days >= 150) {
cost = bus.getRent() * days * 0.6;
break;
}else {
System.out.println("请输入正确时间!");
System.out.println("按任意键继续...");
try{System.in.read();}
catch (Exception e) {}
}
}
System.out.println("您的费用是:" + cost);
while (true) {
System.out.println("是(1)否(0)支付?");
int isPay = sc.nextInt();
if(isPay == 1) {
System.out.println("支付成功!");
SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");
Date date0 = new Date();
Date date1 = new Date(date0.getTime() + 86400000L * days); //86400000
bus.setRentalTime(sdf.format(date0) + "---" + sdf.format(date1));
System.out.println("您的车牌号是" + bus.getNumber() + "\n" + "租赁时间是" + bus.getRentalTime());
bus.setRented(true);
assert ac != null;
ac.getBorrowList().add(bus);
System.out.println("按任意键继续...");
try{System.in.read();}
catch (Exception e) {}
break;
}else if(isPay == 0) {
System.out.println("未支付!");
System.out.println("按任意键继续...");
try{System.in.read();}
catch (Exception e) {}
break;
}else {
System.out.println("请输入正确数字!");
System.out.println("按任意键继续...");
try{System.in.read();}
catch (Exception e) {}
}
}
}else if(input == 0) System.exit(1);
}
}
Control端
package com.test.carRentalSystem;
import com.test.carRentalSystem.utils.MD5;
import java.io.*;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Pattern;
public class Control {
// TODO 第一次使用时:
// 此处应从Bus/Sedan/Account处复制绝对路径
static final String busFileName = "com\\test\\carRentalSystem\\Bus";
static final String sedanFileName = "com\\test\\carRentalSystem\\Sedan";
static final String accountClient = "com\\test\\carRentalSystem\\Account";
static Scanner sc = new Scanner(System.in);
static List<Sedan> sedans;
static List<Bus> buses;
static List<Account> accounts;
static int index;
// 单向MD5加密验证码
static String conform = "a218779d1b752827";
static {
Class<?> fileHelperClass = FileHelper.class;
FileHelper fileHelperSedan = new FileHelper(sedanFileName);
FileHelper fileHelperBus = new FileHelper(busFileName);
FileHelper fileHelperAccount = new FileHelper(accountClient);
try {
Method getObjFromFile = fileHelperClass.getMethod("getObjFromFile");
sedans = (List<Sedan>) getObjFromFile.invoke(fileHelperSedan);
buses = (List<Bus>) getObjFromFile.invoke(fileHelperBus);
accounts = (List<Account>) getObjFromFile.invoke(fileHelperAccount);
// 获取全局ID以自增.
index = accounts.get(accounts.size() - 1).ID;
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
while (true) {
System.out.println("=======欢迎来到汽车租赁系统控制端=======");
System.out.println("请先登录或者注册:");
System.out.print("1.登录 ");
System.out.print("2.注册 ");
System.out.println("'其他'.退出");
String in = sc.next();
if(in.equals("1")) {
String ID;
String password;
Account ac = null;
boolean flag = true;
while (flag) {
System.out.println("请输入账号:");
ID = sc.next();
System.out.println("请输入密码:");
password = sc.next();
for (Account account : accounts) {
if(account.name.equals(ID) && account.passwd.equals(password)) {
ac = account;
flag = false;
break;
}
}
if(flag) {
System.out.println("账号或密码错误!");
System.out.println("输入0退出或继续输入");
try{
if(sc.next().equals("0")) System.exit(0);
}
catch (Exception e) {}
}
}
if(!ac.isPower()) {
System.out.println("该账号没有权限");
System.exit(1);
}else {
System.out.println("登陆成功!");
}
}
else if(in.equals("2")) {
String name = "";
String passwd = "";
String rePasswd = "1";
boolean flag = true;
while (flag) {
System.out.println("请输入账号:");
name = sc.next();
flag = false;
for (Account account : accounts) {
if(account.name.equals(name)) {
System.out.println("该账号已存在!");
flag = true;
break;
}
}
}
while (!passwd.equals(rePasswd)) {
System.out.println("请输入密码:");
passwd = sc.next();
System.out.println("请再次输入密码:");
rePasswd = sc.next();
if(!passwd.equals(rePasswd)) System.out.println("密码前后不一致");
}
System.out.println("请输入验证码:");
String reconfirm = "";
while (!MD5.getMD5(reconfirm).equals(conform)) {
reconfirm = sc.next();
if(MD5.getMD5(reconfirm).equals(conform)) {
break;
}else System.out.println("验证码错误!");
System.out.println("输入0退出或继续输入验证码");
try{
if(sc.next().equals("0")) System.exit(0);
}
catch (Exception e) {}
}
System.out.println("注册成功!");
Account account = new Account(++index, name, passwd, true, null);
Class<?> fileHelperClass = FileHelper.class;
accounts.add(account);
FileHelper fileHelper = new FileHelper(accountClient);
Method saveObjToFileAccount = fileHelperClass.getMethod("saveObjToFileAccount", List.class);
saveObjToFileAccount.invoke(fileHelper, accounts);
}
else System.exit(0);
while (true) {
System.out.println("1.录入车辆");
System.out.println("2.删除车辆");
System.out.println("3.修改车辆");
System.out.println("4.查询流水");
System.out.println("9.退出系统");
int input = sc.nextInt();
if(input == 1) {
try {
inputCar();
} catch (IOException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}else if(input == 2) {
while (true) {
System.out.println("请输入要删除的车的车牌号:");
String Num = sc.next();
if(!deleteCar(Num)) {
System.out.println("未查到该车辆!");
}else {
System.out.println("该车辆已删除!");
System.out.println("按任意键继续...");
try{System.in.read();}
catch (Exception e) {}
break;
}
}
}else if(input == 3) {
System.out.println("请输入要修改的车的车牌号:");
String Num = sc.next();
if(changeCar(Num)) System.out.println("操作已完成!");
else System.out.println("未查到该车牌号!");
System.out.println("按任意键继续...");
try{System.in.read();}
catch (Exception ignored) {}
}else if(input == 4) {
System.out.println("请输入要查询的车辆类型:0.轿车 1.客车 9.退出");
double cost = 0;
while (true) {
int num = sc.nextInt();
if(num == 0) {
for (Sedan sedan : sedans) {
if(sedan.isRented()) cost += sedan.getTotalRent();
}
System.out.println("轿车流水为:" + cost);
break;
}else if(num == 1) {
for (Bus bus : buses) {
if(bus.isRented()) cost += bus.getTotalRent();
}
System.out.println("客车流水为:" + cost);
break;
}else if(num == 9) {
break;
}
}
}
else if(input == 9) {
System.out.println("登出系统");
System.exit(0);
}else {
System.out.println("请输入正确的数字!");
}
}
}
}
private static boolean changeCar(String Number) {
for (Sedan sedan : sedans) {
if(sedan.getNumber().equals(Number)) {
while (true) {
System.out.println("请选择要修改的项目:");
System.out.println("1.租金(元/天)");
System.out.println("2.品牌");
System.out.println("3.型号");
System.out.println("9.返回");
int input = sc.nextInt();
if(input == 1) {
System.out.println("请输入租金:");
sedan.setRent(sc.nextInt());
}else if(input == 2) {
System.out.println("请输入品牌:");
sedan.setBrand(sc.next());
}else if(input == 3) {
System.out.println("请输入型号:");
sedan.setType(sc.next());
}else if(input == 9) {
return true;
}else {
System.out.println("请输入正确的号码!");
}
}
}
}
for (Bus bus : buses) {
if(bus.getNumber().equals(Number)) {
while (true) {
System.out.println("请选择要修改的项目:");
System.out.println("1.租金");
System.out.println("2.品牌");
System.out.println("3.座位数");
System.out.println("9.返回");
int input = sc.nextInt();
if(input == 1) {
System.out.println("请输入租金(元/天):");
bus.setRent(sc.nextInt());
}else if(input == 2) {
System.out.println("请输入品牌:");
bus.setBrand(sc.next());
}else if(input == 3) {
System.out.println("请输入座位数:");
bus.setSeats(sc.nextInt());
}else if (input == 9) {
return true;
} else {
System.out.println("请输入正确的号码!");
}
}
}
}
return false;
}
private static boolean deleteCar(String Number) {
for (Sedan sedan : sedans) {
if(sedan.getNumber().equals(Number)) {
File file = new File(sedanFileName + "\\" + sedan.getBrand() + " - " + sedan.getNumber() + ".ser");
sedans.remove(sedan);
return file.delete();
}
}
for (Bus bus : buses) {
if(bus.getNumber().equals(Number)) {
File file = new File(busFileName + "\\" + bus.getBrand() + " - " + bus.getNumber() + ".ser");
buses.remove(bus);
return file.delete();
}
}
return false;
}
@MyTest
private static void inputCar() throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
ObjectOutputStream oos;
System.out.println("请输入车辆类型:");
System.out.println("1.轿车");
System.out.println("2.客车");
int type = sc.nextInt();
if(type == 1) {
boolean flag = true;
Sedan sedan = new Sedan();
System.out.println("请输入品牌:");
while(flag) {
String b = sc.next();
if(checkFormat(b, false)) {
sedan.setBrand(b);
flag = false;
}else {
System.out.println("请输入正确的格式!");
System.out.println("请输入品牌:");
}
}
flag = true;
System.out.println("请输入型号:");
while(flag) {
String c = sc.next();
if(checkFormat(c, false)) {
sedan.setType(c);
flag = false;
}else {
System.out.println("请输入正确的格式!");
System.out.println("请输入品牌:");
}
}
while (true) {
System.out.println("请输入车牌:");
String number = sc.next();
if(checkFormat(number, true)) {
sedan.setNumber(number);
break;
}else{
System.out.println("请输入合法车牌!");
}
}
System.out.println("请输入租金(元/天):");
// 反射FileHelper以执行method
sedan.setRent(sc.nextInt());
sedan.setRented(false);
oos = new ObjectOutputStream(new FileOutputStream(sedanFileName + "\\" + sedan.getBrand() + " - " + sedan.getNumber() + ".ser"));
Class<?> fileHelperClass = FileHelper.class;
FileHelper fileHelper = new FileHelper(sedanFileName);
Method saveObjToFile = fileHelperClass.getMethod("saveObjToFileSedan", List.class);
saveObjToFile.invoke(fileHelper, sedans);
oos.writeObject(sedan);
oos.close();
System.out.println(sedan.getBrand() + " - " + sedan.getType() + " 成功保存!");
}else if(type == 2) {
Bus bus = new Bus();
System.out.println("请输入品牌:");
bus.setBrand(sc.next());
while (true) {
System.out.println("请输入座位数:");
String num = sc.next();
int n = 0;
try {
n = Integer.parseInt(num);
}catch (NumberFormatException e) {
System.out.println("请输入正确的数量!");
}
if(n != 0) {
bus.setSeats(n);
break;
}
}
while (true) {
System.out.println("请输入车牌:");
String number = sc.next();
if(checkFormat(number, true)) {
bus.setNumber(number);
break;
}else{
System.out.println("请输入合法车牌!");
}
}
System.out.println("请输入租金(元/天):");
// 反射FileHelper以执行method
bus.setRent(sc.nextInt());
oos = new ObjectOutputStream(new FileOutputStream(busFileName+ "\\" + bus.getBrand() + " - " + bus.getNumber() + ".ser"));
Class<?> fileHelperClass = FileHelper.class;
FileHelper fileHelper = new FileHelper(sedanFileName);
Method saveObjToFile = fileHelperClass.getMethod("saveObjToFileBus", List.class);
saveObjToFile.invoke(fileHelper, buses);
oos.writeObject(bus);
oos.close();
System.out.println(bus.getBrand() + " - " + bus.getSeats() + " 成功保存!");
}
}
/**
*
* @param content 用于正则匹配的String
* @param flag true:判断车牌号; false:判断是否为合法文件名
* @return
*/
public static boolean checkFormat(String content, boolean flag) {
String pattern1 = "([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]{1}(([A-HJ-Z]{1}[A-HJ-NP-Z0-9]{5})|([A-HJ-Z]{1}(([DF]{1}[A-HJ-NP-Z0-9]{1}[0-9]{4})|([0-9]{5}[DF]{1})))|([A-HJ-Z]{1}[A-D0-9]{1}[0-9]{3}警)))|([0-9]{6}使)|((([沪粤川云桂鄂陕蒙藏黑辽渝]{1}A)|鲁B|闽D|蒙E|蒙H)[0-9]{4}领)|(WJ[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼·•]{1}[0-9]{4}[TDSHBXJ0-9]{1})|([VKHBSLJNGCE]{1}[A-DJ-PR-TVY]{1}[0-9]{5})";
String pattern2 = "[^\\s\\\\/:\\*\\?\\\"<>\\|](\\x20|[^\\s\\\\/:\\*\\?\\\"<>\\|])*[^\\s\\\\/:\\*\\?\\\"<>\\|\\.]$";
if(flag) return Pattern.matches(pattern1, content);
else return Pattern.matches(pattern2, content);
}
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface MyTest{
}
- 汽车租赁系统的需求分析;(5分)
- 根据需求分析,画出系统功能结构图;(5分)
- 结合需求分析和功能模块,画出系统的类图;(20分,按照设计有对应类代码,缺少一个扣5分,直到该项扣完为止)
- 系统测试,合理设置测试用例,验证系统是否正常运行。(20分)
- 代码实现(20分)
- 面向对象设计方法和Java特性考察点(15分,每一个3分,加满为止)
四、收获,体会及问题
(请详细书写,写得越详细、越个性化、越真实越好,否则指导教师不知道你做这个实验的心路历程,也就无法充分地判断你是否是独立完成的这个实验、你是否在做这个实验时进行了认真仔细地思考、通过这个实验你是否在实践能力上得到了提高)
首先,在最基础上的控制台系统上做文章,我想,光以pdf文件中的简单功能还满足不了,于是我使用了客户端与服务端分开的设计,并加入了保存功能,也就是说在服务端可以进行以下操作
在此过程中,我利用了不同的方式来完善内容与安全性,比如:
以下代码利用了try...catch来捕捉NumberFormatException;添加了checkFormat方法.
完成一系列输入方法后,会进行保存——通过fileHelper类进行。
fileHelper类中包含了文件加载和保存。
加载是通过读取相应的序列化文件来加载相应类;保存是通过将类输出为序列化文件。在此基础上,我设计了一个ArrayList<?>类用于保存不同类型车辆的链表以加快类的读取输出速度。
在客户端中,加载ArrayList时会进行判断——如果现在的时间大于租车的截止时间则将该车对象的租赁状态设置为false,并重置rentalTime。
以下是客户端。
完成租赁后会进行保存并在可租赁车库中不显示,如在第一张图中只显示了序号2的车辆。
登录和注册:
在启用用户对象前,在静态代码块中将所有用户添加至List中以方便调用。
服务端采用单向MD5验证码的方式来确实注册者是否为管理员,如下图:
用户端可以登录管理员和普通用户,而服务端只能登录管理员,如图:
用户保存方式依旧是序列化对象,但共同保存到了一个文件夹中
其中序号自增的实现方法为
先获取最后一个对象的ID号,将其设置为全局变量,再在此基础上自增。
五、附件
请将系统说明书、源代码一起提交,同时准备综合实验展示。
请加wx:Rhinox137获取源码
系统说明书
需求分析:描述系统要实现的基本功能
用户:谁会用这个功能?
汽车租赁
场景:用户在什么情况下会用?
汽车租赁
问题:用户在上述场景下,碰到什么问题?
找不到
方案:系统为用户提供什么样的解决方案?
找得到
- 功能结构图
功能结构图参考如下,列出该系统的子功能模块,并阐述每个功能。
- 类设计、类图
根据前面的需求分析和功能划分,确定类,画出对应的类图,并简单说明。
- 系统测试设计
给出系统的测试用例,使用测试用例表。
用例编号 | 用例标题 | 输入数据 | 预期结果 |
LU1 | 对用户名和密码进 行输入 | 用户名:admin 密码:123 | 正确进入系统 |
普通用户1 | 对用户名和密码进 行输入 | 用户名:a123 密码:123 | 正确进入系统 |