记一次Java综合小练习
最近开学入门学习Java,在今天上午之前,这个综合练习对我来说都是有难度的,哈哈.感觉主要是没有思路吧,没套路的纯情学生一枚
0.问题描述
这是一道慕课网上的综合小练习.针对的是Java入门.我天,有和我同样水平的小伙伴,这道练习很适合你哦
好了,废话不多说,上题目描述:
根据所学知识,编写一个控制台版的"答答租车系统".
功能:
1. 展示所有可租车辆
2. 选择车型,租车量
3. 展示祖车清单,包含: 总金额, 总载货量及其车型,总载人量及其车型
1.项目Analysis
看到它的第一眼,完全 懵 了,有木有…
如果叫我不看视频的分析,我想这个思路我是铁打的想不出来了…
分析分为3部分: 数据模型分析, 业务模型分析, 还有就是显示和流程分析
模型简化: 车可以分为载货车和载客车两类.其中载货车又有轻型和重型之分. 载客车又分为小客车和大客车.(注意这里只是通过项目来学习面向对象思想,因此用的是及其简单的模型).这里面有一类车比较特殊,它既能载客又能载货,比如说皮卡车.
业务分析: 这里只考虑消费者需求.有简单的选车,租车天数,统计金额,统计载客和货量.
显示与流程分析: 控制台用户界面,以及可能的界面跳转等等.噢,感觉心被掏空.
2.部分代码Show
面向对象有三个特点: 封装,继承以及多态
那代码里是怎样体现这些特性的呢?
比如,继承特性,通过写Car抽象类, 然后在具体向下编写其它子类
public abstract class Car {
public abstract String getVehicleName();
public abstract double getCapacity();
public abstract double getRentPrice();
public abstract int getRemainAmount();
}
然后呢,子类可以进一步根据父类调整自己需要.听慕课课堂老师小慕说,抽象类是对子类的约束,这一点还不是很理解,hah
另外两个类载客车类和载货车类,继承父类Car. 稀里糊涂就上来了. Car类中其他三个方法都一样,然而getCapacity()方法我去使用两个其他的来代替
public abstract class CarryVehicle extends Car {
...
public abstract double getMaxCarryWeight();
}
public abstract class PassengerVehicle extends Car {
...
public abstract int getMaxCapacity();
}
在再下一级的类的实现部分,就是依着具体的类来实现,这里就只举例一个类.
比如,一个AudiA4类
public class AudiA4 extends PassengerVehicle {
private String carName = "AudiA4";
private int maxCapacity = 4;
private double rentPrice = 500;
private int remainAmount = 20;
@Override
public String getVehicleName() {
return this.carName;
}
@Override
public int getMaxCapacity() {
return this.maxCapacity;
}
@Override
public double getRentPrice() {
return this.rentPrice;
}
@Override
public int getRemainAmount() {
return this.remainAmount;
}
@Override
public double getCapacity() {
return this.getMaxCapacity();
}
}
如果世界一直如我想象的那般单纯,程序员(当然不止这一职业啦)的生活会系多么滴美好~
可恶的皮卡类,为什么你既能载客又能载人??好吧,为了你,我不得不另外写代码-_-
上吧,我的皮卡丘!哦,不对我的Pickup类
public class PickupCar extends CarryVehicle {
private String carName = "Picca6";
private double maxCarryWeight = 20;
private double rentPrice = 998;
private int remainAmount = 12;
@Override
public String getVehicleName() {
return this.carName;
}
@Override
public double getCapacity() {
return this.getMaxCarryWeight();
}
@Override
public double getMaxCarryWeight() {
return this.maxCarryWeight;
}
@Override
public double getRentPrice() {
return this.rentPrice;
}
@Override
public int getRemainAmount() {
return this.remainAmount;
}
public int getMaxCapacity() {
return (new PickupPassenger()).getMaxCapacity();
}
class PickupPassenger extends PassengerVehicle {
private int maxCapacity = 5;
@Override
public double getCapacity() {
return this.getMaxCapacity();
}
@Override
public int getMaxCapacity() {
return this.maxCapacity;
}
@Override
public String getVehicleName() {
return PickupCar.this.carName;
}
@Override
public double getRentPrice() {
return PickupCar.this.rentPrice;
}
@Override
public int getRemainAmount() {
return PickupCar.this.remainAmount;
}
}
}
封装特性当然就是 我不知道啦
多态特性呢,在代码里有这样的体现.
Car c1 = new AudiA4();
Car c2 = new Mazda();
Car c3 = new SonghuaRiver();
Car c4 = new Iveco();
Car c5 = new PickupCar();
ArrayList<Car> carCollection = new ArrayList<Car>();
carCollection.add(c1);
carCollection.add(c2);
carCollection.add(c3);
carCollection.add(c4);
carCollection.add(c5);
嗯,可以根据情况来确定使用什么类,比如说:
if (carCollection.get(i) instanceof PickupCar ) {
System.out.print((int)carCollection.get(i).getCapacity() + "人"
+ "," + ((PickupCar)(carCollection.get(i))).getMaxCapacity() + "辆" );
} else if (carCollection.get(i) instanceof PassengerVehicle) {
System.out.print((int)carCollection.get(i).getCapacity() + "人");
} else if (carCollection.get(i) instanceof CarryVehicle) {
System.out.print((int)carCollection.get(i).getCapacity() + "吨");
}
上面我就是我理解的多态的一个例子,也不知道对不对,嘻嘻
3.学到的其他Stuff
比如说,对于 Map类的遍历问题:
for (Map.Entry<Integer, Integer> carItem : carList.entrySet()) {
int carIndex = carItem.getKey().intValue() - 1;
if ( carCollection.get(carIndex) instanceof CarryVehicle ||
carCollection.get(carIndex) instanceof PickupCar ) {
System.out.print(carCollection.get(carIndex).getVehicleName() + " ");
}
}
系上面介样滴
再比如说,从命令行读取输入时,使用Scanner读取一个行输入之后,就会这样…
public class Initial {
...
private String readLine() {
Scanner scanner = new Scanner(System.in);
String nextLine = scanner.nextLine();
scanner.close();
return nextLine;
}
}
...
// main
Initial init = new Initial();
...
System.out.println("请输入你要租车的数量:");
int carTotal = Integer.parseInt(init.readLine());
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Unknown Source)
at Initial.readLine(Initial.java:17)
at Initial.main(Initial.java:128)
但是原因我目前还是不知道的,hah
不过呢,换成这样子就ok啦
public class Initial {
...
private String readLine() throws IOException {
InputStreamReader isr = new InputStreamReader(System.in);
return new BufferedReader(isr).readLine();
}
}
还有一点,以前不会有制表符,用了之后居然系这样滴,鸡冻
序号 汽车名称 租金 容量 剩余数量
1. AudiA4 500.0元/天 4人 20辆
2. Mazda 150.0元/天 5人 34辆
3. Songhu 400.0元/天 4吨 3辆
4. IVECO 1000.0元/天 20吨 1辆
5. Picca6 998.0元/天 20人,5辆 12辆
什么,控制台里好好滴,复制到这里来这个卵样??不多解释了,大家认为它默认对齐就好
还有一个特别重要的一点:
在Map类遍历的例子里(段落3.0开头),使用了 instanceof PickupCar这个东东,实在是没有想到更好的办法呢.主要来源于自己写的那种 伪继承方法吧,这个词语也是解决不了Pickup问题google时查到滴!看起来好高端的样子,抽时间学习一下!
慕课上一个呢称叫睿智狂人的小伙伴就很牛,写出了下面的思路:
1、创建两个接口(载客接口A-载客量)、(载货接口B-载货量),载客和货接口C extend 载客接口A,载货接口B(载客量、载货量),
一个抽象父类Car(车型、单价-->元/天);
2、实现-卡车类 extend 父类Car implement 载货接口B;
实现-客车类 extend 父类Car implement 载客接口A;
实现-皮卡类 extend 父类Car implement 载客和货接口C;
3、租车系统类:一维数组 实例化 卡车对象、客车对象 和 皮卡对象;
4、客户选车、分类汇总车辆后,输出租车明细与总价。
仔细想了想,这种思路确实比我那好很多,hah
4.小Conclusion
虽然看上去挺简单,但是实践出真知,越发自己动手能力不咋地啊
咻咻,
和我一样想入门学Java却踌躇的小伙伴,这个小综合练习是个不错的推荐哦~