OOP4-6次作业总结BLOG

OOP4-6次作业总结BLOG

22201303-范宇

前言

三次题目集中,对我个人而言,第5次较为简单,第四次和第六次有两道题比较困难,三次题目集总的来说具备一定的挑战性,挺适合我。

第四次和第五次题目集均给了提示,类的结构基本都设计好了,我们要做的只是填空;而第六次题目集的后两道题没有提示,需要自己设计类。

设计与分析

题目集四

7-1 菜单计价程序-3

作者 蔡轲
单位 南昌航空大学

设计点菜计价程序,根据输入的信息,计算并输出总价格。

输入内容按先后顺序包括两部分:菜单、订单,最后以"end"结束。

菜单由一条或多条菜品记录组成,每条记录一行

每条菜品记录包含:菜名、基础价格 两个信息。

订单分:桌号标识、点菜记录和删除信息、代点菜信息。每一类信息都可包含一条或多条记录,每条记录一行或多行。

桌号标识独占一行,包含两个信息:桌号、时间。

桌号以下的所有记录都是本桌的记录,直至下一个桌号标识。

点菜记录包含:序号、菜名、份额、份数。份额可选项包括:1、2、3,分别代表小、中、大份。

不同份额菜价的计算方法:小份菜的价格=菜品的基础价格。中份菜的价格=菜品的基础价格1.5。小份菜的价格=菜品的基础价格2。如果计算出现小数,按四舍五入的规则进行处理。

删除记录格式:序号 delete

标识删除对应序号的那条点菜记录。

如果序号不对,输出"delete error"

代点菜信息包含:桌号 序号 菜品名称 份额 分数

代点菜是当前桌为另外一桌点菜,信息中的桌号是另一桌的桌号,带点菜的价格计算在当前这一桌。

程序最后按输入的先后顺序依次输出每一桌的总价(注意:由于有代点菜的功能,总价不一定等于当前桌上的菜的价格之和)。

每桌的总价等于那一桌所有菜的价格之和乘以折扣。如存在小数,按四舍五入规则计算,保留整数。

折扣的计算方法(注:以下时间段均按闭区间计算):

周一至周五营业时间与折扣:晚上(17:00-20:30)8折,周一至周五中午(10:30--14:30)6折,其余时间不营业。

周末全价,营业时间:9:30-21:30

如果下单时间不在营业范围内,输出"table " + t.tableNum + " out of opening hours"

参考以下类的模板进行设计:菜品类:对应菜谱上一道菜的信息。

Dish {

String name;//菜品名称

int unit_price; //单价

int getPrice(int portion)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份) }

菜谱类:对应菜谱,包含饭店提供的所有菜的信息。

Menu {

Dish\[\] dishs ;//菜品数组,保存所有菜品信息

Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。

Dish addDish(String dishName,int unit_price)//添加一道菜品信息

}

点菜记录类:保存订单上的一道菜品记录

Record {

int orderNum;//序号\\

Dish d;//菜品\\

int portion;//份额(1/2/3代表小/中/大份)\\

int getPrice()//计价,计算本条记录的价格\\

}

订单类:保存用户点的所有菜的信息。

Order {

Record\[\] records;//保存订单上每一道的记录

int getTotalPrice()//计算订单的总价

Record addARecord(int orderNum,String dishName,int portion,int num)//添加一条菜品信息到订单中。

delARecordByOrderNum(int orderNum)//根据序号删除一条记录

findRecordByNum(int orderNum)//根据序号查找一条记录

}

### 输入格式:

桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)

菜品记录格式:

菜名+英文空格+基础价格

如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。

点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。

删除记录格式:序号 +英文空格+delete

代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数

最后一条记录以“end”结束。

### 输出格式:

按输入顺序输出每一桌的订单记录处理信息,包括:

1、桌号,格式:table+英文空格+桌号+”:”

2、按顺序输出当前这一桌每条订单记录的处理信息,

每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品\*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“\*\* does not exist”,\*\*是不能识别的菜名

如果删除记录的序号不存在,则输出“delete error”

最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的总价

本次题目不考虑其他错误情况,如:桌号、菜单订单顺序颠倒、不符合格式的输入、序号重复等,在本系列的后续作业中会做要求。

输入格式:

桌号标识格式:table + 序号 +英文空格+ 日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)

菜品记录格式:

菜名+英文空格+基础价格

如果有多条相同的菜名的记录,菜品的基础价格以最后一条记录为准。

点菜记录格式:序号+英文空格+菜名+英文空格+份额+英文空格+份数注:份额可输入(1/2/3), 1代表小份,2代表中份,3代表大份。

删除记录格式:序号 +英文空格+delete

代点菜信息包含:桌号+英文空格+序号+英文空格+菜品名称+英文空格+份额+英文空格+分数

最后一条记录以“end”结束。

输出格式:

按输入顺序输出每一桌的订单记录处理信息,包括:

1、桌号,格式:table+英文空格+桌号+“:”

2、按顺序输出当前这一桌每条订单记录的处理信息,

每条点菜记录输出:序号+英文空格+菜名+英文空格+价格。其中的价格等于对应记录的菜品\*份数,序号是之前输入的订单记录的序号。如果订单中包含不能识别的菜名,则输出“\*\* does not exist”,\*\*是不能识别的菜名

如果删除记录的序号不存在,则输出“delete error”

最后按输入顺序一次输出每一桌所有菜品的总价(整数数值)格式:table+英文空格+桌号+“:”+英文空格+当前桌的总价

