此文为记录一次Java课的小作业所写,适合停留在Java基础的新手练习。
随着家庭购买汽车的增加,停车场车位紧张的问题越来越突出。请根据题目要求完成简单的车位管理程序。 1.停车场有若干停车位(为说明问题,假定为n个,可扩),每个位置可以存放不同种类的的汽车,包括卡车Truck,客车Carriage和小轿车Car,但同一时刻一个位置只能存放0或1辆汽车。 2.管理系统模拟实际车辆停车的情况:新来车辆时如果有空位,按顺序为该车分配停车位;车辆开走时,按停车场的收费标准交纳相应停车费(假定停车场能获取车辆对象的类别);统计各类车辆的数量。 3.定义描述停车场的类Park,其中有n个位置用于存放各类车辆。 4.定义基类Automobile:①驾驶员;②车牌号(字符串)、车辆类别(分为Car、Truck、Carriage);③String getMobileMessage()车辆相关信息;④parking()泊车、start()开车、pause()暂停等。 5.定义派生类Truck,Carriage和Car,这些车辆除了拥有车牌号(字符串)、车辆已使用年数(整数)之外, Truck还拥有载重量(浮点数,单位吨)属性,Carriage还拥有乘坐人数(整数,单位人)属性, Car还拥有排气量(浮点数,单位L)属性。 6.每辆车上只有一驾驶员,驾驶员按停车场的收费要求支付费用;按现实停车场的场景来模拟需有的动作(方法):在出口前停车、付费、开车、泊车等。 7.收费标准:其中Truck收费2元/小时,Carriage收费1.5元/小时,Car收费1元/小时。 8.测试上述所要求的各种功能,即根据菜单命令为新来车辆分配停车位、开走车辆(输入车位编号)时付费、显示停车场中各类车辆的数量。
无论是Car,Truck还是Carrige,都是继承基类AutoMoblie,它抽象了各种车的公共部分,同时Car,Truck和Carrige都有自己独有的属性,同时基类中有私有属性Type,用来标识车是什么类型的车,同时覆写了getMobileMessage方法(用来返回具体的字符串)
车有私有属性people,即AutoMoblie聚合了People类,主要用来模拟人坐进车中这么一个操作;同时People类也依赖于AutoMoblie类,主要体现在调用people方法时,也会相应的调用车的方法。
停车场内部维护了两个ArrayList数组,一个用来存储车位信息,一个用来存储各车位计时
每当车辆进入时,程序会自动检查automobiles,如果有空车位则进入,并且times数组开始计时,否则则对数组进行扩容已达到停车场扩容的效果。
Park类中有个display方法,用于展示当前停车场的具体情况
具体效果如下:
Park类中有个获取真实容量的方法,因为Park类中使用ArrayList来存储数据,但是其中真实数组elementData是私有的并不对外提供操作的方法,这时我们获取其真实的容量大小就得通过反射来进行,具体操作如下
为了达到开闭原则,提升系统的延展性,我把类型和收费标准抽象出来单独成类,未来要是要修改类型和收费标准,可以直接替换这两个类,当然更好的操作是再设计接口,未来如果要改,直接实现该接口就行,但是为了方便起见,我这里没有设计相应接口(主要是觉得太麻烦了)。 具体操作如下:
为了更好模拟停车场实际情况,特意设计类一个随机类,用于返回随机车牌号等。
为了使测试更清楚,这里把一秒当做一小时来计算
package com.dreamchaser.park;
public class Automobile {
/**
* 驾驶员
*/
private People people;
/**
* 车牌号
*/
private String number;
/**
* 车辆已使用年年数
*/
private Integer year;
/**
* 车辆类别
*/
private Type type;
public People getPeople() {
return people;
}
public void setPeople(People people) {
this.people = people;
}
public Integer getYear() {
return year;
}
public void setYear(Integer year) {
this.year = year;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
public Automobile(People people, String number, Integer year) {
this.people = people;
this.number = number;
this.year = year;
}
public String getMobileMessage(){
return "驾驶员:"+people+" ;车牌号:"+number+" ;车辆类别:"+type;
}
public void parking(int i){
System.out.println(people+"把车开到"+i+"号车位泊车!");
}
public void start(){
System.out.println("车已启动!");
}
public void pause(String s){
System.out.println(people+"把车暂时停在了"+s);
}
}
package com.dreamchaser.park;
public class Car extends Automobile{
/**
* 排气量
*/
private float displacement;
public Car(People people, String number, Integer year, float displacement) {
super(people, number, year);
this.displacement = displacement;
this.setType(Type.CAR);
}
@Override
public String getMobileMessage() {
return super.getMobileMessage()+" ;排气量:"+displacement+"L";
}
}
package com.dreamchaser.park;
public class Carriage extends Automobile{
private Integer peopleNumber;
public Carriage(People people, String number, Integer year, Integer peopleNumber) {
super(people, number, year);
this.peopleNumber = peopleNumber;
this.setType(Type.CARRIAGE);
}
@Override
public String getMobileMessage() {
return super.getMobileMessage()+" ;乘坐人数:"+peopleNumber+"人";
}
}
package com.dreamchaser.park;
public class Truck extends Automobile{
private float capacity;
public Truck(People people, String number, Integer year, float capacity) {
super(people, number, year);
this.capacity = capacity;
this.setType(Type.TRUCK);
}
@Override
public String getMobileMessage() {
return super.getMobileMessage()+" ;载重量:"+capacity+"吨";
}
}
package com.dreamchaser.park;
public class People {
/**
* 驾驶员名字
*/
private String name;
public People(String name) {
this.name = name;
}
/**
* 在出口前停车
*/
public void stop(Automobile automobile){
automobile.pause("出口");
}
/**
* 付费
* @param d
*/
public void pay(double d){
System.out.println("付费"+d+"元!");
}
/**
* 开车
*/
public void drive(Automobile automobile){
automobile.start();
}
/**
* 泊车
* @param i
*/
public void park(Automobile automobile,int i){
automobile.parking(i);
}
@Override
public String toString() {
return name;
}
public void into(Automobile automobile,Park park){
stop(automobile);
System.out.println("车辆信息:"+automobile.getMobileMessage());
drive(automobile);
park(automobile,park.park(automobile));
System.out.println("---------------------------------------");
}
public void out(Automobile automobile,Park park){
drive(automobile);
stop(automobile);
System.out.println("车辆信息:"+automobile.getMobileMessage());
pay(park.out(automobile));
drive(automobile);
System.out.println("---------------------------------------");
}
}
package com.dreamchaser.park;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class Park {
/**
*初始停车场车位为10
*/
private List<Automobile> automobiles=new ArrayList<>(10);
/**
* 存储时间
*/
private List<Long> times=new ArrayList<>();
int capacity=getArrayListCapacity((ArrayList<?>) automobiles);
public int park(Automobile automobile){
Date date=new Date();
int i=0;
for (;i<automobiles.size();i++){
Automobile a=automobiles.get(i);
if (a==null){
automobiles.set(i,automobile);
times.set(i,date.getTime());
return i;
}
}
//车位不够则扩容
automobiles.add(automobile);
times.add(date.getTime());
//比较容量,如果size大于容量,说明容量已被扩充,需更新并通知
if (automobiles.size()>capacity){
System.out.println("---------------------------");
capacity=getArrayListCapacity((ArrayList<?>) automobiles);
System.out.println("车位扩容!当前停车场车位总数为"+capacity);
System.out.println("---------------------------");
}
return i;
}
public double out(Automobile automobile){
Date date=new Date();
long t=0;
for (int i=0;i<automobiles.size();i++){
if (automobiles.get(i)==automobile){
automobiles.set(i,null);
t=date.getTime()-times.get(i);
times.set(i,null);
System.out.println(i+"号车位的车已驶离!");
break;
}
}
//这里为了演示清楚,一秒当一小时
return t/1000*Charging.getCharging(automobile.getType());
}
/**
* 通过反射获取list中的数组,然后通过数组返回其容量大小
* @param arrayList
* @return
*/
public static int getArrayListCapacity(ArrayList<?> arrayList) {
Class<ArrayList> arrayListClass = ArrayList.class;
try {
//获取 elementData 字段
Field field = arrayListClass.getDeclaredField("elementData");
//开始访问权限
field.setAccessible(true);
//把示例传入get,获取实例字段elementData的值
Object[] objects = (Object[])field.get(arrayList);
//返回当前ArrayList实例的容量值
return objects.length;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
public void display(){
System.out.println("当前停车场情况:");
System.out.println("\t\t\t\t金昊霖的停车场\t\t\t\t");
System.out.println("------------------------------------------------------");
//外置变量记录循环的次数
int a=0;
for (Automobile automobile:automobiles){
if (a%5==0){
System.out.println();
System.out.print("|\t");
}
if (automobile==null){
System.out.print("空\t|\t");
}else{
System.out.print(a+"\t|\t");
}
a++;
}
System.out.println();
System.out.println("------------------------------------------------------");
}
}
package com.dreamchaser.park;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Main {
public static void main(String[] args) {
Park park=new Park();
List<People> peoples=new ArrayList<>(20);
for (int i=0;i<20;i++){
peoples.add(new People("第"+i+"个志愿者"));
}
List<Automobile> automobiles=new ArrayList<>(20);
for (int i=0;i<20;i++){
Type type=MyRandom.getType();
if (type==Type.CAR){
automobiles.add(new Car(peoples.get(i), MyRandom.getLicense(),MyRandom.getInteger(),MyRandom.getInteger()));
}else if (type==Type.CARRIAGE){
automobiles.add(new Carriage(peoples.get(i), MyRandom.getLicense(),MyRandom.getInteger(),MyRandom.getInteger()));
}else if (type==Type.TRUCK){
automobiles.add(new Truck(peoples.get(i), MyRandom.getLicense(),MyRandom.getInteger(),MyRandom.getFloat()));
}
}
try {
//前十辆驶入停车场
for (int i=0;i<10;i++){
peoples.get(i).into(automobiles.get(i),park);
}
//显示停车场当前情况
park.display();
//1个小时后
Thread.sleep(1000);
//前五辆驶出停车场
for (int i=0;i<5;i++){
peoples.get(i).out(automobiles.get(i),park);
}
//显示停车场当前情况
park.display();
//后十辆驶入停车场
for (int i=10;i<20;i++){
peoples.get(i).into(automobiles.get(i),park);
}
//显示停车场当前情况
park.display();
//2个小时后
Thread.sleep(2000);
//后十辆驶出停车场
for (int i=10;i<20;i++){
peoples.get(i).out(automobiles.get(i),park);
}
//显示停车场当前情况
park.display();
//1个小时后
Thread.sleep(1000);
//剩下五辆驶出停车场
for (int i=5;i<10;i++){
peoples.get(i).out(automobiles.get(i),park);
}
//显示停车场当前情况
park.display();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MyRandom{
static Random random=new Random();
public static String getLicense(){
return "浙"+(char) (Math.random ()*26+'A')+(int)(Math.random ()*10)+(int)(Math.random ()*10)+(int)(Math.random ()*10)+(int)(Math.random ()*10);
}
public static Type getType(){
int i= (int)(Math.random()* Type.values().length);
return Type.values()[i];
}
public static Integer getInteger(){
return random.nextInt(100);
}
public static float getFloat(){
return random.nextFloat();
}
}
package com.dreamchaser.park;
public class Charging {
public static double getCharging(Type type){
if (type==Type.CAR){
return 1;
}else if (type==Type.CARRIAGE){
return 1.5;
}else{
return 2;
}
}
}
package com.dreamchaser.park;
public enum Type {
TRUCK,CAR,CARRIAGE
}
注:此处为了更好的模拟效果,程序将一秒当做一小时来计算
此作业涉及继承、覆写、反射、线程、设计模式等Java基础知识点,适合当做初学Java的新手练习。
评论