OOP4-6题目集总结
4-6次题目集,从集合框架,正则表达式,类的继承与多态三个方面展开,在帮助我们了解java常用的工具(集合框架,正则表达式)的同时让我们学着利用类与类之间的关系来减少耦合,第六次题目集侧重于类的继承与多态,同时让我们自己根据题目设计类来解题,在了解面向对象的编程思想后,加强我们对类与类之间关系的理解,不再是面向过程的编程了,要学着转变思想。写题目也不能一味的拿到题目就开写,没有好的构思,写的再多还是要重写!!多构思!!
前言:
作业相关知识点:
1.第四次作业主要是对于集合框架(ArraryList,Set相关知识点的练习)同时加入点菜,加强我们对类的封装及类与类之间关系的理解;
2.第五次作业主要是关于正则表达式处理字符串(字符串判断,字符排序等)这一方面知识点的学习,同时将之前题目集的日期类改用聚合关系实现,加深对类之间关系的理解;
3.第六次作业先是继承与多态的理解,再从根据老师给的类图编写程序到自己根据题目设计类图再来解决问题,这就体现了面向对象编程思维的重要性,正确的构思可以提高效率。
4.这三次题目集,从我们近期所学的知识点进行设计,不仅对要学习的java工具有练习,同时让我们从根据类图完成题目到自己设计类来解决题目,加强对面向对象的了解。
作业题量:
三次作业题量为7+6+5,题目量不大但仍需花时间来静下心去写。
作业难度:
按照五颗星难度标准,在我看来,第4次作业的7-1(菜单计价程序-3)为5★(花的时间较多,没有构思整个框架),第四次的其他题目都比较基础加强我们对集合框架的理解;第五次作业的日期问题(两次聚合)的难度为3★,因为给出了类图更多的是理解类与类之间的关系;第六次作业水文数据处理的难度为3★,ATM机需要我们自己去根据需求设计类,我卡了一个测试点,总体难度不大为3★。
设计与分析:
1.菜单计价程序(第三次题目集7-1)
通过Dish,Menu,Record,Oreder等四个类实现对点菜系统的模拟(计算总价,判断点的菜是否在菜单中,删除菜品,是否在营业时间内),多桌点菜的信息在点菜结束后一起输出,在输入,输出的考虑上我没有太多的构思,实际上可以写两个类来储存点菜信息,处理数据后,在通过输出信息类进行输出,这样可以避免主函数的冗余。编程习惯还是太差了,在写的时候走一步看一步,没有提前构思好,导致花了很多时间但效率不是很高,最终也只是拿到了单桌测试的分数。
SourceMonitor分析:
由于在主函数写了大量的if语句去判断点菜的合法及处理信息,所以最大圈复杂度不合理,主函数的深度也很大,写了答辩代码;
类图:
只是对基本的四个类进行了设计,输入,处理,输出都放在了主函数中,要写好这道题所需要的类远不止这些,构思上就已经出了问题。
实现代码(写的一言难尽):
import java.time.LocalDate;
import java.util.*;
class Dish {
public String name; //菜名
public int unit_price; //单价
public Dish() { }
public Dish(String name, int unit_price) {
this .name = name;
this .unit_price = unit_price;
}
public String getName() {
return this .name;
}
public void setName(String name) {
this .name = name;
}
public int getUnit_price() {
return this .unit_price;
}
public void setUnit_price( int unit_price) {
this .unit_price = unit_price;
}
public int getPrice( int portion) {
if (portion == 1 ) {
return this .unit_price;
}
else if (portion == 2 ) {
return ( int )(unit_price* 1.5 + 0.5 );
} else {
return this .unit_price* 2 ;
}
}
}
class Menu {
Dish dish;
public static ArrayList<String> notExistDishName = new ArrayList<>();
private ArrayList<Dish> dishs = new ArrayList<>(); //菜品数组
public void addDish(String dishName, int unit_price) {
dish = new Dish(dishName, unit_price);
dishs.add(dish);
}
public Dish searchDish(String disName) {
for ( int i = 0 ;i < dishs.size();i++) {
if (disName.equals(dishs.get(i).getName())) {
return dishs.get(i);
}
}
return null ; // 没找到
}
}
class Record {
public int orderNum; // 序号
public Dish dish;
public int portion; // 份额
public int num; // 份数
public Record() { }
public Record( int orderNum, Dish dish, int portion, int num) {
this .orderNum = orderNum;
this .dish = dish;
this .portion = portion;
this .num = num;
}
public int getOrderNum() {
return orderNum;
} public void setOrderNum( int orderNum) {
this .orderNum = orderNum;
} public Dish getDish() {
return dish;
} public void setDish(Dish dish) {
this .dish = dish;
} public int getPortion() {
return portion;
} public void setPortion( int portion) {
this .portion = portion;
} public int getNum() {
return num;
} public void setNum( int num) {
this .num = num;
}
public int getPrice() { // 计算这条记录的价格
return dish.getPrice(portion) * num;
}
} class Order {
ArrayList<Record> records;
public static int differenceMoney; // 要删除菜品的价钱
public static int errorDeleteTime; //删除错误的次数
public int getDifferenceMoney() {
return differenceMoney;
}
public void setDifferenceMoney( int differenceMoney) {
this .differenceMoney = differenceMoney;
}
public Order() {
records = new ArrayList<>();
}
public int getTotalPrice() { // 获得总价
int totalPrice = 0 ;
for (Record record : records) {
totalPrice += record.getPrice();
}
return totalPrice;
}
public Record addARecord( int orderNum, String dishName, int portion, int num, Menu menu) {
Dish dish = menu.searchDish(dishName); // 要添加的在菜单中是否存在
if (dish == null ) {
Menu.notExistDishName.add(dishName);
System.out.println(dishName + " does not exist" );
return null ;
}
Record record = new Record(orderNum, dish, portion, num);
records.add(record);
return record;
}
public void delARecordByOrderNum( int orderNum) { // 根据序号删除一条记录
for ( int i = 0 ; i < records.size(); i++) {
if (records.get(i).orderNum == orderNum) {
differenceMoney += records.get(i).getPrice();
return ;
}
}
//errorDeleteTime += 1;
System.out.println( "delete error;" ); // 序号不存在
}
public Record findRecordByNum( int orderNum) { // 根据序号查找
for (Record record : records) {
if (record.orderNum == orderNum) {
return record;
}
}
return null ; // 没找到
}
}
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
ArrayList<String> outPut = new ArrayList<String>(); // 最后要输出的信息
Menu menu = new Menu();
double discount = 1.0 ;
String line = input.nextLine();
while (!line.equals( "end" )) {
if (line.startsWith( "table" )) {
String[] parts = line.split( "\\s+" );
int tableNum = Integer.parseInt(parts[ 1 ]);
System.out.println( "table " + tableNum + ": " );
String date = parts[ 2 ];
LocalDate currentDate = LocalDate.of(Integer.parseInt(parts[ 2 ].split( "/" )[ 0 ]), Integer.parseInt(parts[ 2 ].split( "/" )[ 1 ]),
Integer.parseInt(parts[ 2 ].split( "/" )[ 2 ]));
String week = String.valueOf(currentDate.getDayOfWeek());
String time = parts[ 3 ];
Order order = new Order();
int totalPrice = 0 ;
boolean isDiscount = false ;
boolean outTime = false ;
while ( true ){
line = input.nextLine();
if (line.contains( "end" )) {
break ;
}
if (line.startsWith( "table" )) {
break ;
} else if (line.contains( "delete" )) { // 删除菜品
int deleteNum = Integer.parseInt(line.split( "\\s+" )[ 0 ]);
order.delARecordByOrderNum(deleteNum);
} else {
String[] parts2 = line.split( "\\s+" );
if (parts2.length > 2 && parts2.length <= 4 ) {
int orderNum = Integer.parseInt(parts2[ 0 ]);
String dishName = parts2[ 1 ];
int portion = Integer.parseInt(parts2[ 2 ]);
int num = Integer.parseInt(parts2[ 3 ]);
Record record = order.addARecord(orderNum, dishName, portion, num, menu);
if (record != null ) {
totalPrice += record.getPrice();
System.out.println(record.orderNum + " " + record.dish.name + " " + record.getPrice());
}
}
else if (parts2.length > 4 ) {
int dNUm = Integer.parseInt(parts2[ 0 ]);
int orderNum = Integer.parseInt(parts2[ 1 ]);
String dishName = parts2[ 2 ];
int portion = Integer.parseInt(parts2[ 3 ]);
int num = Integer.parseInt(parts2[ 4 ]);
Record record = order.addARecord(orderNum, dishName, portion, num, menu);
if (record != null ) {
totalPrice += record.getPrice();
System.out.println(record.orderNum + " table " + tableNum + " pay for table " + dNUm + " " + record.getPrice());
}
}
}
}
int hour = Integer.parseInt(time.split( "/" )[ 0 ]);
int minute = Integer.parseInt(time.split( "/" )[ 1 ]);
if ( week.equals( "SATURDAY" ) || week.equals( "SUNDAY" )) {
if ( (hour > 9 && hour <= 21 ) || (hour == 9 && minute >= 30 ) ) {
isDiscount = true ;
discount = 1.0 ;
outTime = false ;
} else {
outTime = true ;
}
} else {
if ( hour > 10 && hour < 14 || (hour == 10 && minute >= 30 ) || (hour == 14 && minute <= 30 )) {
isDiscount = true ;
discount = 0.6 ;
}
else if ( (hour >= 17 && hour < 20 ) ||(hour == 20 && minute <= 30 ) ) {
isDiscount = true ;
discount = 0.8 ;
} else {
outTime = true ;
}
}
if (isDiscount) {
totalPrice = ( int )((totalPrice- Order.differenceMoney) * discount + 0.5 );
}
if (outTime) {
outPut.add( "table " + String.valueOf(tableNum) + " out of opening hours" );
} else {
outPut.add( "table " + String.valueOf(tableNum) + ": " + totalPrice);
}
} else {
String[] parts = line.split( "\\s+" );
String dishName = parts[ 0 ];
int unit_price = Integer.parseInt(parts[ 1 ]);
menu.addDish(dishName, unit_price);
line = input.nextLine();
}
}
for ( int i = 0 ; i <outPut.size();i++) {
System.out.println(outPut.get(i));
}
}
}
2. 日期问题面向对象设计(聚合一)(第五次题目集7-5)
在第三次题目集将day,month,year都放在DateUtil作为属性的基础上,设计了如下几个类:DateUtil、Year、Month、Day,类与类之间通过组合联系,在DateUtil中进行计算。
SourceMontior分析:
主函数对输入的操作做了判断,所以圈复杂度较高,其他的方面都还行。
类图:
实现代码:
import java.util.*;
class Day {
private int value;
private Month month;
private int [] mon_maxnum = new int []{ 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 }; public Day() {
}
public Day( int yearValue, int monthValue, int dayValue) {
this .value = dayValue;
this .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 month) {
this .month = month;
}
public void resetMin() { //天数复位为1
this .value = 1 ;
}
public void resetMax() { // 天数设为月最大
this .value = mon_maxnum[month.getValue()- 1 ];
}
public boolean validate() { // 天数在合法范围,注意闰年
if (month.getYear().isLeapYear()) {
mon_maxnum[ 1 ] = 29 ;
} else {
mon_maxnum[ 1 ] = 28 ;
}
if (value >= 1 && value <= mon_maxnum[month.getValue()- 1 ]) {
return true ;
} 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() {
value--;
if (month.getYear().isLeapYear()) { // 判断闰年
mon_maxnum[ 1 ] = 29 ;
} else {
mon_maxnum[ 1 ] = 28 ;
}
if (value <= 0 ) {
month.monthReduction();
resetMax();
}
}
} class Month {
private int value;
private Year year; public Month() {
}
public Month( int yearValue, int monthValue) {
this .value = monthValue;
this .year = new Year(yearValue);
} 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
this .value = 1 ;
}
public void resetMax() { // 月份设置为12
this .value = 12 ;
}
public boolean validate() {
if ( this .value >= 1 && this .value <= 12 ) {
return true ;
} else {
return false ;
}
}
public void monthIncrement() {
this .value++;
if (value > 12 ) { // 下一年
resetMin();
year.yearIncrement();
}
}
public void monthReduction() {
this .value--;
if (value <= 0 ) { // 上一年
resetMax();
year.yearReduction();
}
}
} class Year {
private int value; public Year() {
} public Year( int value) {
this .value = value;
} public int getValue() {
return value;
} public void setValue( int value) {
this .value = value;
} public boolean isLeapYear() {
if (( this .value % 4 == 0 && this .value % 100 != 0 ) || this .value % 400 == 0 ) {
return true ;
} else {
return false ;
}
} public boolean validate() {
if ( this .value >= 1900 && this .value <= 2050 ) {
return true ;
} else {
return false ;
}
}
public void yearIncrement() {
this .value++;
}
public void yearReduction() {
this .value--;
}
} class DateUtil {
private Day day;
public DateUtil() {
}
public DateUtil( int d, int m, int y) {
this .day = new Day(d, m, y);
} public Day getDay() {
return day;
} public void setDay(Day day) {
this .day = day;
}
public boolean checkInputValidity() {
if ( day.getMonth().getYear().validate() &&
day.getMonth().validate() &&
day.validate()) {
return true ;
} else {
return false ;
}
}
public boolean compareDates(DateUtil date) { // date 大于 day
if (day.getMonth().getYear().getValue() < date.getDay().getMonth().getYear().getValue()) {
return true ;
}
else if (date.getDay().getMonth().getYear().getValue() == day.getMonth().getYear().getValue() &&
date.getDay().getMonth().getValue() > day.getMonth().getValue()) {
return true ;
}
else if (date.getDay().getMonth().getYear().getValue() == day.getMonth().getYear().getValue() &&
date.getDay().getMonth().getValue() == day.getMonth().getValue() &&
date.getDay().getValue() > day.getValue()) {
return true ;
} else {
return false ;
}
}
public boolean equalTwoDates(DateUtil date) {
if (date.getDay().getMonth().getYear().getValue() == this .getDay().getMonth().getYear().getValue() &&
date.getDay().getMonth().getValue() == this .getDay().getMonth().getValue() &&
date.getDay().getValue() == this .getDay().getValue()) {
return true ;
} else {
return false ;
} }
public String showDate() {
return this .getDay().getMonth().getYear().getValue() + "-" + this .getDay().getMonth().getValue() + "-" +
this .getDay().getValue();
}
public DateUtil getNextNDays( int n) {
for ( int i = 0 ; i < n; i++) {
day.dayIncrement();
}
return this ;
}
public DateUtil getPreviousNDays( int n) {
for ( int i = 0 ; i < n; i++) {
day.dayReduction();
}
return this ;
}
public int getDaysofDates(DateUtil date) {
int daysDifference = 0 ;
if ( this .equalTwoDates(date)) {
return 0 ;
} else {
if ( this .compareDates(date)) { //date大 求date前的day
while (! this .equalTwoDates(date)) {
date.getPreviousNDays( 1 );
daysDifference++;
}
} else {
while (! this .equalTwoDates(date)) {
date.getNextNDays( 1 );
daysDifference++;
}
}
}
return daysDifference;
}
}
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int choice = input.nextInt();
int year;
int month;
int day;
if (choice == 1 ) { //下n天操作
int n = 0 ;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity()) { // 日期错误
System.out.println( "Wrong Format" );
System.exit( 0 );
}
n = input.nextInt();
date.getNextNDays(n);
System.out.println(date.showDate());
} else if (choice == 2 ) { // 上m天操作
int m = 0 ;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity()) { //日期错误
System.out.println( "Wrong Format" );
System.exit( 0 );
}
m = input.nextInt();
date.getPreviousNDays(m);
System.out.println(date.showDate());
} else if (choice == 3 ) { // 天数差
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
int anotherYear = Integer.parseInt(input.next());
int anotherMonth = Integer.parseInt(input.next());
int anotherDay = Integer.parseInt(input.next());
DateUtil anotherDate = new DateUtil(anotherYear, anotherMonth, anotherDay);
if (!date.checkInputValidity() || !anotherDate.checkInputValidity()) { //日期错误
System.out.println( "Wrong Format" );
System.exit( 0 );
}
System.out.println(date.getDaysofDates(anotherDate));
} else { // 错误操作
System.out.println( "Wrong Format" );
}
}
}
3. 日期问题面向对象设计(聚合二)(第五次题目集7-6)
在聚合一的基础上,改变了DateUtil、Year、Month、Day四个类之间的聚合关系,DateUtil与Year,Month,Day之间聚合,通过7-5还是比较容易修改的。
SourceMonitor分析:
大体与上次一致,只是改变了类之间的聚合关系
类图:
这个设计,DateUtil相当与一个中介,让Day,Month,Year之间没有直接的联系,减少了它们之间的耦合。
实现代码:
import java.util.*;
class Day {
private int value; public Day() {
}
public Day( int dayValue) {
this .value = dayValue;
} public int getValue() {
return value;
} public void setValue( int value) {
this .value = value;
} public void dayIncrement() {
value++;
}
public void dayReduction() {
value--;
} } class Month {
private int value; public Month() {
}
public Month( int monthValue) {
this .value = monthValue;
} public int getValue() {
return value;
} public void setValue( int value) {
this .value = value;
}
public void setMin() {
this .value = 1 ;
}
public void setMax() {
this .value = 12 ;
} public boolean validate() {
if ( this .value >= 1 && this .value <= 12 ) {
return true ;
} else {
return false ;
}
}
public void monthIncrement() {
this .value++;
}
public void monthReduction() {
this .value--;
}
} class Year {
private int value; public Year() {
} public Year( int value) {
this .value = value;
} public int getValue() {
return value;
} public void setValue( int value) {
this .value = value;
} public boolean isLeapYear() {
if (( this .value % 4 == 0 && this .value % 100 != 0 ) || this .value % 400 == 0 ) {
return true ;
} else {
return false ;
}
}
public boolean validate() {
if ( this .value >= 1820 && this .value <= 2020 ) {
return true ;
} else {
return false ;
}
}
public void yearIncrement() {
this .value++;
}
public void yearReduction() {
this .value--;
}
} class DateUtil {
private Day day;
private Month month;
private Year year;
private int [] mon_maxnum = new int []{ 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 };
public DateUtil() {
}
public DateUtil( int y, int m, int d) {
year = new Year(y);
month = new Month(m);
day = new Day(d);
} public Day getDay() {
return day;
} public void setDay(Day day) {
this .day = day;
} public Month getMonth() {
return month;
} public void setMonth(Month month) {
this .month = month;
} public Year getYear() {
return year;
} public void setYear(Year year) {
this .year = year;
} public void setDayMin() { //天数复位为1
day.setValue( 1 );
}
public void setDayMax() {
if (year.isLeapYear()) {
mon_maxnum[ 1 ] = 29 ;
} else {
mon_maxnum[ 1 ] = 28 ;
}
if (month.getValue() - 1 > 0 ) {
day.setValue(mon_maxnum[month.getValue()- 1 ]);
} else {
day.setValue(mon_maxnum[ 0 ]);
} }
public boolean checkInputValidity() {
if ( month.validate() && year.validate() &&
day.getValue() >= 1 && day.getValue() <= mon_maxnum[month.getValue()- 1 ]) {
return true ;
} else {
return false ;
}
}
public boolean compareDates(DateUtil date) { // date 大于 day
if (year.getValue() < date.year.getValue()) {
return true ;
}
else if (year.getValue() == date.year.getValue() && month.getValue() < date.month.getValue()) {
return true ;
}
else if (year.getValue() == date.year.getValue() && month.getValue() == date.month.getValue() &&
day.getValue() < date.day.getValue() ) {
return true ;
} else {
return false ;
}
}
public boolean equalTwoDates(DateUtil date) {
if (year.getValue() == date.year.getValue() && month.getValue() == date.month.getValue() &&
day.getValue() == date.day.getValue()) {
return true ;
} else {
return false ;
} }
public String showDate() {
return year.getValue() + "-" + month.getValue() + "-" + day.getValue();
}
public DateUtil getNextNDays( int n) {
for ( int i = 0 ; i < n; i++) {
if (year.isLeapYear()) {
mon_maxnum[ 1 ] = 29 ;
} else {
mon_maxnum[ 1 ] = 28 ;
}
day.dayIncrement();
if (day.getValue() > mon_maxnum[month.getValue()- 1 ]) {
setDayMin();
month.monthIncrement();
}
if (month.getValue() > 12 ) {
year.yearIncrement();
month.setMin();
}
}
return this ;
}
public DateUtil getPreviousNDays( int n) {
for ( int i = 0 ; i < n; i++) {
if (year.isLeapYear()) {
mon_maxnum[ 1 ] = 29 ;
} else {
mon_maxnum[ 1 ] = 28 ;
}
day.dayReduction();
if (day.getValue() <= 0 ) {
month.monthReduction();
setDayMax();
}
if (month.getValue() <= 0 ){
month.setMax();
year.yearReduction();
}
}
return this ;
}
public int getDaysofDates(DateUtil date) {
int daysDifference = 0 ;
if ( this .equalTwoDates(date)) {
return 0 ;
} else {
if ( this .compareDates(date)) { //date大 求date前的day
while (! this .equalTwoDates(date)) {
date.getPreviousNDays( 1 );
daysDifference++;
}
} else {
while (! this .equalTwoDates(date)) {
date.getNextNDays( 1 );
daysDifference++;
}
}
}
return daysDifference;
}
}
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int choice = input.nextInt();
int year;
int month;
int day;
if (choice == 1 ) { //下n天操作
int n = 0 ;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity()) { // 日期错误
System.out.println( "Wrong Format" );
System.exit( 0 );
}
n = input.nextInt();
System.out.print(date.getYear().getValue() + "-" + date.getMonth().getValue() + "-" + date.getDay().getValue() + " next " + n + " days is:" );
date.getNextNDays(n);
System.out.print(date.showDate());
} else if (choice == 2 ) { // 上m天操作
int m = 0 ;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity()) { //日期错误
System.out.println( "Wrong Format" );
System.exit( 0 );
}
m = input.nextInt();
System.out.print(date.getYear().getValue() + "-" + date.getMonth().getValue() + "-" + date.getDay().getValue() + " previous " + m + " days is:" );
date.getPreviousNDays(m);
System.out.print(date.showDate());
} else if (choice == 3 ) { // 天数差
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
int anotherYear = Integer.parseInt(input.next());
int anotherMonth = Integer.parseInt(input.next());
int anotherDay = Integer.parseInt(input.next());
DateUtil anotherDate = new DateUtil(anotherYear, anotherMonth, anotherDay);
if (!date.checkInputValidity() || !anotherDate.checkInputValidity()) { // 日期错误
System.out.println( "Wrong Format" );
System.exit( 0 );
}
System.out.println( "The days between " + date.showDate() +
" and " + anotherDate.showDate() + " are:"
+ date.getDaysofDates(anotherDate));
} else { // 错误操作
System.out.println( "Wrong Format" );
}
}
}
4.ATM机类结构设计(一)(第六次题目集7-4)
根据题目背景,设计ATM机仿真系统,具体实现五个实体类,在这基础上进行扩充,理解类与类之间一对一和一对多的关系,实现对账户余额的查询,取款,存款等功能,对输入信息进行正确性检测给出相应的错误提示。
SourceMonitor分析:
在五个实体类的基础上进行了类的扩充,各项指标都还在理想范围内。
类图:
Account与Card和Bank相联系,通过所有的用户列表,查找卡号,进行操作;同时为了减少主函数的职责,引入了Controller作控制,Operate类进行对输入信息操作(DealData),Check检查输入的合法性,InitData进行数据的初始化,Input存入所有的输入信息再给DealData集中处理。
实现代码:
import java.util.ArrayList;
import java.util.Scanner; class ChinaUnionPay{
private ArrayList<Bank> banks; public ChinaUnionPay() {
} public ArrayList<Bank> getBanks() {
return banks;
} public void setBanks(ArrayList<Bank> banks) {
this.banks = banks;
}
}
class Bank {
private String bankName; // 银行名称
private ArrayList<String> ATMNumber; // 银行ATM机序号 public Bank() {
} public Bank(String bankName, ArrayList<String> ATMNumber) {
this.bankName = bankName;
this.ATMNumber = ATMNumber;
} public String getBankName() {
return bankName;
} public void setBankName(String bankName) {
this.bankName = bankName;
} public ArrayList<String> getATMNumber() {
return ATMNumber;
} public void setATMNumber(ArrayList<String> ATMNumber) {
this.ATMNumber = ATMNumber;
} }
class User { // 用户开账户 账户名下有银行卡
private String userName;
private ArrayList<Account> accounts; public User() {
} public User(String userName, ArrayList<Account> accounts) {
this.userName = userName;
this.accounts = accounts;
} public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} public ArrayList<Account> getAccounts() {
return accounts;
} public void setAccounts(ArrayList<Account> accounts) {
this.accounts = accounts;
}
}
class Account {
private String accountHolderName;
private String accountNumber;
private ArrayList<Card> cards;
private Bank bank;
private double balance;
public Account() {
} public Account(String accountHolderName, String accountNumber, ArrayList<Card> cards, Bank bank, double balance) {
this.accountHolderName = accountHolderName;
this.accountNumber = accountNumber;
this.cards = cards;
this.bank = bank;
this.balance = balance;
} public Account(String accountNumber, ArrayList<Card> cards, Bank bank) {
this.accountNumber = accountNumber;
this.cards = cards;
this.bank = bank;
} public ArrayList<Card> getCards() {
return cards;
} public void setCards(ArrayList<Card> cards) {
this.cards = cards;
} public Bank getBank() {
return bank;
} public void setBank(Bank bank) {
this.bank = bank;
} public double getBalance() {
return balance;
} public void setBalance(double balance) {
this.balance = balance;
} public String getAccountHolderName() {
return accountHolderName;
} public void setAccountHolderName(String accountHolderName) {
this.accountHolderName = accountHolderName;
}
}
class Card {
private String cardId;// 卡号
private String passWord;// 密码 public Card() {
} public Card(String cardId, String passWord) {
this.cardId = cardId;
this.passWord = passWord;
} public String getCardId() {
return cardId;
} public void setCardId(String cardId) {
this.cardId = cardId;
} public String getPassWord() {
return passWord;
} public void setPassWord(String passWord) {
this.passWord = passWord;
} }
class ATM {
private String ATMNumber;// ATM机编号 public ATM() {
} public ATM(String ATMNumber) {
this.ATMNumber = ATMNumber;
}
}
class Check {
/* 存取款错误检测 卡号 ATM机 密码 金额合法 跨行检测
* 余额查询错误检测 卡号是否存在
*/
private ArrayList<Account> accountList;
private String cardId;
private String password;
private String ATMNumber;
private double money; public Check(ArrayList<Account> accountList, String cardId, String password, String ATMNumber, double money) {
this.accountList = accountList;
this.cardId = cardId;
this.password = password;
this.ATMNumber = ATMNumber;
this.money = money;
}
public Check(ArrayList<Account> accountList, String cardId) { //单个余额检测
this.accountList = accountList;
this.cardId = cardId;
}
public boolean isActionable() { // 是否可以进行存取操作
int accountOfOperation = 0; // 进行操作的账户序号
int cardOfOperation = 0; // 进行操作的卡在列表中的序号
int flag = 0;
for(int i = 0; i < accountList.size(); i++) { // 卡号存在
for(int j = 0; j < accountList.get(i).getCards().size(); j++) {
if (accountList.get(i).getCards().get(j).getCardId().equals(cardId)) {
flag = 1;
accountOfOperation = i;
cardOfOperation = j;
break;
}
}
if (flag == 1) break;
}
if(flag == 1) { // 输入密码正确检测
if(password.equals(accountList.get(accountOfOperation).getCards().get(cardOfOperation).getPassWord())){
flag=2;
} else {
System.out.println("Sorry,your password is wrong."); // 银行卡密码错误
return false;
}
} else{
System.out.println("Sorry,this card does not exist.");//卡号不存在
return false;
}
if(flag == 2) {
ArrayList<String> ATMList = new ArrayList<>();
ATMList.add("01");
ATMList.add("02");
ATMList.add("03");
ATMList.add("04");
ATMList.add("05");
ATMList.add("06");
ATMList.add("07");
ATMList.add("08");
if (ATMList.contains(ATMNumber)) { // ATM机编号正确
flag = 3;
}
}
if(flag == 3){ // 取款金额正确
if(money <= accountList.get(accountOfOperation).getBalance()) {
flag=4;
} else { // 取款金额大于账户余额
System.out.println("Sorry,your account balance is insufficient.");
return false;
}
} else { // 上一次的检测为错误
System.out.println("Sorry,the ATM's id is wrong.");
return false;
}
if(flag == 4) {
if (accountList.get(accountOfOperation).getBank().getATMNumber().contains(ATMNumber)) { // ATM没跨行
flag = 5;
}
}
if(flag!=5) { // 跨行操作
System.out.println("Sorry,cross-bank withdrawal is not supported.");
return false;
} else {
return true;
} }
public boolean isCardExist() {
for(int i = 0; i < accountList.size(); i++) {
for(int j = 0; j < accountList.get(i).getCards().size(); j++) {
if (accountList.get(i).getCards().get(j).getCardId().equals(cardId)) {
return true;
}
}
}
return false;
}
}
class Operate {
private ArrayList<Account> accountList;
private String cardId;
private String ATMNumber;
private double money; public Operate(ArrayList<Account> accountList, String cardId, String ATMNumber, double money) {
this.accountList = accountList;
this.cardId = cardId;
this.ATMNumber = ATMNumber;
this.money = money;
} public void operate() {
int accountOfOperation = 0; // 进行操作的账户序号
int cardOfOperation = 0; // 进行操作的卡在列表中的序号
for(int i = 0; i < accountList.size(); i++) { // 卡号存在
for(int j = 0; j < accountList.get(i).getCards().size(); j++) {
if (accountList.get(i).getCards().get(j).getCardId().equals(cardId)) {
accountOfOperation = i;
cardOfOperation = j;
break;
}
}
}
accountList.get(accountOfOperation).setBalance(accountList.get(accountOfOperation).getBalance()-money);
}
public void showOperatedMessage() {
int accountOfOperation = 0; // 进行操作的账户序号
int cardOfOperation = 0; // 进行操作的卡在列表中的序号
for(int i = 0; i < accountList.size(); i++) { // 卡号存在
for(int j = 0; j < accountList.get(i).getCards().size(); j++) {
if (accountList.get(i).getCards().get(j).getCardId().equals(cardId)) {
accountOfOperation = i;
cardOfOperation = j;
break;
}
}
}
if(money >= 0) { // 取款操作
System.out.println(accountList.get(accountOfOperation).getAccountHolderName() +
"在" + accountList.get(accountOfOperation).getBank().getBankName() + "的" +
ATMNumber + String.format("号ATM机上取款¥%.2f", money));
}
else{
money=-money;
System.out.println(accountList.get(accountOfOperation).getAccountHolderName() +
"在" + accountList.get(accountOfOperation).getBank().getBankName() + "的" +
ATMNumber + String.format("号ATM机上存款¥%.2f", money));
}
System.out.println(String.format("当前余额为¥%.2f", accountList.get(accountOfOperation).getBalance()));
}
}
//存取款的操作展示
class ShowBalance {
private ArrayList<Account> accountList;
private String cardId; public ShowBalance(ArrayList<Account> accountList, String cardId) {
this.accountList = accountList;
this.cardId = cardId;
}
public void showBalance() {
for(int i = 0; i < accountList.size(); i++ ) {
for(int j = 0; j < accountList.get(i).getCards().size(); j++) {
if(accountList.get(i).getCards().get(j).getCardId().equals(cardId)) {
System.out.println("¥" + String.format("%.2f", accountList.get(i).getBalance()));
break;
}
}
}
}
}
class InitData {
public static ArrayList<Account> init(){
ArrayList<String> ATMNumbers1 = new ArrayList<>();
ATMNumbers1.add("01");
ATMNumbers1.add("02");
ATMNumbers1.add("03");
ATMNumbers1.add("04");
Bank bank1 = new Bank("中国建设银行",ATMNumbers1);
ArrayList<Card> cards1 = new ArrayList<Card>(); // 用户拥有的卡
Card card1 = new Card("6217000010041315709","88888888");
Card card2 = new Card("6217000010041315715","88888888");
cards1.add(card1);
cards1.add(card2);
ArrayList<Card> cards2 = new ArrayList<>(); // 用户拥有的卡
Card card3 = new Card("6217000010041315718","88888888");
cards2.add(card3);
Account account1 = new Account("杨过","3217000010041315709",cards1, bank1,10000.00);
Account account2 = new Account("杨过","3217000010041315715",cards2, bank1,10000.00);
ArrayList<Account> accountsOfUser1 = new ArrayList<>();
accountsOfUser1.add(account1);
accountsOfUser1.add(account2);
User user1 = new User("杨过", accountsOfUser1); // 杨过拥有两个账户
ArrayList<Card> cards3 = new ArrayList<Card>(); // 用户拥有的卡
Card card4 = new Card("6217000010051320007", "8888888");
cards3.add(card4);
ArrayList<Account> accountsOfUser2 = new ArrayList<>();
Account account3 = new Account("郭靖","3217000010051320007",cards3, bank1,10000.00); // 郭靖拥有一个账户
accountsOfUser2.add(account3); ArrayList<String> ATMNumbers2 = new ArrayList<>();
ATMNumbers2.add("05");
ATMNumbers2.add("06");
Bank bank2 = new Bank("中国工商银行",ATMNumbers2);
Card card5 = new Card("6222081502001312389","88888888");
Card card6 = new Card("6222081502001312390","88888888");
Card card7 = new Card("6222081502001312399","88888888");
Card card8 = new Card("6222081502001312400","88888888");
ArrayList<Card> cards4 = new ArrayList<Card>(); // 用户拥有的卡
cards4.add(card5);
ArrayList<Card> cards5 = new ArrayList<Card>();
cards5.add(card6);
ArrayList<Card> cards6 = new ArrayList<Card>();
cards6.add(card7);
cards6.add(card8);
Account account4 = new Account("张无忌", "3222081502001312389", cards4, bank2,10000);
Account account5 = new Account("张无忌", "3222081502001312390", cards5, bank2, 10000);
Account account6 = new Account("张无忌", "3222081502001312399", cards6, bank2, 10000); // 张无忌有三个账户
ArrayList<Account> accountOfUsers3 = new ArrayList<>();
accountOfUsers3.add(account4);
accountOfUsers3.add(account5);
accountOfUsers3.add(account6);
Card card9 = new Card("6222081502051320785","88888888");
Card card10 = new Card("6222081502051320786","88888888"); ArrayList<Card> cards7 = new ArrayList<Card>();
cards7.add(card9);
ArrayList<Card> cards8 = new ArrayList<Card>();
cards8.add(card10);
Account account7 = new Account("韦小宝","3222081502051320785", cards7, bank2,10000);
Account account8 = new Account("韦小宝","3222081502051320786", cards8, bank2,10000); /*所有银行账户的总合*/
ArrayList<Account> accounts = new ArrayList<>();
accounts.add(account1);
accounts.add(account2);
accounts.add(account3);
accounts.add(account4);
accounts.add(account5);
accounts.add(account6);
accounts.add(account7);
accounts.add(account8);
return accounts;
}
}
class DealData {
private StringBuilder acceptData; public DealData(StringBuilder acceptData) {
this.acceptData = acceptData;
}
public void progressData(ArrayList<Account> accounts) {
Check check;
String[] data = this.acceptData.toString().split("\n");
for (int i = 0; i < data.length; i++ ){
String[] datum = data[i].split("\\s+"); // 匹配多个空格 将数据分割开
if (datum.length > 1) { // 存取款
check = new Check(accounts, datum[0], datum[1], datum[2], Double.parseDouble(datum[3]));
boolean flag = check.isActionable();
if (flag == true) {
Operate op = new Operate(accounts, datum[0], datum[2], Double.parseDouble(datum[3]));
op.operate();
op.showOperatedMessage(); // 展示信息
}
} else { // 余额查询
check = new Check(accounts, datum[0]);
if(check.isCardExist()) {
ShowBalance show = new ShowBalance(accounts, datum[0]);
show.showBalance();
}
}
}
}
}
class Input {
public StringBuilder getData() {
Scanner input = new Scanner(System.in);
StringBuilder operationalData = new StringBuilder();
String data1 = input.nextLine();
while(!data1.equals("#")) {
operationalData.append(data1 + "\n");
data1 = input.nextLine();
}
return operationalData;
}
}
class Controller {
private Input inn = new Input();
private InitData init = new InitData();
private DealData dealData;
public void control() {
ArrayList<Account> accounts = init.init();
StringBuilder operationalData = inn.getData();
dealData = new DealData(operationalData);
dealData.progressData(accounts);
}
}
public class Main {
public static void main(String[] args) {
Controller controller = new Controller();
controller.control();
}
}
5.ATM机类结构设计(二)
在ATM机类结构设计(一)的基础上,加入了账号的种类(贷记和借记),贷记账户可透支取款(但账户的透支余额不可超过50000),可跨行取款但需要收取相应的手续费,我在跨行透支的理解上有偏差,即使跨行了要收取相应的手续费,但是透支的计算与跨行无关,仍是原来的余额,而不是减去跨行后的余额,还存在一个测试点的错误没找出来。
SourceMonitor分析:
大体与上一次没太大的区别,把Account扩展为抽象类,方便继承。
类图:
Account为抽象类,下面有贷记和借记两种账户,方便扩展。
实现代码:
import java.util.ArrayList;
import java.util.Scanner; class ChinaUnionPay{
private ArrayList<Bank> banks; public ChinaUnionPay() {
} public ArrayList<Bank> getBanks() {
return banks;
} public void setBanks(ArrayList<Bank> banks) {
this.banks = banks;
}
}
class Bank {
private String bankName; // 银行名称
private ArrayList<String> ATMNumber; // 银行ATM机序号 public Bank() {
} public Bank(String bankName, ArrayList<String> ATMNumber) {
this.bankName = bankName;
this.ATMNumber = ATMNumber;
} public String getBankName() {
return bankName;
} public void setBankName(String bankName) {
this.bankName = bankName;
} public ArrayList<String> getATMNumber() {
return ATMNumber;
} public void setATMNumber(ArrayList<String> ATMNumber) {
this.ATMNumber = ATMNumber;
} }
class User { // 用户开账户 账户名下有银行卡
private String userName;
private ArrayList<Account> accounts; public User() {
} public User(String userName, ArrayList<Account> accounts) {
this.userName = userName;
this.accounts = accounts;
} public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} public ArrayList<Account> getAccounts() {
return accounts;
} public void setAccounts(ArrayList<Account> accounts) {
this.accounts = accounts;
}
}
abstract class Account {
private String accountHolderName;
private String accountNumber;
private ArrayList<Card> cards;
private Bank bank;
private String accountType; // 账号种类
private double balance; // 余额
private double DraftBalance; // 可透支的余额
public Account() {
} public Account(String accountHolderName, String accountNumber, ArrayList<Card> cards, Bank bank, String accountType, double balance) {
this.accountHolderName = accountHolderName;
this.accountNumber = accountNumber;
this.cards = cards;
this.bank = bank;
this.accountType = accountType;
this.balance = balance;
} public Account(String accountHolderName, String accountNumber, ArrayList<Card> cards, Bank bank, String accountType, double balance, double draftBalance) {
this.accountHolderName = accountHolderName;
this.accountNumber = accountNumber;
this.cards = cards;
this.bank = bank;
this.accountType = accountType;
this.balance = balance;
DraftBalance = draftBalance;
} public String getAccountType() {
return accountType;
} public void setAccountType(String accountType) {
this.accountType = accountType;
} public ArrayList<Card> getCards() {
return cards;
} public void setCards(ArrayList<Card> cards) {
this.cards = cards;
} public Bank getBank() {
return bank;
} public void setBank(Bank bank) {
this.bank = bank;
} public double getBalance() {
return balance;
} public void setBalance(double balance) {
this.balance = balance;
} public String getAccountHolderName() {
return accountHolderName;
} public void setAccountHolderName(String accountHolderName) {
this.accountHolderName = accountHolderName;
} public double getDraftBalance() {
return DraftBalance;
} public void setDraftBalance(double draftBalance) {
DraftBalance = draftBalance;
}
}
class Account1 extends Account {
public Account1(String accountHolderName, String accountNumber, ArrayList<Card> cards, Bank bank, String accountType, double balance) {
super(accountHolderName, accountNumber, cards, bank, accountType, balance);
}
}
class Account2 extends Account {
public Account2(String accountHolderName, String accountNumber, ArrayList<Card> cards, Bank bank, String accountType, double balance, double draftBalance) {
super(accountHolderName, accountNumber, cards, bank, accountType, balance, draftBalance);
}
}
class Card {
private String cardId;// 卡号
private String passWord;// 密码 public Card() {
} public Card(String cardId, String passWord) {
this.cardId = cardId;
this.passWord = passWord;
} public String getCardId() {
return cardId;
} public void setCardId(String cardId) {
this.cardId = cardId;
} public String getPassWord() {
return passWord;
} public void setPassWord(String passWord) {
this.passWord = passWord;
} }
class ATM {
private String ATMNumber;// ATM机编号
public ATM() {
} public ATM(String ATMNumber) {
this.ATMNumber = ATMNumber;
}
}
class Check {
/* 存取款错误检测 卡号 ATM机 密码 金额合法 跨行检测
* 余额查询错误检测 卡号是否存在
*/
private ArrayList<Account> accountList;
private String cardId;
private String password;
private String ATMNumber;
private double money; public Check(ArrayList<Account> accountList, String cardId, String password, String ATMNumber, double money) {
this.accountList = accountList;
this.cardId = cardId;
this.password = password;
this.ATMNumber = ATMNumber;
this.money = money;
}
public Check(ArrayList<Account> accountList, String cardId) { //单个余额检测
this.accountList = accountList;
this.cardId = cardId;
}
public boolean isActionable() { // 是否可以进行存取操作
int accountOfOperation = 0; // 进行操作的账户序号
int cardOfOperation = 0; // 进行操作的卡在列表中的序号
int flag = 0;
for(int i = 0; i < accountList.size(); i++) { // 卡号存在
for(int j = 0; j < accountList.get(i).getCards().size(); j++) {
if (accountList.get(i).getCards().get(j).getCardId().equals(cardId)) {
flag = 1;
accountOfOperation = i;
cardOfOperation = j;
break;
}
}
if (flag == 1) break;
}
if(flag == 1) { // 输入密码正确检测
if(password.equals(accountList.get(accountOfOperation).getCards().get(cardOfOperation).getPassWord())){
flag=2;
} else {
System.out.println("Sorry,your password is wrong."); // 银行卡密码错误
System.exit(0);
return false;
}
} else{
System.out.println("Sorry,this card does not exist.");//卡号不存在
System.exit(0);
return false;
}
if(flag == 2) {
ArrayList<String> ATMList = new ArrayList<>();
ATMList.add("01");
ATMList.add("02");
ATMList.add("03");
ATMList.add("04");
ATMList.add("05");
ATMList.add("06");
ATMList.add("07");
ATMList.add("08");
ATMList.add("09");
ATMList.add("10");
ATMList.add("11");
if (ATMList.contains(ATMNumber)) { // ATM机编号正确
flag = 3;
}
}
if (flag == 3) {
return true;
} else { // 上一次的检测为错误
System.out.println("Sorry,the ATM's id is wrong.");
System.exit(0);
return false;
}
}
public boolean isCrossBank() { //是否跨行
int accountOfOperation = 0;
for(int i = 0; i < accountList.size(); i++) { // 卡号存在
for (int j = 0; j < accountList.get(i).getCards().size(); j++) {
if (accountList.get(i).getCards().get(j).getCardId().equals(cardId)) {
accountOfOperation = i;
break;
}
}
}
if(accountList.get(accountOfOperation).getBank().getATMNumber().contains(ATMNumber)) {
return false;
}
return true;
}
public boolean isOverDraft() { // 贷记账户的取款是否透支
int accountOfOperation = 0;
for(int i = 0; i < accountList.size(); i++) { // 卡号存在
for (int j = 0; j < accountList.get(i).getCards().size(); j++) {
if (accountList.get(i).getCards().get(j).getCardId().equals(cardId)) {
accountOfOperation = i;
break;
}
}
}
if(accountList.get(accountOfOperation).getAccountType().equals("贷记") &&
accountList.get(accountOfOperation).getBalance() - money < 0) {
return true;
}
return false;
}
public boolean isCardExist() {
for(int i = 0; i < accountList.size(); i++) {
for(int j = 0; j < accountList.get(i).getCards().size(); j++) {
if (accountList.get(i).getCards().get(j).getCardId().equals(cardId)) {
return true;
}
}
}
return false;
}
}
class Operate {
private ArrayList<Account> accountList;
private String cardId;
private String ATMNumber;
private double money;
private String operateBank; // 取款存款的实际银行 public Operate(ArrayList<Account> accountList, String cardId, String ATMNumber, double money) {
this.accountList = accountList;
this.cardId = cardId;
this.ATMNumber = ATMNumber;
this.money = money;
} public void operate(boolean isCrossBank, boolean isOverDraft) {
int accountOfOperation = 0; // 进行操作的账户序号
double crossBankMoney = 0; // 跨行手续费
double overDraftMoney = 0; // 透支手续费
for(int i = 0; i < accountList.size(); i++) { // 卡号存在
for(int j = 0; j < accountList.get(i).getCards().size(); j++) {
if (accountList.get(i).getCards().get(j).getCardId().equals(cardId)) {
accountOfOperation = i;
break;
}
}
}
if (money > 0) { // 取款操作
if (isCrossBank) { // 跨行取款手续费
int atmNumber = Integer.parseInt(ATMNumber);
if(atmNumber >= 1 && atmNumber <= 4) {
crossBankMoney = money * 0.02;
operateBank = "中国建设银行";
}
else if (atmNumber > 4 && atmNumber <= 6) {
crossBankMoney = money * 0.03;
operateBank = "中国工商银行";
} else {
crossBankMoney = money * 0.04;
operateBank = "中国农业银行";
}
}
//accountList.get(accountOfOperation).setBalance(accountList.get(accountOfOperation).getBalance() - crossBankMoney);
if (isOverDraft) {
if (accountList.get(accountOfOperation).getBalance() > 0) {
if (accountList.get(accountOfOperation).getBalance() - money - // 超出透支的最大金额
Math.abs(accountList.get(accountOfOperation).getBalance()-money) *0.05 < -50000) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
overDraftMoney = (money - accountList.get(accountOfOperation).getBalance()) * 0.05;
} else {
if (accountList.get(accountOfOperation).getBalance() - money - Math.abs(money)*0.05 < -50000) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
overDraftMoney = money * 0.05;
}
}
}
if(isCrossBank) {
if((accountList.get(accountOfOperation).getAccountType().equals("借记") &&
money + crossBankMoney > accountList.get(accountOfOperation).getBalance())) {
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
}
accountList.get(accountOfOperation).setBalance(accountList.get(accountOfOperation).getBalance()-crossBankMoney);
}
accountList.get(accountOfOperation).setBalance(accountList.get(accountOfOperation).getBalance()
- money - overDraftMoney);
showOperatedMessage(isCrossBank);
}
public void showOperatedMessage(boolean isCrossBank) {
int accountOfOperation = 0; // 进行操作的账户序号
for(int i = 0; i < accountList.size(); i++) { // 卡号存在
for(int j = 0; j < accountList.get(i).getCards().size(); j++) {
if (accountList.get(i).getCards().get(j).getCardId().equals(cardId)) {
accountOfOperation = i;
break;
}
}
}
if (!isCrossBank) {
operateBank = accountList.get(accountOfOperation).getBank().getBankName();
}
if(money >= 0) { // 取款操作
System.out.println("业务:取款 "+accountList.get(accountOfOperation).getAccountHolderName() +
"在" + operateBank + "的" + ATMNumber + String.format("号ATM机上取款¥%.2f", money));
} else{
money=-money;
System.out.println("业务:存款 "+accountList.get(accountOfOperation).getAccountHolderName() +
"在" + accountList.get(accountOfOperation).getBank().getBankName() + "的" +
ATMNumber + String.format("号ATM机上存款¥%.2f", money));
}
System.out.println(String.format("当前余额为¥%.2f", accountList.get(accountOfOperation).getBalance()));
}
}
//余额查询操作展示
class ShowBalance {
private ArrayList<Account> accountList;
private String cardId; public ShowBalance(ArrayList<Account> accountList, String cardId) {
this.accountList = accountList;
this.cardId = cardId;
} public void showBalance() {
for(int i = 0; i < accountList.size(); i++ ) {
for(int j = 0; j < accountList.get(i).getCards().size(); j++) {
if(accountList.get(i).getCards().get(j).getCardId().equals(cardId)) {
System.out.println("业务:查询余额 "+"¥" + String.format("%.2f", accountList.get(i).getBalance()));
break;
}
}
}
}
}
class InitData {
public ArrayList<Account> init(){
ArrayList<String> ATMNumbers1 = new ArrayList<>();
ATMNumbers1.add("01");
ATMNumbers1.add("02");
ATMNumbers1.add("03");
ATMNumbers1.add("04");
Bank bank1 = new Bank("中国建设银行",ATMNumbers1);
ArrayList<Card> cards1 = new ArrayList<Card>(); // 用户拥有的卡
Card card1 = new Card("6217000010041315709","88888888");
Card card2 = new Card("6217000010041315715","88888888");
cards1.add(card1);
cards1.add(card2);
ArrayList<Card> cards2 = new ArrayList<>(); // 用户拥有的卡
Card card3 = new Card("6217000010041315718","88888888");
cards2.add(card3);
Account account1 = new Account1("杨过","3217000010041315709",cards1, bank1,"借记",10000.00);
Account account2 = new Account1("杨过","3217000010041315715",cards2, bank1,"借记",10000.00);
ArrayList<Account> accountsOfUser1 = new ArrayList<>();
accountsOfUser1.add(account1);
accountsOfUser1.add(account2);
User user1 = new User("杨过", accountsOfUser1); // 杨过拥有两个账户
ArrayList<Card> cards3 = new ArrayList<Card>(); // 用户拥有的卡
Card card4 = new Card("6217000010051320007", "8888888");
cards3.add(card4);
ArrayList<Account> accountsOfUser2 = new ArrayList<>();
Account account3 = new Account1("郭靖","3217000010051320007",cards3, bank1,"借记",10000.00); // 郭靖拥有一个账户
accountsOfUser2.add(account3); ArrayList<String> ATMNumbers2 = new ArrayList<>();
ATMNumbers2.add("05");
ATMNumbers2.add("06");
Bank bank2 = new Bank("中国工商银行",ATMNumbers2);
ArrayList<String> ATMNumbers3 = new ArrayList<>();
ATMNumbers3.add("07");
ATMNumbers3.add("08");
ATMNumbers3.add("09");
ATMNumbers3.add("10");
ATMNumbers3.add("11");
Bank bank3 = new Bank("中国农业银行",ATMNumbers3);
Card card5 = new Card("6222081502001312389","88888888");
Card card6 = new Card("6222081502001312390","88888888");
Card card7 = new Card("6222081502001312399","88888888");
Card card8 = new Card("6222081502001312400","88888888");
ArrayList<Card> cards4 = new ArrayList<Card>(); // 用户拥有的卡
cards4.add(card5);
ArrayList<Card> cards5 = new ArrayList<Card>();
cards5.add(card6);
ArrayList<Card> cards6 = new ArrayList<Card>();
cards6.add(card7);
cards6.add(card8);
Account account4 = new Account1("张无忌", "3222081502001312389", cards4, bank2,"借记",10000);
Account account5 = new Account1("张无忌", "3222081502001312390", cards5, bank2,"借记", 10000);
Account account6 = new Account1("张无忌", "3222081502001312399", cards6, bank2, "借记",10000); // 张无忌有三个账户
ArrayList<Account> accountOfUsers3 = new ArrayList<>();
accountOfUsers3.add(account4);
accountOfUsers3.add(account5);
accountOfUsers3.add(account6);
Card card9 = new Card("6222081502051320785","88888888");
Card card10 = new Card("6222081502051320786","88888888"); ArrayList<Card> cards7 = new ArrayList<Card>();
cards7.add(card9);
ArrayList<Card> cards8 = new ArrayList<Card>();
cards8.add(card10);
Account account7 = new Account1("韦小宝","3222081502051320785", cards7, bank2,"借记",10000);
Account account8 = new Account1("韦小宝","3222081502051320786", cards8, bank2,"借记",10000); Card card11 = new Card("6640000010045442002","88888888");
Card card12 = new Card("6640000010045442003","88888888");
ArrayList<Card> cards9 = new ArrayList<Card>();
cards9.add(card11);
cards9.add(card12);
Account account9 = new Account2("张三丰","3640000010045442002", cards9, bank1,"贷记",10000,50000); Card card13 = new Card("6640000010045441009","88888888");
ArrayList<Card> cards10 = new ArrayList<Card>();
cards10.add(card13);
Account account10 = new Account2("令狐冲","3640000010045441009", cards10, bank2,"贷记",10000,50000); Card card14 = new Card("6630000010033431001","88888888");
ArrayList<Card> cards11 = new ArrayList<Card>();
cards11.add(card14);
Account account11 = new Account2("乔峰","3630000010033431001", cards11, bank3,"贷记",10000,50000); Card card15 = new Card("6630000010033431008","88888888");
ArrayList<Card> cards12 = new ArrayList<Card>();
cards11.add(card15);
Account account12 = new Account2("洪七公","3630000010033431008", cards12, bank3,"贷记",10000,50000); /*所有银行账户的总合*/
ArrayList<Account> accounts = new ArrayList<>();
accounts.add(account1);
accounts.add(account2);
accounts.add(account3);
accounts.add(account4);
accounts.add(account5);
accounts.add(account6);
accounts.add(account7);
accounts.add(account8);
accounts.add(account9);
accounts.add(account10);
accounts.add(account11);
accounts.add(account12);
return accounts;
}
}
class DealData {
private StringBuilder acceptData; public DealData(StringBuilder acceptData) {
this.acceptData = acceptData;
}
public void progressData(ArrayList<Account> accounts) {
Check check;
String[] data = this.acceptData.toString().split("\n");
for (int i = 0; i < data.length; i++ ){
String[] datum = data[i].split("\\s+"); // 匹配多个空格 将数据分割开
if (datum.length > 1) { // 存取款
check = new Check(accounts, datum[0], datum[1], datum[2], Double.parseDouble(datum[3]));
boolean flag = check.isActionable();
if (flag == true) {
Operate op = new Operate(accounts, datum[0], datum[2], Double.parseDouble(datum[3]));
op.operate(check.isCrossBank(), check.isOverDraft());
}
} else { // 余额查询
check = new Check(accounts, datum[0]);
if(check.isCardExist()) {
ShowBalance show = new ShowBalance(accounts, datum[0]);
show.showBalance();
}
}
}
} }
class Input {
public StringBuilder getData() {
Scanner input = new Scanner(System.in);
StringBuilder operationalData = new StringBuilder();
String data1 = input.nextLine();
while(!data1.equals("#")) {
operationalData.append(data1 + "\n");
data1 = input.nextLine();
}
return operationalData;
}
}
class Controller {
private Input inn = new Input();
private InitData init = new InitData();
private DealData dealData;
public void control() {
ArrayList<Account> accounts = init.init();
StringBuilder operationalData = inn.getData();
dealData = new DealData(operationalData);
dealData.progressData(accounts);
} }
public class Main {
public static void main(String[] args) {
Controller controller = new Controller();
controller.control();
}
}
踩坑心得:
1.菜单的设计不合理,输入信息和处理信息及最后的输出信息都写在主函数里,太凌乱了,到最后修改都不太好改,只把单桌菜做好了,多桌菜的输出不知道哪里有问题。写题之前还得好好构思!
2.第四次题目集7-6中,通过给出的样例,默认输出的数据都是两位数(直接用.2f)输出了,题目的样例对了,但卡死了一个点,很低级的逻辑错误。
3.水文信息处理中,如果直接输入exit,程序会非零返回,没有对数据进行判断就开始分割,导致字符串转换为double类型报错,没有考虑到特殊情况。
4.在图形的继承上,子类的生成需要层层调用,为了体现这种关系,构造函数调用时要输出Constructing+类名,我调用了带参构造函数忘记加上这句话,有一个测试点出错。
5.在ATM机(二)中卡死在一个测试点上,改到最后还是没搞清为什么,和同学交流也没有很好的解决方法。
改进建议:
1.菜单的构思,把输入信息先存起来写一个输入类,在写一个处理信息类,最后再输出,减少主函数的职责,更有条理性;
2.ATM机设计,Check类的方法太多,可以把输入检查按照题目要求分开来,一个类做一件事,满足单一职责原则;
3.在ATM机2中,跨行,透支等两种取款方式我放在一个操作类里,这样方法用到了较多的if-else 来进行判断,可以把贷记的取款写成两个类,一个贷记跨行不透支,另一个跨行透支,不跨行也不透支的取款仍为原来的方法。
总结:
1.这三次题目集,不仅对集合框架和正则表达式等java的常用工具进行了练习,同时穿插着面向对象编程的封装性,继承,多态,对我们这一阶段的知识有巩固;
2.从给类图到不给类图,让我们根据需求去自己设计类,这个过渡是有点困难的,在设计的时候,我会有种怕麻烦的心理,不喜欢太多的类,但随着题目的升级,我要转变自己的思想,不要怕类多,设计要满足单一职责,同时合理利用MVC减少主函数的职责;
3.到这个阶段,我们对面向对象的编程思想已经有了学习,做题时不要再想着面向过程去偷懒,练习时多用用平时学到的东西,把自己的基础打扎实。
OOP4-6题目集总结的更多相关文章
- Java高级程序员(5年左右)面试的题目集
Java高级程序员(5年左右)面试的题目集 https://blog.csdn.net/fangqun663775/article/details/73614850?utm_source=blogxg ...
- 浙大版《C语言程序设计(第3版)》题目集 --总结
浙大版<C语言程序设计(第3版)>题目集 此篇博客意义为总结pta上浙大版<C语言程序设计(第3版)>题目集所做题目的错误点,心得体会. 1.练习2-10 计算分段函数[1] ...
- KMP,Trie,AC自动机题目集
字符串算法并不多,KMP,trie,AC自动机就是其中几个最经典的.字符串的题目灵活多变也有许多套路,需要多做题才能体会.这里收集了许多前辈的题目做个集合,方便自己回忆. KMP题目:https:// ...
- PTA数据结构与算法题目集(中文) 7-43字符串关键字的散列映射 (25 分)
PTA数据结构与算法题目集(中文) 7-43字符串关键字的散列映射 (25 分) 7-43 字符串关键字的散列映射 (25 分) 给定一系列由大写英文字母组成的字符串关键字和素数P,用移位法定义 ...
- PTA数据结构与算法题目集(中文) 7-42整型关键字的散列映射 (25 分)
PTA数据结构与算法题目集(中文) 7-42整型关键字的散列映射 (25 分) 7-42 整型关键字的散列映射 (25 分) 给定一系列整型关键字和素数P,用除留余数法定义的散列函数将关键字映射 ...
- PTA数据结构与算法题目集(中文) 7-41PAT排名汇总 (25 分)
PTA数据结构与算法题目集(中文) 7-41PAT排名汇总 (25 分) 7-41 PAT排名汇总 (25 分) 计算机程序设计能力考试(Programming Ability Test,简称P ...
- PTA数据结构与算法题目集(中文) 7-40奥运排行榜 (25 分)
PTA数据结构与算法题目集(中文) 7-40奥运排行榜 (25 分) 7-40 奥运排行榜 (25 分) 每年奥运会各大媒体都会公布一个排行榜,但是细心的读者发现,不同国家的排行榜略有不同.比如 ...
- PTA数据结构与算法题目集(中文) 7-39魔法优惠券 (25 分)
PTA数据结构与算法题目集(中文) 7-39魔法优惠券 (25 分) 7-39 魔法优惠券 (25 分) 在火星上有个魔法商店,提供魔法优惠券.每个优惠劵上印有一个整数面值K,表示若你在购买某商 ...
- PTA数据结构与算法题目集(中文) 7-38寻找大富翁 (25 分)
PTA数据结构与算法题目集(中文) 7-38寻找大富翁 (25 分) 7-38 寻找大富翁 (25 分) 胡润研究院的调查显示,截至2017年底,中国个人资产超过1亿元的高净值人群达15万人.假 ...
- PTA数据结构与算法题目集(中文) 7-37 模拟EXCEL排序 (25 分)
PTA数据结构与算法题目集(中文) 7-37 模拟EXCEL排序 (25 分) 7-37 模拟EXCEL排序 (25 分) Excel可以对一组纪录按任意指定列排序.现请编写程序实现类似功能. ...
随机推荐
- 浅析Nordic nRF5 SDK例程架构
很多刚接触Nordic nRF5 SDK的初学者出于对新平台的不熟悉,会觉得这个SDK很难,本文讲浅析nRF5 SDK中例程的架构,让初学者能够快速上手SDK. 在开始之前,先推荐阅读观看下面这些文章 ...
- 手机号码归属地 API 实现个性化推荐的思路分析
前言 随着移动互联网和智能手机的普及,越来越多的人使用手机上网和购物,移动营销已成为企业获取用户和提升品牌知名度的重要手段.手机号码归属地 API 作为移动营销的关键工具,具有广阔的应用前景. 本文将 ...
- Redis为什么能抗住10万并发?揭秘性能优越的背后原因
1. Redis简介 Redis是一个开源的,基于内存的,高性能的键值型数据库.它支持多种数据结构,包含五种基本类型 String(字符串).Hash(哈希).List(列表).Set(集合).Zse ...
- 【vue3-element-admin】ESLint+Prettier+Stylelint+EditorConfig 约束和统一前端代码规范
前言 本文介绍 vue3-element-admin 如何通过ESLint 检测 JS/TS 代码.Prettier 格式化代码.Stylelint 检测 CSS/SCSS 代码和配置 EditorC ...
- 33-module
const { resolve } = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') module. ...
- List嵌套排序并取第一个对象
using Newtonsoft.Json;using 嵌套List排序; //示例listvar exampleString = "{\"code\":1,\" ...
- NC23054 华华开始学信息学
题目链接 题目 题目描述 因为上次在月月面前丢人了,所以华华决定开始学信息学.十分钟后,他就开始学树状数组了.这是一道树状数组的入门题: 给定一个长度为 \(N\) 的序列 \(A\) ,所有元素初值 ...
- dede网站flash中图片不能正常显示解决办法
专业微信开发 网站制作 就在西安格创网络 联系电话:18009249661 原因:因为服务器或虚拟主机用了CDN加速,导致图片是调用远程缓存,只能显示FLASH控件,但图片不能正常显示,常见于西 ...
- STL------sort三种比较算子定义
sort的三种比较算子的定义方式 例:一道细碎的细节模拟题: http://newoj.acmclub.cn/contests/1258/problem/3 1932: 2018蓝桥杯培训-STL应用 ...
- 域名配置动态代理后,为什么每次 ping 还是相同的 ip?
当你配置了域名的动态代理后,ping 命令所显示的 IP 地址不会随着代理服务器的变化而变化. 这是因为 ping 命令使用了 DNS 缓存,它会将域名解析结果缓存到本地,直到缓存过期或者手动清除缓存 ...