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] , 设计类图如下:
应用程序共测试三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
注意:严禁使用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] , 设计类图如下:
应用程序共测试三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
注意:严禁使用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; } } }
踩坑心得
- 题目集四7-1中,通过一个含有年月日的具体日期来判断该日期为星期几,可以使用time包下的LocalDate和DayOfWeek;
- 题目集六7-4中,由于类与类之间大多是多对一之间的关系,而且都是以数组为属性,所以在搜索某一确定的实例化对象时需要遍历所有在它的上层数组,设计类的时候把所有的处理方法都放在DealData一个类中,非常不方便,应该在每个类里创造一个搜索方法,在DealData中只要逐一调用;
- 在题目集六中,方法设计时犯了低级错误,在形参命名时并没有使用英文全称,偷懒使用s字母,导致在后续调用方法时忘记了形参是什么,结果又要返回去看代码,浪费了很多时间,这也是给自己埋雷,长个教训。如:
public Account searchAccount(String s)
; - 要多留心空格,有个测试点格式错误,找空格找了一个小时,结果是在人名后面多了个空格;另外在String类中经常要对空格进行删除,常见的有
replace(" ","")删除所有空格
和trim()//删除首尾空格
; - pta测试点经常出现非零返回,一般来说都是数组越界,回顾代码,推测是slipt返回的新数组与设想的数组长度不同,我的解决方案是加入判断,如果所返回的数组长度与预设长度不一致,则跳过;
改进建议
- 规范命名,不要嫌弃名字过长,易懂最重要;
- 设计类时,每个类应该要有一些基本处理信息的方法,不要把所有的步骤都堆积到一个类里,如题目集六7-4中的DealData类;
- 设计类时,要时刻记得七大设计原则——SRP,迪米特法则,OCP,合成复用原则,LSP,接口隔离原则,依赖倒转原则;
总结
上一次总结偏向于语法的学习,这一次重点更偏向于设计,设计时不光要考虑到每个类本身,还要考虑到各个类之间的关系。
这三次题目集收获颇多,对语法的掌握有了更深的理解,通过题目集六对类的设计也有了新的认识,对类的七大设计原则也有了切身的体会;但在类的设计过程中,明显感觉到自己对于这方面比较生疏,最后生成的类图也反应出虽然拿了满分,但类之间的关系还存在很大的改进空间。
设计对我而言学习之路还很长,老师最近还在给我们讲23种设计模式,这些设计模式能明显的反映出七大设计原则,使我们对类的设计有更好的理解。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)