本次题目不考虑其他错误情况,如:桌号、菜单订单顺序颠倒、不符合格式的输入、序号重复等,在本系列的后续作业中会做要求。

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.*;
import java.lang.*;
public class Main{
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String dish = input.nextLine();
String[] name = dish.split(" ");
ArrayList<Dish> ds = new ArrayList<>();
while (name[0].compareTo("table") != 0) {
int unit_price = Integer.parseInt(name[1]);
Dish dish1 = new Dish(name[0], unit_price);
int i;
for(i=0;i<ds.size();i++){
if(ds.get(i).getName().compareTo(name[0])==0){
break;
}
}
if(i==ds.size()) ds.add(dish1);
else {
//ds.remove(i);
ds.set(i,dish1);
}
//menu.addDish(name[0],unit_price);
dish = input.nextLine();
name = dish.split(" ");
if(name[0].equals("end"))
break;
}
Menu menu = new Menu(ds);
if(name[0].equals("end"))
return;
//String table01 = input.nextLine();
// String[] table1 = name.split(" ");
String[] time1 = name[2].split("/");
int y = Integer.parseInt(time1[0]);
int m = Integer.parseInt((time1[1]));
int d = Integer.parseInt(time1[2]);
LocalDate date1 = LocalDate.of(y, m, d);
DayOfWeek week1 = date1.getDayOfWeek();
int week=week1.getValue();
//String date01 = date1.format(fmt);
//String week1 = getWeek(date01);
//int week = Integer.parseInt(week1);
String[] time2 = name[3].split("/");
int h = Integer.parseInt(time2[0]);
int minute = Integer.parseInt(time2[1]);
int s = Integer.parseInt(time2[2]);
double discount;
String r1 = input.nextLine();
String[] r01 = r1.split(" ");
ArrayList<Record> records = new ArrayList<>();
Order order1 = new Order(records);
int i=1;
int countDelete=0;
while(r01[0].compareTo("end")!=0){
int orderNum = Integer.parseInt(r01[0]);
if(r01[1].equals("delete")){
double price1 = 0.5+order1.findRecordByNum(orderNum).getPrice();
if(price1==0)
countDelete++;
Dish d2=new Dish("delete",-price1);
Record record2=new Record(orderNum,d2,1,1);
records.add(record2);
break;
}
Dish d1 = menu.searchDish(r01[1]);
int portion = Integer.parseInt(r01[2]);
int num = Integer.parseInt(r01[3]);
i++;
//order1.addARecord(orderNum,d1.getName(),portion,num);
Record record1=new Record(orderNum,d1,portion,num);
records.add(record1);
r1= input.nextLine();
r01 = r1.split(" ");
}
while(r01[0].compareTo("end")!=0){
r1= input.nextLine();
r01 = r1.split(" ");
if(r01[0].equals("end"))
break;
int orderNum = Integer.parseInt(r01[0]);
double price1 = order1.findRecordByNum(orderNum).getPrice();
if(price1==0)
countDelete++;
Dish d2=new Dish("delete",-price1);
Record record2=new Record(orderNum,d2,1,1);
records.add(record2);
}
Order order = new Order(records);
if (week==6||week==7){
if(h>9&&h<21||h==9&&minute>=30||h==21&&minute<30||h==21&&minute==30&&s==0)
discount=1;
else{
System.out.println(name[0]+" "+name[1]+": ");
for(int j=0;j<i-1;j++){
if(order.findRecordByNum(j+1).getPrice()!=0)
System.out.println(j+1+" "+order.findRecordByNum(j+1).getD().getName()+" "+(int)(0.5+order.findRecordByNum(j+1).getPrice()));
else
System.out.println(order.findRecordByNum(j+1).getD().getName()+" does not exist");
}
for(int j=0;j<countDelete;j++){
System.out.println("delete error;");
}
System.out.println("table " + name[1] + " out of opening hours");
return;
}
}
else{
if(h>=17&&h<20||h==20&&minute<30||h==20&&minute==30&&s==0){
discount=0.8;
}
else if(h>10&&h<14||h==10&&minute>=30||h==14&&minute<30||h==14&&minute==30&&s==0){
discount=0.6;
}
else{
System.out.println(name[0]+" "+name[1]+": ");
for(int j=0;j<i-1;j++){
if(order.findRecordByNum(j+1).getPrice()!=0)
System.out.println(j+1+" "+order.findRecordByNum(j+1).getD().getName()+" "+(int)(0.5+order.findRecordByNum(j+1).getPrice()));
else
System.out.println(order.findRecordByNum(j+1).getD().getName()+" does not exist");
}
for(int j=0;j<countDelete;j++){
System.out.println("delete error;");
}
System.out.println("table " + name[1] + " out of opening hours");
return;
}
}
System.out.println(name[0]+" "+name[1]+": ");
for(int j=0;j<i-1;j++){
if(order.findRecordByNum(j+1).getPrice()!=0)
System.out.println(j+1+" "+order.findRecordByNum(j+1).getD().getName()+" "+(int)(0.5+order.findRecordByNum(j+1).getPrice()));
else
System.out.println(order.findRecordByNum(j+1).getD().getName()+" does not exist");
}
for(int j=0;j<countDelete;j++){
System.out.println("delete error;");
}
System.out.println(name[0]+" "+name[1]+":"+" "+(int)(order.getTotalPrice()*discount+0.5));
}
}
class Dish{
private String name;
private double unit_price;
Dish(){}
Dish(String name,double unit_price){
this.name=name;
this.unit_price=unit_price;
}
public double getPrice(int portion){
if(portion==2)
unit_price=unit_price*1.5;
if(portion==3)
unit_price = unit_price*2;
return unit_price;
//return (int)(unit_price*(1+(0.5*(portion-1))));
}
public String getName(){
return name;
}
}
class Menu{
private static ArrayList<Dish> dishs;
Menu(){}
public Menu(ArrayList<Dish> dishs){
this.dishs = dishs;
}
public static Dish searchDish(String dishName){
int i;
for(i=0;i<dishs.size();i++){
if(dishs.get(i).getName().compareTo(dishName)==0){
break;
}
}
if(i== dishs.size()){
return new Dish(dishName,0);
}
return dishs.get(i);
}
public Dish addDish(String dishName,double unit_price){
this.dishs.add(new Dish(dishName,unit_price));
return new Dish(dishName,unit_price);
}
}
class Record{
private int orderNum;
private Dish d;
private int portion;
private int num;
Record(int orderNum,Dish d,int portion,int num){
this.orderNum=orderNum;
this.d=d;
this.portion=portion;
this.num=num;
}
public int getNum(){
return num;
}
public Dish getD(){
return d;
}
public int getPortion(){
return portion;
}
public int getOrderNum(){
return orderNum;
}
public double getPrice(){
return d.getPrice(portion)*num;
}
}
class Order {
private ArrayList<Record> records;
public Order(ArrayList<Record> records) {
this.records = records;
}
public double getTotalPrice() {
double sum = 0;
for (Record r : records) {
sum += (int)(0.5+r.getPrice());
}
return sum;
}
public Record addARecord(int orderNum, String dishName, int portion, int num) {
Dish d = Menu.searchDish(dishName);
this.records.add(new Record(orderNum, d, portion,num));
return new Record(orderNum, d, portion,num);
}
public void delARecordByOrderNum(int orderNum) {
records.remove(orderNum - 1);
}
public Record findRecordByNum(int orderNum) {
int ordernum=0,portion=0,num=0;
double price=0;
String name="";
for (Record r : this.records) {
if (r.getOrderNum() == orderNum) {
ordernum=r.getOrderNum();
name=r.getD().getName();
portion=r.getPortion();
price=r.getD().getPrice(1);
num=r.getNum();
break;
}
}
Dish d=new Dish(name,price);
return new Record(ordernum,d,portion,num);
}
}

首先要对这道题的时间进行判断,通过LocalDate对日期信息进行处理,再通过DayOfWeek求出该日期为星期几,代码如下:

String[] time1 = name[2].split("/");
int y = Integer.parseInt(time1[0]);
int m = Integer.parseInt((time1[1]));
int d = Integer.parseInt(time1[2]);
LocalDate date1 = LocalDate.of(y, m, d);
DayOfWeek week1 = date1.getDayOfWeek();

然后根据周几和时间计算出折扣,并对点菜信息进行处理:首先判断菜品信息正误,然后有删除和增加订单信息,最后计算总价格。在计算总价格的过程中,我的思路是最后一次性算出所有价格再求和,而订单信息全都储存在Record类里,而Order中的Record属性是以动态数组的形式存在,所以要逐一遍历计算价格求和,代码如下:

public Record findRecordByNum(int orderNum) {
int ordernum=0,portion=0,num=0;
double price=0;
String name="";
for (Record r : this.records) {
if (r.getOrderNum() == orderNum) {
ordernum=r.getOrderNum();
name=r.getD().getName();
portion=r.getPortion();
price=r.getD().getPrice(1);
num=r.getNum();
break;
}
}
Dish d=new Dish(name,price);
return new Record(ordernum,d,portion,num);
}
public double getTotalPrice() {
double sum = 0;
for (Record r : records) {
sum += (int)(0.5+r.getPrice());
}
return sum;
}

这道题只拿了一半的分,只完成了单桌基本要求,多桌还未实现。

题目集五

7-5 日期问题面向对象设计(聚合一)

作者 段喜龙
单位 南昌航空大学

参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

类图.jpg

应用程序共测试三个功能:

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数

注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)

输入格式:

有三种输入方式(以输入的第一个数字划分[1,3]):

  • 1 year month day n //测试输入日期的下n天
  • 2 year month day n //测试输入日期的前n天
  • 3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数

输出格式:

  • 当输入有误时,输出格式如下:
    Wrong Format
  • 当第一个数字为1且输入均有效,输出格式如下:
    year-month-day
     
  • 当第一个数字为2且输入均有效,输出格式如下:
    year-month-day
     
  • 当第一个数字为3且输入均有效,输出格式如下:
    天数值
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int a = input.nextInt();
if(a==1){
int y=input.nextInt();
int m=input.nextInt();
int d=input.nextInt();
Day day = new Day(y,m,d);
DateUtil date = new DateUtil(d,m,y);
if(day.validate()){
int n=input.nextInt();
date.getNextNDays(n);
System.out.println(date.showDate());
}
else
System.out.println("Wrong Format");
}
else if(a==2){
int y=input.nextInt();
int m=input.nextInt();
int d=input.nextInt();
Day day = new Day(y,m,d);
DateUtil date = new DateUtil(d,m,y);
if(day.validate()){
int n=input.nextInt();
date.getPreviousNDays(n);
System.out.println(date.showDate());
}
else
System.out.println("Wrong Format");
}
else if(a==3){
int y=input.nextInt();
int m=input.nextInt();
int d=input.nextInt();
int y1=input.nextInt();
int m1=input.nextInt();
int d1=input.nextInt();
DateUtil date = new DateUtil(d,m,y);
DateUtil date1 = new DateUtil(d1,m1,y1);
if(date.getDay().validate()&&date1.getDay().validate()){
int n = date.getDaysofDates(date1);
System.out.println(n);
}
else
System.out.println("Wrong Format");
}
else
System.out.println("Wrong Format");
}
}
class Year{
private int value;
Year(){}
Year(int value){
this.value=value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public boolean isLeapYear(){ //判断是否为闰年
if(value%4==0&&value%100!=0||value%400==0){
return true;
}
else
return false;
}
public boolean validate(){ //校验数据合法性
if(value>=1900&&value<=2050)
return true;
else
return false;
}
public void yearIncrement(){ //年份增1
this.value++;
}
public void yearReduction(){ //年份减1
this.value--;
}
}
class Month{
private int value;
private Year year;
Month(){}
Month(int yearValue,int monthValue){
year = new Year(yearValue);
this.value=monthValue;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Year getYear(){
return year;
}
public void setYear(Year year) {
this.year = year;
}
public void resetMin(){ //月份复位(1)
value=1;
}
public void resetMax(){ //月份复位(12)
value=12;
}
public boolean validate(){ //判断月份是否合法
if(value>=1&&value<=12&& year.validate())
return true;
else
return false;
}
public void monthIncrement(){ //月份增1
this.value++;
if(value>12){
resetMin();
year.yearIncrement();
}
}
public void monthReduction(){ //月份减1
this.value--;
if(value==0){
resetMax();
year.yearReduction();
}
}
}
class Day{
private int value;
private Month month;
private int[] mon_maxnum={31,28,31,30,31,30,31,31,30,31,30,31};
Day(){}
Day(int yearValue,int monthValue,int dayValue){
this.value=dayValue;
month = new Month(yearValue,monthValue);
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Month getMonth() {
return month;
}
public void setMonth(Month value) {
this.month = value;
}
public void resetMin(){//日期复位(1)
value=1;
}
public void resetMax(){// 日期改为当月最大值
value=mon_maxnum[month.getValue()-1];
}
public boolean validate(){//校验数据合法性
if(month.validate()) {
if (month.getYear().isLeapYear())
mon_maxnum[1] = 29;
else
mon_maxnum[1] = 28;
if (value >= 1 && value <= mon_maxnum[month.getValue() - 1] && month.validate())
return true;
else
return false;
}
else
return false;
}
public void dayIncrement(){//日期增1
value++;
if(month.getYear().isLeapYear())
mon_maxnum[1]=29;
else
mon_maxnum[1]=28;
if(value>mon_maxnum[month.getValue()-1]){
resetMin();
month.monthIncrement();
}
}
public void dayReduction(){//日期减1
value--;
if(value==0){
month.monthReduction();
if(month.getYear().isLeapYear())
mon_maxnum[1]=29;
else
mon_maxnum[1]=28;
resetMax();
}
}
}
class DateUtil{
private Day day;
DateUtil(){}
DateUtil(int d,int m,int y){
day = new Day(y,m,d);
}
public Day getDay() {
return day;
}
public void setDay(Day day) {
this.day = day;
}
public boolean checkInputValidity(){//校验数据合法性
if(day.validate())
return true;
else
return false;
}
public boolean compareDates(DateUtil date){//比较两个日期的大小
if(day.getMonth().getYear().getValue()>date.getDay().getMonth().getYear().getValue()){
return true;
}
else if(day.getMonth().getYear().getValue()==date.getDay().getMonth().getYear().getValue()&&day.getMonth().getValue()>date.getDay().getMonth().getValue()){
return true;
}
else if(day.getMonth().getValue()==date.getDay().getMonth().getValue()&&day.getValue()>date.getDay().getValue()){
return true;
}
else
return false;
}
public boolean equalTwoDates(DateUtil date){
if(day.getValue()==date.getDay().getValue()&&day.getMonth().getValue()==date.getDay().getMonth().getValue()&&day.getMonth().getYear().getValue()==date.getDay().getMonth().getYear().getValue())
return true;
else
return false;
}
public String showDate(){
return day.getMonth().getYear().getValue()+"-"+day.getMonth().getValue()+"-"+day.getValue();
}
public DateUtil getNextNDays(int n){
for(int i=0;i<n;i++){
day.dayIncrement();
}
return new DateUtil(day.getValue(),day.getMonth().getValue(),day.getMonth().getYear().getValue());
}
public DateUtil getPreviousNDays(int n){
for(int i=0;i<n;i++){
day.dayReduction();
}
return new DateUtil(day.getValue(),day.getMonth().getValue(),day.getMonth().getYear().getValue());
}
public int getDaysofDates(DateUtil date){
int n=0;
DateUtil date1 = new DateUtil(day.getValue(),day.getMonth().getValue(),day.getMonth().getYear().getValue());
while(date1.compareDates(date)){
date.getDay().dayIncrement();
n++;
}
while(date.compareDates(date1)){
date1.getDay().dayIncrement();
n++;
}
return n;
}
}

这道题已经设计好了类图,重点就在于理解类之间的关系,以及如何实现类之间的关系。

这道题给的类图耦合性还是比较强的,上一个类作为下一个类的属性,一个类套另一个类,整体上来看并不符合单一职责原则。

我个人认为这道题难度较小,毕竟类图给了,这道题相当于是填空,主要问题就是日期增加的时候没有考虑到日期,月份越界的情况。

7-6 日期问题面向对象设计(聚合二)

作者 段喜龙
单位 南昌航空大学

参考题目7-3的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

类图.jpg

应用程序共测试三个功能:

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数

注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)

输入格式:

有三种输入方式(以输入的第一个数字划分[1,3]):

  • 1 year month day n //测试输入日期的下n天
  • 2 year month day n //测试输入日期的前n天
  • 3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数

输出格式:

  • 当输入有误时,输出格式如下:
    Wrong Format
  • 当第一个数字为1且输入均有效,输出格式如下:
    year1-month1-day1 next n days is:year2-month2-day2
     
  • 当第一个数字为2且输入均有效,输出格式如下:
    year1-month1-day1 previous n days is:year2-month2-day2
     
  • 当第一个数字为3且输入均有效,输出格式如下:
    The days between year1-month1-day1 and year2-month2-day2 are:值
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int a = input.nextInt();
if(a==1){
int y=input.nextInt();
int m=input.nextInt();
int d=input.nextInt();
DateUtil date = new DateUtil(y,m,d);
if(date.checkInputValidity()){
int n=input.nextInt();
date.getNextNDays(n);
System.out.println(y+"-"+m+"-"+d+" next "+n+" days is:"+date.showDate());
}
else
System.out.println("Wrong Format");
}
else if(a==2){
int y=input.nextInt();
int m=input.nextInt();
int d=input.nextInt();
DateUtil date = new DateUtil(y,m,d);
if(date.checkInputValidity()){
int n=input.nextInt();
date.getPreviousNDays(n);
System.out.println(y+"-"+m+"-"+d+" previous "+n+" days is:"+date.showDate());
}
else
System.out.println("Wrong Format");
}
else if(a==3){
int y=input.nextInt();
int m=input.nextInt();
int d=input.nextInt();
int y1=input.nextInt();
int m1=input.nextInt();
int d1=input.nextInt();
DateUtil date = new DateUtil(y,m,d);
DateUtil date1 = new DateUtil(y1,m1,d1);
if(date.checkInputValidity()&&date1.checkInputValidity()){
int n = date.getDaysofDates(date1);
System.out.println("The days between "+y+"-"+m+"-"+d+" and "+y1+"-"+m1+"-"+d1+" are:"+n);
}
else
System.out.println("Wrong Format");
}
else
System.out.println("Wrong Format");
}
}
class Year{
private int value;
Year(){}
Year(int value){
this.value=value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public boolean isLeapYear(){
if(value%4==0&&value%100!=0||value%400==0){
return true;
}
else
return false;
}
public boolean validate(){
if(value>=1820&&value<=2020)
return true;
else
return false;
}
public void yearIncrement(){
this.value++;
}
public void yearReduction(){
this.value--;
}
}
class Month{
private int value;
Month(){}
Month(int Value){
this.value=Value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public void resetMin(){
this.value=1;
}
public void resetMax(){
this.value=12;
}
public boolean validate(){
if(value>=1&&value<=12)
return true;
else
return false;
}
public void monthIncrement(){
this.value++;
}
public void monthReduction(){
this.value--;
}
}
class Day{
private int value;
Day(){}
Day(int Value){
this.value=Value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public void dayIncrement(){
value++;
}
public void dayReduction(){
value--;
}
}
class DateUtil{
private Year year;
private Month month;
private Day day;
private int[] mon_maxnum={31,28,31,30,31,30,31,31,30,31,30,31};
DateUtil(){}
DateUtil(int y,int m,int d){
year = new Year(y);
month = new Month(m);
day = new Day(d);
}
public Year getYear() {
return year;
}
public void setYear(Year year) {
this.year = year;
}
public Month getMonth() {
return month;
}
public void setMonth(Month month) {
this.month = month;
}
public Day getDay() {
return day;
}
public void setDay(Day day) {
this.day = day;
}
public void setDayMin(){//设置日期最小值1
day.setValue(1);
}
public void setDayMax(){//设置日期为当月最大值
day.setValue(mon_maxnum[month.getValue()-1]);
}
public boolean checkInputValidity(){//校验输入数据合法性
if(year.validate()&&month.validate()&&day.getValue()>=1&&day.getValue()<=mon_maxnum[month.getValue()-1])
return true;
else
return false;
}
public boolean compareDates(DateUtil date){//判断两个日期的先后
if(year.getValue()>date.getYear().getValue()){
return true;
}
else if(year.getValue()==date.getYear().getValue()&&month.getValue()>date.getMonth().getValue()){
return true;
}
else if(month.getValue()==date.getMonth().getValue()&&day.getValue()>date.getDay().getValue()){
return true;
}
else
return false;
}
public boolean equalTwoDates(DateUtil date){//判断两个日期是否相等
if(day.getValue()==date.getDay().getValue()&&month.getValue()==date.getMonth().getValue()&&year.getValue()==date.getYear().getValue())
return true;
else
return false;
}
public String showDate(){//日期格式化
String date = year.getValue()+"-"+month.getValue()+"-"+day.getValue();
return date;
}
public DateUtil getNextNDays(int n){//求下N天
for(int i=0;i<n;i++){
day.dayIncrement();
if(year.isLeapYear()){
mon_maxnum[1]=29;
}
else
mon_maxnum[1]=28;
if(day.getValue()>mon_maxnum[month.getValue()-1]){
day.setValue(1);
month.monthIncrement();
if(month.getValue()>12){
month.setValue(1);
year.yearIncrement();
}
}
}
return new DateUtil(year.getValue(),month.getValue(),day.getValue());
}
public DateUtil getPreviousNDays(int n){//求前N天
for(int i=0;i<n;i++){
day.dayReduction();
if(day.getValue()==0){
month.monthReduction();
if(month.getValue()==0){
month.setValue(12);
year.yearReduction();
}if(year.isLeapYear()){
mon_maxnum[1]=29;
}
else
mon_maxnum[1]=28;
day.setValue(mon_maxnum[month.getValue()-1]);
}
}
return new DateUtil(year.getValue(),month.getValue(),day.getValue());
}
public int getDaysofDates(DateUtil date){//求两个日期的天数差
int n=0;
DateUtil date1 = new DateUtil(year.getValue(),month.getValue(),day.getValue());
while(date1.compareDates(date)){//每次加一天,直到两个日期相等
date.getNextNDays(1);
n++;
}
while(date.compareDates(date1)){
date1.getNextNDays(1);
n++;
}
return n;
}
}

这道题是上一题的进阶,与上一题相比,弥补了上一题类之间耦合性高的缺点,类Day,Month,Year三个类之间互不干扰,符合单一职责原则。数据的处理统一由DateUtil类处理。

在上一道题的错误经验上,这道题我是一遍过的,依旧是填空,把每个类的方法都填完,程序自然就完成了。

题目集六

7-4 ATM机类结构设计(一)

作者 段喜龙
单位 南昌航空大学

设计ATM仿真系统,具体要求参见作业说明。
OO作业8-1题目说明.pdf

输入格式:

每一行输入一次业务操作,可以输入多行,最终以字符#终止。具体每种业务操作输入格式如下:

  • 存款、取款功能输入数据格式:
    卡号 密码 ATM机编号 金额(由一个或多个空格分隔),
    其中,当金额大于0时,代表取款,否则代表存款。
  • 查询余额功能输入数据格式:
    卡号

输出格式:

①输入错误处理

  • 如果输入卡号不存在,则输出Sorry,this card does not exist.
  • 如果输入ATM机编号不存在,则输出Sorry,the ATM's id is wrong.
  • 如果输入银行卡密码错误,则输出Sorry,your password is wrong.
  • 如果输入取款金额大于账户余额,则输出Sorry,your account balance is insufficient.
  • 如果检测为跨行存取款,则输出Sorry,cross-bank withdrawal is not supported.

②取款业务输出

输出共两行,格式分别为:

[用户姓名]在[银行名称]的[ATM编号]上取款¥[金额]

当前余额为¥[金额]

其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。

③存款业务输出

输出共两行,格式分别为:

[用户姓名]在[银行名称]的[ATM编号]上存款¥[金额]

当前余额为¥[金额]

其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。

④查询余额业务输出

¥[金额]

金额保留两位小数。

import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String str = input.nextLine();
Data data = new Data();
while (str.compareTo("#")!=0){
DealData dealData = new DealData(str,data);
dealData.getDataResult();
str = input.nextLine();
}
}
}
class UnionPay{
private String name;
private Bank[] banks;
UnionPay(){}
UnionPay(String name,Bank[] banks){
this.name=name;
this.banks=banks;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Bank[] getBanks() {
return banks;
}
public void setBanks(Bank[] banks) {
this.banks = banks;
}
}
class Bank{
private String name;
private User[] users;
private Account[] accounts;
private ATM[] atms;
Bank(){}
public Bank(String name, User[] users, Account[] accounts, ATM[] atms) {
this.name = name;
this.users = users;
this.accounts = accounts;
this.atms = atms;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User[] getUsers() {
return users;
}
public void setUsers(User[] users) {
this.users = users;
}
public Account[] getAccounts() {
return accounts;
}
public void setAccounts(Account[] accounts) {
this.accounts = accounts;
}
public ATM[] getAtms() {
return atms;
}
public void setAtms(ATM[] atms) {
this.atms = atms;
}
}
class User{
private String name;
private Account[] accounts;
public String getName() {
return name;
}
public User() {
}
public User(String name, Account[] accounts) {
this.name = name;
this.accounts = accounts;
}
public void setName(String name) {
this.name = name;
}
public Account[] getAccounts() {
return accounts;
}
public void setAccounts(Account[] accounts) {
this.accounts = accounts;
}
}
class Account{
private String id;
private Card[] cards;
private double balance;
public Account() {
}
public Account(String id, Card[] cards,double balance) {
this.id = id;
this.cards = cards;
this.balance=balance;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Card[] getCards() {
return cards;
}
public void setCards(Card[] cards) {
this.cards = cards;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}
class Card{
private String id;
private String password="88888888";
public Card() {
}
public Card(String id) {
this.id = id;
}
public void setId(String id) {
this.id = id;
}
public void setPassword(String password) {
this.password = password;
}
public String getId() {
return id;
}
public String getPassword() {
return password;
}
}
class ATM{
private String id;
public ATM() {
}
public ATM(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
class Data{
private UnionPay unionPay;
Data(){
Card card1 = new Card("6217000010041315709");
Card card2 = new Card("6217000010041315715");
Card card3 = new Card("6217000010041315718");
Card card4 = new Card("6217000010051320007");
Card card5 = new Card("6222081502001312389");
Card card6 = new Card("6222081502001312390");
Card card7 = new Card("6222081502001312399");
Card card8 = new Card("6222081502001312400");
Card card9 = new Card("6222081502051320785");
Card card10 = new Card("6222081502051320786");
Card[] cards1 = {card1,card2};
Card[] cards2 = {card3};
Card[] cards3 = {card4};
Card[] cards4 = {card5};
Card[] cards5 = {card6};
Card[] cards6 = {card7,card8};
Card[] cards7 = {card9};
Card[] cards8 = {card10};
Account account1 = new Account("3217000010041315709",cards1,10000.00);
Account account2= new Account("3217000010041315715",cards2,10000.00);
Account account3 = new Account("3217000010051320007",cards3,10000.00);
Account account4 = new Account("3222081502001312389",cards4,10000.00);
Account account5 = new Account("3222081502001312390",cards5,10000.00);
Account account6 = new Account("3222081502001312399",cards6,10000.00);
Account account7 = new Account("3222081502051320785",cards7,10000.00);
Account account8 = new Account("3222081502051320786",cards8,10000.00);
Account[] accounts1 = {account1,account2};
Account[] accounts2 = {account3};
Account[] accounts3 = {account4,account5,account6};
Account[] accounts4 = {account7,account8};
User user1 = new User("杨过",accounts1);
User user2 = new User("郭靖",accounts2);
User user3 = new User("张无忌",accounts3);
User user4 = new User("韦小宝",accounts4);
User[] users1 = {user1,user2};
User[] users2 = {user3,user4};
Account[] accounts01={account1,account2,account3};
Account[] accounts02={account4,account5,account6,account7,account8};
ATM atm1 = new ATM("01");
ATM atm2 = new ATM("02");
ATM atm3 = new ATM("03");
ATM atm4 = new ATM("04");
ATM atm5 = new ATM("05");
ATM atm6 = new ATM("06");
ATM[] atms1 = {atm1,atm2,atm3,atm4};
ATM[] atms2 = {atm5,atm6};
Bank bank1 = new Bank("中国建设银行",users1,accounts01,atms1);
Bank bank2 = new Bank("中国工商银行",users2,accounts02,atms2);
Bank[] banks = {bank1,bank2};
unionPay = new UnionPay("中国银联",banks);
}
public UnionPay getUnionPay() {
return unionPay;
}
public void setUnionPay(UnionPay unionPay) {
this.unionPay = unionPay;
}
public void setBalance(String cardId,double money){
searchAccount(cardId).setBalance(searchAccount(cardId).getBalance()+money);
}
public Account searchAccount(String s){
Bank[] banks=unionPay.getBanks();
for(int i=0;i<banks.length;i++){
Account[] accounts=banks[i].getAccounts();
for(int j=0;j<accounts.length;j++){
Card[] cards=accounts[j].getCards();
for(int k=0;k<cards.length;k++){
if(cards[k].getId().equals(s))
return accounts[j];
}
}
}
return null;
}
}
class DealData{
private String s;
private Data data;
DealData(){}
DealData(String s,Data data){
this.s=s;
this.data=data;
}
public void getDataResult(){
String[] s01 = s.split(" ");
String[] s1 = new String[4];
int k=0;
for(int i=0;i<s01.length;i++){
if(s01[i].compareTo("")!=0){
s1[k]=s01[i];
k++;
}
}
if(s01.length==1){
if(rightCard(s1[0])){
System.out.printf("¥%.2f\n",searchAccount(s1[0]).getBalance());
}
}
else {
if(rightCard(s1[0])){
if(rightPassword(s1[1])){
if(rightATM(s1[2])){
if(isLowBalance(s1[0],s1[3])){
if(isSameBank(s1[0],s1[2])){
String user_name = searchUser(s1[0]).getName();
String bank_name = searchBank(s1[0]).getName();
double money = Double.parseDouble(s1[3]);
if(isTakeMoney(s1[3])) {
System.out.printf(user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上取款¥%.2f\n",money);
money=-money;
}
else {
money=-money;
System.out.printf(user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上存款¥%.2f\n",money);
}
setBalance(s1[0],money);
System.out.printf("当前余额为¥%.2f\n",searchAccount(s1[0]).getBalance());
}
}
}
}
}
}
}
public void setBalance(String cardId,double money){
data.setBalance(cardId,money);
}
public boolean isTakeMoney(String s){
double money = Double.parseDouble(s);
if(money>0)
return true;
else
return false;
}
public Bank searchBank(String s){
Bank[] banks=data.getUnionPay().getBanks();
for(int i=0;i<banks.length;i++){
Account[] accounts=banks[i].getAccounts();
for(int j=0;j<accounts.length;j++){
Card[] cards=accounts[j].getCards();
for(int k=0;k<cards.length;k++){
if(cards[k].getId().equals(s))
return banks[i];
}
}
}
return null;
}
public User searchUser(String s){
Bank[] banks=data.getUnionPay().getBanks();
for(int i=0;i<banks.length;i++){
User[] users=banks[i].getUsers();
for(int j=0;j<users.length;j++){
Account[] accounts=users[j].getAccounts();
for(int k=0;k<accounts.length;k++){
Card[] cards = accounts[k].getCards();
for(int q=0;q<cards.length;q++){
if(cards[q].getId().equals(s))
return users[j];
}
}
}
}
return null;
}
public Account searchAccount(String s){
Bank[] banks=data.getUnionPay().getBanks();
for(int i=0;i<banks.length;i++){
Account[] accounts=banks[i].getAccounts();
for(int j=0;j<accounts.length;j++){
Card[] cards=accounts[j].getCards();
for(int k=0;k<cards.length;k++){
if(cards[k].getId().equals(s))
return accounts[j];
}
}
}
return null;
}
public Card searchCard(String s){
Bank[] banks=data.getUnionPay().getBanks();
for(int i=0;i<banks.length;i++){
Account[] accounts=banks[i].getAccounts();
for(int j=0;j<accounts.length;j++){
Card[] cards=accounts[j].getCards();
for(int k=0;k<cards.length;k++){
if(cards[k].getId().equals(s))
return cards[k];
}
}
}
return null;
}
public boolean isLowBalance(String s1,String s){
double money = Double.parseDouble(s);
if(money<=searchAccount(s1).getBalance())
return true;
else {
System.out.println("Sorry,your account balance is insufficient.");
return false;
}
}
public boolean isSameBank(String s1,String s2){
Bank[] banks=data.getUnionPay().getBanks();
for(int i=0;i<banks.length;i++){
ATM[] atms=banks[i].getAtms();
for(int j=0;j<atms.length;j++){
if(atms[j].getId().equals(s2)){
Account[] accounts=banks[i].getAccounts();
for(int j1=0;j1<accounts.length;j1++){
Card[] cards=accounts[j1].getCards();
for(int k=0;k<cards.length;k++){
if(cards[k].getId().equals(s1))
return true;
}
}
}
}
}
System.out.println("Sorry,cross-bank withdrawal is not supported.");
return false;
}
public boolean rightCard(String s){
Bank[] banks=data.getUnionPay().getBanks();
for(int i=0;i<banks.length;i++){
Account[] accounts=banks[i].getAccounts();
for(int j=0;j<accounts.length;j++){
Card[] cards=accounts[j].getCards();
for(int k=0;k<cards.length;k++){
if(cards[k].getId().equals(s))
return true;
}
}
}
System.out.println("Sorry,this card does not exist.");
return false;
}
public boolean rightPassword(String s){
if(s.compareTo("88888888")==0)
return true;
else{
System.out.println("Sorry,your password is wrong.");
return false;
}
}
public boolean rightATM(String s){
Bank[] banks=data.getUnionPay().getBanks();
for(int i=0;i<banks.length;i++){
ATM[] atms=banks[i].getAtms();
for(int j=0;j<atms.length;j++){
if(atms[j].getId().equals(s))
return true;
}
}
System.out.println("Sorry,the ATM's id is wrong.");
return false;
}
}

这道题没有给类图,因此在做这道题的时候花费了较多的时间。类的设计我主要是根据作业说明里的信息来做的,我个人其实并不满意自己设计的类,因为耦合性太高了,通过这次设计类,我感受到了自己在设计这方面的不足,这道题里,类之间的多对一关系较难处理。

我这道题其实主要是在DealData类里完成的,DealData类相当于控制类,Data类用来存储原始数据,主要思想就是遍历数组,直到搜索到目标字符串,然后返回需要的信息,代码如下:

public Card searchCard(String s){
Bank[] banks=data.getUnionPay().getBanks();
for(int i=0;i<banks.length;i++){
Account[] accounts=banks[i].getAccounts();
for(int j=0;j<accounts.length;j++){
Card[] cards=accounts[j].getCards();
for(int k=0;k<cards.length;k++){
if(cards[k].getId().equals(s))
return cards[k];
}
}
}
return null;
}

实现业务功能的主要代码如下:

public void getDataResult(){
String[] s01 = s.split(" ");
String[] s1 = new String[4];
int k=0;
for(int i=0;i<s01.length;i++){
if(s01[i].compareTo("")!=0){
s1[k]=s01[i];
k++;
}
}
if(s01.length==1){
if(rightCard(s1[0])){
System.out.printf("¥%.2f\n",searchAccount(s1[0]).getBalance());
}
}
else {
if(rightCard(s1[0])){
if(rightPassword(s1[1])){
if(rightATM(s1[2])){
if(isLowBalance(s1[0],s1[3])){
if(isSameBank(s1[0],s1[2])){
String user_name = searchUser(s1[0]).getName();
String bank_name = searchBank(s1[0]).getName();
double money = Double.parseDouble(s1[3]);
if(isTakeMoney(s1[3])) {
System.out.printf(user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上取款¥%.2f\n",money);
money=-money;
}
else {
money=-money;
System.out.printf(user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上存款¥%.2f\n",money);
}
setBalance(s1[0],money);
System.out.printf("当前余额为¥%.2f\n",searchAccount(s1[0]).getBalance());
}
}
}
}
}
}
}

7-5 ATM机类结构设计(二)

作者 段喜龙
单位 南昌航空大学

设计ATM仿真系统,具体要求参见作业说明。
OO作业9-1题目说明.pdf

输入格式:

每一行输入一次业务操作,可以输入多行,最终以字符#终止。具体每种业务操作输入格式如下:

  • 取款功能输入数据格式:
    卡号 密码 ATM机编号 金额(由一个或多个空格分隔)
  • 查询余额功能输入数据格式:
    卡号

输出格式:

①输入错误处理

  • 如果输入卡号不存在,则输出Sorry,this card does not exist.
  • 如果输入ATM机编号不存在,则输出Sorry,the ATM's id is wrong.
  • 如果输入银行卡密码错误,则输出Sorry,your password is wrong.
  • 如果输入取款金额大于账户余额,则输出Sorry,your account balance is insufficient.

②取款业务输出

输出共两行,格式分别为:

业务:取款 [用户姓名]在[银行名称]的[ATM编号]上取款¥[金额]

当前余额为¥[金额]

其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。

③查询余额业务输出

业务:查询余额 ¥[金额]

金额保留两位小数。

import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String str = input.nextLine();
Data data = new Data();
while (str.compareTo("#")!=0){
DealData dealData = new DealData(str,data);
dealData.getDataResult();
str = input.nextLine();
}
}
}
class UnionPay{
private String name;
private Bank[] banks;
UnionPay(){}
UnionPay(String name,Bank[] banks){
this.name=name;
this.banks=banks;
}
public Bank[] getBanks() {
return banks;
}
}
class Bank{
private String name;
private User[] users;
private Account[] accounts;
private ATM[] atms;
Bank(){}
public Bank(String name, User[] users, Account[] accounts, ATM[] atms) {
this.name = name;
this.users = users;
this.accounts = accounts;
this.atms = atms;
}
public String getName() {
return name;
}
public User[] getUsers() {
return users;
}
public Account[] getAccounts() {
return accounts;
}
public ATM[] getAtms() {
return atms;
}
}
class User{
private String name;
private Account[] accounts;
public String getName() {
return name;
}
public User() {
}
public User(String name, Account[] accounts) {
this.name = name;
this.accounts = accounts;
}
public Account[] getAccounts() {
return accounts;
}
}
class Account{
private String id;
private Card[] cards;
private double balance;
private boolean kind;//true为借记,false为贷记
public Account() {
}
public Account(String id, Card[] cards,double balance) {
this.id = id;
this.cards = cards;
this.balance=balance;
this.kind=true;
}
public boolean isKind() {
return kind;
}
public void setKind(boolean kind) {
this.kind = kind;
}
public Card[] getCards() {
return cards;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}
class Card{
private String id;
private String password="88888888";
public Card() {
}
public Card(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
class ATM{
private String id;
public ATM() {
}
public ATM(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
class Data{
private UnionPay unionPay;
Data(){
Card card1 = new Card("6217000010041315709");
Card card2 = new Card("6217000010041315715");
Card card3 = new Card("6217000010041315718");
Card card4 = new Card("6217000010051320007");
Card card5 = new Card("6222081502001312389");
Card card6 = new Card("6222081502001312390");
Card card7 = new Card("6222081502001312399");
Card card8 = new Card("6222081502001312400");
Card card9 = new Card("6222081502051320785");
Card card10 = new Card("6222081502051320786");
Card card11 = new Card("6640000010045442002");
Card card12 = new Card("6640000010045442003");
Card card13 = new Card("6640000010045441009");
Card card14 = new Card("6630000010033431001");
Card card15 = new Card("6630000010033431008");
Card[] cards1 = {card1,card2};
Card[] cards2 = {card3};
Card[] cards3 = {card4};
Card[] cards4 = {card5};
Card[] cards5 = {card6};
Card[] cards6 = {card7,card8};
Card[] cards7 = {card9};
Card[] cards8 = {card10};
Card[] cards9 = {card11,card12};
Card[] cards10 = {card13};
Card[] cards11 = {card14};
Card[] cards12 = {card15};
Account account1 = new Account("3217000010041315709",cards1,10000.00);
Account account2= new Account("3217000010041315715",cards2,10000.00);
Account account3 = new Account("3217000010051320007",cards3,10000.00);
Account account4 = new Account("3222081502001312389",cards4,10000.00);
Account account5 = new Account("3222081502001312390",cards5,10000.00);
Account account6 = new Account("3222081502001312399",cards6,10000.00);
Account account7 = new Account("3222081502051320785",cards7,10000.00);
Account account8 = new Account("3222081502051320786",cards8,10000.00);
Account account9 = new Account("3640000010045442002",cards9,10000.00);
Account account10 = new Account("3640000010045441009",cards10,10000.00);
Account account11 = new Account("3630000010033431001",cards11,10000.00);
Account account12 = new Account("3630000010033431008",cards12,10000.00);
account9.setKind(false);
account10.setKind(false);
account11.setKind(false);
account12.setKind(false);
Account[] accounts1 = {account1,account2};
Account[] accounts2 = {account3};
Account[] accounts3 = {account4,account5,account6};
Account[] accounts4 = {account7,account8};
Account[] accounts5 = {account9};
Account[] accounts6 = {account10};
Account[] accounts7 = {account11};
Account[] accounts8 = {account12};
User user1 = new User("杨过",accounts1);
User user2 = new User("郭靖",accounts2);
User user3 = new User("张无忌",accounts3);
User user4 = new User("韦小宝",accounts4);
User user5 = new User("张三丰",accounts5);
User user6 = new User("令狐冲",accounts6);
User user7 = new User("乔峰",accounts7);
User user8 = new User("洪七公",accounts8);
User[] users1 = {user1,user2,user5};
User[] users2 = {user3,user4,user6};
User[] users3 = {user7,user8};
Account[] accounts01={account1,account2,account3,account9};
Account[] accounts02={account4,account5,account6,account7,account8,account10};
Account[] accounts03={account11,account12};
ATM atm1 = new ATM("01");
ATM atm2 = new ATM("02");
ATM atm3 = new ATM("03");
ATM atm4 = new ATM("04");
ATM atm5 = new ATM("05");
ATM atm6 = new ATM("06");
ATM atm7 = new ATM("07");
ATM atm8 = new ATM("08");
ATM atm9 = new ATM("09");
ATM atm10 = new ATM("10");
ATM atm11 = new ATM("11");
ATM[] atms1 = {atm1,atm2,atm3,atm4};
ATM[] atms2 = {atm5,atm6};
ATM[] atms3 = {atm7,atm8,atm9,atm10,atm11};
Bank bank1 = new Bank("中国建设银行",users1,accounts01,atms1);
Bank bank2 = new Bank("中国工商银行",users2,accounts02,atms2);
Bank bank3 = new Bank("中国农业银行",users3,accounts03,atms3);
Bank[] banks = {bank1,bank2,bank3};
unionPay = new UnionPay("中国银联",banks);
}
public UnionPay getUnionPay() {
return unionPay;
}
public void setBalance(String cardId,double money){
searchAccount(cardId).setBalance(searchAccount(cardId).getBalance()+money);
}
public Account searchAccount(String s){
Bank[] banks=unionPay.getBanks();
for(int i=0;i<banks.length;i++){
Account[] accounts=banks[i].getAccounts();
for(int j=0;j<accounts.length;j++){
Card[] cards=accounts[j].getCards();
for(int k=0;k<cards.length;k++){
if(cards[k].getId().equals(s))
return accounts[j];
}
}
}
return null;
}
}
class DealData{
private String s;
private Data data;
DealData(){}
DealData(String s,Data data){
this.s=s;
this.data=data;
}
public void getDataResult(){
String[] s01 = s.split(" ");
String[] s1 = new String[4];
int k=0;
for(int i=0;i<s01.length;i++){
if(s01[i].compareTo("")!=0){
s1[k]=s01[i];
k++;
}
}
if(s01.length==1){
if(rightCard(s1[0])){
System.out.printf("业务:查询余额 ¥%.2f\n",searchAccount(s1[0]).getBalance());
}
}
else {
if(rightCard(s1[0])){
if(rightPassword(s1[1])){
if(rightATM(s1[2])){
if(searchAccount(s1[0]).isKind()){
if(isLowBalance(s1[0],s1[3],s1[2])) {
if (isSameBank(s1[0], s1[2])) {
String user_name = searchUser(s1[0]).getName();
String bank_name = searchBank(s1[2]).getName();
double money = Double.parseDouble(s1[3]);
if (isTakeMoney(s1[3])) {
System.out.printf("业务:取款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上取款¥%.2f\n", money);
money = -money;
} else {
money = -money;
System.out.printf("业务:存款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上存款¥%.2f\n", money);
}
setBalance(s1[0], money);
System.out.printf("当前余额为¥%.2f\n", searchAccount(s1[0]).getBalance());
} else {
String user_name = searchUser(s1[0]).getName();
String bank_name = searchBank(s1[2]).getName();
double money = Double.parseDouble(s1[3]);
double money1 = 0;
if (isTakeMoney(s1[3])) {
//手续费
money1=crossBankMoney(s1[2],s1[3]);
System.out.printf("业务:取款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上取款¥%.2f\n", money);
money = money1 + money;
money = -money;
} else {
money = -money;
System.out.printf("业务:存款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上存款¥%.2f\n", money);
}
setBalance(s1[0], money);
System.out.printf("当前余额为¥%.2f\n", searchAccount(s1[0]).getBalance());
}
}
else{
System.out.println("Sorry,your account balance is insufficient.");
}
}
else{
if(isLowBalance(s1[0],s1[3],s1[2])) {
if (isSameBank(s1[0], s1[2])) {
String user_name = searchUser(s1[0]).getName();
String bank_name = searchBank(s1[2]).getName();
double money = Double.parseDouble(s1[3]);
if (isTakeMoney(s1[3])) {
System.out.printf("业务:取款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上取款¥%.2f\n", money);
money = -money;
} else {
money = -money;
System.out.printf("业务:存款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上存款¥%.2f\n", money);
}
setBalance(s1[0], money);
System.out.printf("当前余额为¥%.2f\n", searchAccount(s1[0]).getBalance());
} else {
String user_name = searchUser(s1[0]).getName();
String bank_name = searchBank(s1[2]).getName();
double money = Double.parseDouble(s1[3]);
double money1 = 0;
if (isTakeMoney(s1[3])) {
//手续费
money1=crossBankMoney(s1[2],s1[3]);
System.out.printf("业务:取款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上取款¥%.2f\n", money);
money = money1 + money;
money = -money;
} else {
money = -money;
System.out.printf("业务:存款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上存款¥%.2f\n", money);
}
setBalance(s1[0], money);
System.out.printf("当前余额为¥%.2f\n", searchAccount(s1[0]).getBalance());
}
}else{
String user_name = searchUser(s1[0]).getName();
String bank_name = searchBank(s1[2]).getName();
double money = Double.parseDouble(s1[3]);
double t=money;
double money0 = 0;//透支手续费
if(searchAccount(s1[0]).getBalance()>0)
money0=(money-searchAccount(s1[0]).getBalance())*0.05;
else{
money0=(money)*0.05;
}
if (isSameBank(s1[0], s1[2])) {
if (isTakeMoney(s1[3])) {
money+=money0;
money = -money;
setBalance(s1[0], money);
if(searchAccount(s1[0]).getBalance()<=-50000){
System.out.println("Sorry,your account balance is insufficient.");
}else
System.out.printf("业务:取款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上取款¥%.2f\n", t);
} else {
money = -money;
System.out.printf("业务:存款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上存款¥%.2f\n", money);
setBalance(s1[0], money);
}
} else {
double money1 = 0;
if (isTakeMoney(s1[3])) {
//手续费
money1=crossBankMoney(s1[2],s1[3]);
money = money1 + money;
money+=money0;
money = -money;
setBalance(s1[0], money);
if(searchAccount(s1[0]).getBalance()<=-50000){
System.out.println("Sorry,your account balance is insufficient.");
}else
System.out.printf("业务:取款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上取款¥%.2f\n", t);
} else {
money = -money;
System.out.printf("业务:存款 " + user_name + "在" + bank_name + "的" + s1[2] + "号ATM机上存款¥%.2f\n", money);
setBalance(s1[0], money);
}
}
if(searchAccount(s1[0]).getBalance()>-50000)
System.out.printf("当前余额为¥%.2f\n", searchAccount(s1[0]).getBalance());
}
}
}
}
}
}
}
public double crossBankMoney(String s,String s1){//s ATM,s1 money
double money1=0;
double money = Double.parseDouble(s1);
if (searchBank(s).getName().equals("中国建设银行")) {
money1 = money * 0.02;
}
if (searchBank(s).getName().equals("中国工商银行")) {
money1 = money * 0.03;
}
if (searchBank(s).getName().equals("中国农业银行")) {
money1 = money * 0.04;
}
return money1;
}
public void setBalance(String cardId,double money){
data.setBalance(cardId,money);
}
public boolean isTakeMoney(String s){
double money = Double.parseDouble(s);
if(money>0)
return true;
else
return false;
}
public Bank searchBank(String s){
Bank[] banks=data.getUnionPay().getBanks();
for(int i=0;i<banks.length;i++){
ATM[] atms=banks[i].getAtms();
for(int j=0;j<atms.length;j++){
if(atms[j].getId().equals(s))
return banks[i];
}
}
return null;
}
public User searchUser(String s){
Bank[] banks=data.getUnionPay().getBanks();
for(int i=0;i<banks.length;i++){
User[] users=banks[i].getUsers();
for(int j=0;j<users.length;j++){
Account[] accounts=users[j].getAccounts();
for(int k=0;k<accounts.length;k++){
Card[] cards = accounts[k].getCards();
for(int q=0;q<cards.length;q++){
if(cards[q].getId().equals(s))
return users[j];
}
}
}
}
return null;
}
public Account searchAccount(String s){
Bank[] banks=data.getUnionPay().getBanks();
for(int i=0;i<banks.length;i++){
Account[] accounts=banks[i].getAccounts();
for(int j=0;j<accounts.length;j++){
Card[] cards=accounts[j].getCards();
for(int k=0;k<cards.length;k++){
if(cards[k].getId().equals(s))
return accounts[j];
}
}
}
return null;
}
public boolean isLowBalance(String s1,String s,String s2){
double money = Double.parseDouble(s);
if(isSameBank(s1,s2)){
if(money<=searchAccount(s1).getBalance())
return true;
else {
return false;
}
}else{
if(money+crossBankMoney(s2,s)<=searchAccount(s1).getBalance())
return true;
else {
return false;
}
}
}
public boolean isSameBank(String s1,String s2){
Bank[] banks=data.getUnionPay().getBanks();
for(int i=0;i<banks.length;i++){
ATM[] atms=banks[i].getAtms();
for(int j=0;j<atms.length;j++){
if(atms[j].getId().equals(s2)){
Account[] accounts=banks[i].getAccounts();
for(int j1=0;j1<accounts.length;j1++){
Card[] cards=accounts[j1].getCards();
for(int k=0;k<cards.length;k++){
if(cards[k].getId().equals(s1))
return true;
}
}
}
}
}
return false;
}
public boolean rightCard(String s){
Bank[] banks=data.getUnionPay().getBanks();
for(int i=0;i<banks.length;i++){
Account[] accounts=banks[i].getAccounts();
for(int j=0;j<accounts.length;j++){
Card[] cards=accounts[j].getCards();
for(int k=0;k<cards.length;k++){
if(cards[k].getId().equals(s))
return true;
}
}
}
System.out.println("Sorry,this card does not exist.");
return false;
}
public boolean rightPassword(String s){
if(s.compareTo("88888888")==0)
return true;
else{
System.out.println("Sorry,your password is wrong.");
return false;
}
}
public boolean rightATM(String s){
Bank[] banks=data.getUnionPay().getBanks();
for(int i=0;i<banks.length;i++){
ATM[] atms=banks[i].getAtms();
for(int j=0;j<atms.length;j++){
if(atms[j].getId().equals(s))
return true;
}
}
System.out.println("Sorry,the ATM's id is wrong.");
return false;
}
}

这题与上一题相比主要多了两个内容,一个是可以跨行处理业务,一个是银行账户分借记账户和贷记账户。

处理以上两个新增内容,我主要是通过增加判断来完成,比如判断银行账户的种类:

private boolean kind;//true为借记,false为贷记
public boolean isKind() {
return kind;
}

判断是否跨行,如果是,判断在哪个银行,这个银行的手续费是多少,代码如下:

public double crossBankMoney(String s,String s1){//s ATM,s1 money
double money1=0;
double money = Double.parseDouble(s1);
if (searchBank(s).getName().equals("中国建设银行")) {
money1 = money * 0.02;
}
if (searchBank(s).getName().equals("中国工商银行")) {
money1 = money * 0.03;
}
if (searchBank(s).getName().equals("中国农业银行")) {
money1 = money * 0.04;
}
return money1;
}

然后还有个主要问题就是判断余额是否大于取款,如果跨行,还要考虑到手续费,代码如下:

public boolean isLowBalance(String s1,String s,String s2){
double money = Double.parseDouble(s);
if(isSameBank(s1,s2)){
if(money<=searchAccount(s1).getBalance())
return true;
else {
return false;
}
}else{
if(money+crossBankMoney(s2,s)<=searchAccount(s1).getBalance())
return true;
else {
return false;
}
}
}

踩坑心得

  1. 题目集四7-1中,通过一个含有年月日的具体日期来判断该日期为星期几,可以使用time包下的LocalDate和DayOfWeek;
  2. 题目集六7-4中,由于类与类之间大多是多对一之间的关系,而且都是以数组为属性,所以在搜索某一确定的实例化对象时需要遍历所有在它的上层数组,设计类的时候把所有的处理方法都放在DealData一个类中,非常不方便,应该在每个类里创造一个搜索方法,在DealData中只要逐一调用;
  3. 在题目集六中,方法设计时犯了低级错误,在形参命名时并没有使用英文全称,偷懒使用s字母,导致在后续调用方法时忘记了形参是什么,结果又要返回去看代码,浪费了很多时间,这也是给自己埋雷,长个教训。如:public Account searchAccount(String s);
  4. 要多留心空格,有个测试点格式错误,找空格找了一个小时,结果是在人名后面多了个空格;另外在String类中经常要对空格进行删除,常见的有replace(" ","")删除所有空格trim()//删除首尾空格
  5. pta测试点经常出现非零返回,一般来说都是数组越界,回顾代码,推测是slipt返回的新数组与设想的数组长度不同,我的解决方案是加入判断,如果所返回的数组长度与预设长度不一致,则跳过;

改进建议

  1. 规范命名,不要嫌弃名字过长,易懂最重要;
  2. 设计类时,每个类应该要有一些基本处理信息的方法,不要把所有的步骤都堆积到一个类里,如题目集六7-4中的DealData类;
  3. 设计类时,要时刻记得七大设计原则——SRP,迪米特法则,OCP,合成复用原则,LSP,接口隔离原则,依赖倒转原则;

总结

上一次总结偏向于语法的学习,这一次重点更偏向于设计,设计时不光要考虑到每个类本身,还要考虑到各个类之间的关系。

这三次题目集收获颇多,对语法的掌握有了更深的理解,通过题目集六对类的设计也有了新的认识,对类的七大设计原则也有了切身的体会;但在类的设计过程中,明显感觉到自己对于这方面比较生疏,最后生成的类图也反应出虽然拿了满分,但类之间的关系还存在很大的改进空间。

设计对我而言学习之路还很长,老师最近还在给我们讲23种设计模式,这些设计模式能明显的反映出七大设计原则,使我们对类的设计有更好的理解。

posted @   B饭老司机  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示