OOP4-6题目集总结
阅读原文时间:2023年08月09日阅读:2

  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 notExistDishName =     new ArrayList<>();
private ArrayList 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(&nbsp;&nbsp;&nbsp;  int orderNum, Dish dish,&nbsp;&nbsp;&nbsp;&nbsp;  int portion,&nbsp;&nbsp;&nbsp;&nbsp;  int num) {  
    this .orderNum = orderNum;  
    this .dish = dish;  
    this .portion = portion;  
    this .num = num;  
}  
public int getOrderNum() {  
    return orderNum;  
}

public void setOrderNum(&nbsp;&nbsp;&nbsp;  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(&nbsp;&nbsp;&nbsp;  int portion) {  
    this .portion = portion;  
}

public int getNum() {  
    return num;  
}

public void setNum(&nbsp;&nbsp;&nbsp;  int num) {  
    this .num = num;  
}  
public int getPrice() {&nbsp;&nbsp;&nbsp;&nbsp;  // 计算这条记录的价格  
    return dish.getPrice(portion) \* num;  
}  

}

class Order {
ArrayList 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 outPut =     new ArrayList();     // 最后要输出的信息
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(&nbsp;&nbsp;&nbsp;  int yearValue,&nbsp;&nbsp;&nbsp;&nbsp;  int monthValue,&nbsp;&nbsp;&nbsp;&nbsp;  int dayValue) {  
    this .value = dayValue;  
    this .month =&nbsp;&nbsp;&nbsp;&nbsp;  new Month(yearValue, monthValue);  
}

public int getValue() {  
    return value;  
}

public void setValue(&nbsp;&nbsp;&nbsp;  int value) {  
    this .value = value;  
}

public Month getMonth() {  
    return month;  
}

public void setMonth(Month month) {  
    this .month = month;  
}  
public void resetMin() {&nbsp;&nbsp;&nbsp;&nbsp;  //天数复位为1  
    this .value =&nbsp;&nbsp;&nbsp;&nbsp;  1 ;  
}  
public void resetMax() {&nbsp;&nbsp;&nbsp;&nbsp;  // 天数设为月最大  
    this .value = mon\_maxnum\[month.getValue()-&nbsp;&nbsp;&nbsp;  1 \];  
}  
public boolean validate() {&nbsp;&nbsp;&nbsp;&nbsp;  // 天数在合法范围,注意闰年  
    if (month.getYear().isLeapYear()) {  
        mon\_maxnum\[&nbsp;&nbsp;&nbsp;  1 \] =&nbsp;&nbsp;&nbsp;&nbsp;  29 ;  
    }&nbsp;&nbsp;&nbsp;&nbsp;  else {  
        mon\_maxnum\[&nbsp;&nbsp;&nbsp;  1 \] =&nbsp;&nbsp;&nbsp;&nbsp;  28 ;  
    }  
    if (value >=&nbsp;&nbsp;&nbsp;  1 && value <= mon\_maxnum\[month.getValue()-&nbsp;&nbsp;&nbsp;  1 \]) {  
        return true ;  
    }&nbsp;&nbsp;&nbsp;&nbsp;  else {  
        return false ;  
    }  
}  
public void dayIncrement() {&nbsp;&nbsp;&nbsp;&nbsp;  // 日期增1  
    value++;  
    if (month.getYear().isLeapYear()) {&nbsp;&nbsp;&nbsp;&nbsp;  // 判断闰年  
        mon\_maxnum\[&nbsp;&nbsp;&nbsp;  1 \]=&nbsp;&nbsp;&nbsp;  29 ;  
    }&nbsp;&nbsp;&nbsp;&nbsp;  else {  
        mon\_maxnum\[&nbsp;&nbsp;&nbsp;  1 \]=&nbsp;&nbsp;&nbsp;  28 ;  
    }  
    if (value > mon\_maxnum\[month.getValue()-&nbsp;&nbsp;&nbsp;  1 \]) {&nbsp;&nbsp;&nbsp;&nbsp;  //天数超过当月  
        resetMin();  
        month.monthIncrement();  
    }  
}  
public void dayReduction() {  
    value--;  
    if (month.getYear().isLeapYear()) {&nbsp;&nbsp;&nbsp;&nbsp;  // 判断闰年  
        mon\_maxnum\[&nbsp;&nbsp;&nbsp;  1 \] =&nbsp;&nbsp;&nbsp;&nbsp;  29 ;  
    }&nbsp;&nbsp;&nbsp;&nbsp;  else {  
        mon\_maxnum\[&nbsp;&nbsp;&nbsp;  1 \] =&nbsp;&nbsp;&nbsp;&nbsp;  28 ;  
    }  
    if (value <=&nbsp;&nbsp;&nbsp;&nbsp;  0 ) {  
        month.monthReduction();  
        resetMax();  
    }  
}  

}

class Month {
private int value;
private Year year;

public Month() {  
}  
public Month(&nbsp;&nbsp;&nbsp;  int yearValue,&nbsp;&nbsp;&nbsp;&nbsp;  int monthValue) {  
    this .value = monthValue;  
    this .year =&nbsp;&nbsp;&nbsp;&nbsp;  new Year(yearValue);  
}

public int getValue() {  
    return value;  
}

public void setValue(&nbsp;&nbsp;&nbsp;  int value) {  
    this .value = value;  
}

public Year getYear() {  
    return year;  
}

public void setYear(Year year) {  
    this .year = year;  
}  
public void resetMin() {&nbsp;&nbsp;&nbsp;&nbsp;  // 月份复位为1  
    this .value =&nbsp;&nbsp;&nbsp;&nbsp;  1 ;  
}  
public void resetMax() {&nbsp;&nbsp;&nbsp;&nbsp;  // 月份设置为12  
    this .value =&nbsp;&nbsp;&nbsp;&nbsp;  12 ;  
}  
public boolean validate() {  
    if (&nbsp;&nbsp;&nbsp;  this .value >=&nbsp;&nbsp;&nbsp;  1 &&&nbsp;&nbsp;&nbsp;&nbsp;  this .value <=&nbsp;&nbsp;&nbsp;&nbsp;  12 ) {  
        return true ;  
    }&nbsp;&nbsp;&nbsp;&nbsp;  else {  
        return false ;  
    }  
}  
public void monthIncrement() {  
    this .value++;  
    if (value >&nbsp;&nbsp;&nbsp;&nbsp;  12 ) {&nbsp;&nbsp;&nbsp;&nbsp;  // 下一年  
        resetMin();  
        year.yearIncrement();  
    }  
}  
public void monthReduction() {  
    this .value--;  
    if (value <=&nbsp;&nbsp;&nbsp;&nbsp;  0 ) {&nbsp;&nbsp;&nbsp;&nbsp;  // 上一年  
        resetMax();  
        year.yearReduction();  
    }  
}  

}

class Year {
private int value;

public Year() {  
}

public Year(&nbsp;&nbsp;&nbsp;  int value) {  
    this .value = value;  
}

public int getValue() {  
    return value;  
}

public void setValue(&nbsp;&nbsp;&nbsp;  int value) {  
    this .value = value;  
}

public boolean isLeapYear() {  
    if ((&nbsp;&nbsp;&nbsp;  this .value %&nbsp;&nbsp;&nbsp;&nbsp;  4 ==&nbsp;&nbsp;&nbsp;&nbsp;  0 &&&nbsp;&nbsp;&nbsp;&nbsp;  this .value %&nbsp;&nbsp;&nbsp;&nbsp;  100 !=&nbsp;&nbsp;&nbsp;&nbsp;  0 ) ||&nbsp;&nbsp;&nbsp;&nbsp;  this .value %&nbsp;&nbsp;&nbsp;&nbsp;  400 ==&nbsp;&nbsp;&nbsp;&nbsp;  0 ) {  
        return true ;  
    }&nbsp;&nbsp;&nbsp;&nbsp;  else {  
        return false ;  
    }  
}

public boolean validate() {  
    if (&nbsp;&nbsp;&nbsp;  this .value >=&nbsp;&nbsp;&nbsp;&nbsp;  1900 &&&nbsp;&nbsp;&nbsp;&nbsp;  this .value <=&nbsp;&nbsp;&nbsp;&nbsp;  2050 ) {  
        return true ;  
    }&nbsp;&nbsp;&nbsp;&nbsp;  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 ;  
    }&nbsp;&nbsp;&nbsp;&nbsp;  else {  
        return false ;  
    }  
}  
public boolean compareDates(DateUtil date) {&nbsp;&nbsp;&nbsp;&nbsp;  // 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 ;  
    }&nbsp;&nbsp;&nbsp;&nbsp;  else {  
        return false ;  
    }  
}  
public boolean equalTwoDates(DateUtil date) {  
    if (date.getDay().getMonth().getYear().getValue() ==&nbsp;&nbsp;&nbsp;&nbsp;  this .getDay().getMonth().getYear().getValue() &&  
            date.getDay().getMonth().getValue() ==&nbsp;&nbsp;&nbsp;&nbsp;  this .getDay().getMonth().getValue() &&  
            date.getDay().getValue() ==&nbsp;&nbsp;&nbsp;&nbsp;  this .getDay().getValue()) {  
        return true ;  
    }&nbsp;&nbsp;&nbsp;&nbsp;  else {  
        return false ;  
    }

}  
public String showDate() {  
    return this .getDay().getMonth().getYear().getValue() +&nbsp;&nbsp;&nbsp;&nbsp;  "-" +&nbsp;&nbsp;&nbsp;&nbsp;  this .getDay().getMonth().getValue() +&nbsp;&nbsp;&nbsp;&nbsp;  "-" +  
            this .getDay().getValue();  
}  
public DateUtil getNextNDays(&nbsp;&nbsp;&nbsp;  int n) {  
    for (&nbsp;&nbsp;&nbsp;  int i =&nbsp;&nbsp;&nbsp;&nbsp;  0 ; i < n; i++) {  
        day.dayIncrement();  
    }  
    return this ;  
}  
public DateUtil getPreviousNDays(&nbsp;&nbsp;&nbsp;  int n) {  
    for (&nbsp;&nbsp;&nbsp;  int i =&nbsp;&nbsp;&nbsp;&nbsp;  0 ; i < n; i++) {  
        day.dayReduction();  
    }  
    return this ;  
}  
public int getDaysofDates(DateUtil date) {  
    int daysDifference =&nbsp;&nbsp;&nbsp;&nbsp;  0 ;  
    if (&nbsp;&nbsp;&nbsp;  this .equalTwoDates(date)) {  
        return 0 ;  
    }&nbsp;&nbsp;&nbsp;&nbsp;  else {  
        if (&nbsp;&nbsp;&nbsp;  this .compareDates(date)) {&nbsp;&nbsp;&nbsp;&nbsp;  //date大 求date前的day  
            while (!&nbsp;&nbsp;&nbsp;  this .equalTwoDates(date)) {  
                date.getPreviousNDays(&nbsp;&nbsp;&nbsp;  1 );  
                daysDifference++;  
            }  
        }&nbsp;&nbsp;&nbsp;&nbsp;  else {  
            while (!&nbsp;&nbsp;&nbsp;  this .equalTwoDates(date)) {  
                date.getNextNDays(&nbsp;&nbsp;&nbsp;  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(&nbsp;  int dayValue) {  
    this .value = dayValue;  
}

public int getValue() {  
    return value;  
}

public void setValue(&nbsp;  int value) {  
    this .value = value;  
}

public void dayIncrement() {  
    value++;  
}  
public void dayReduction() {  
    value--;  
}

}

class Month {
private int value;

public Month() {  
}  
public Month(&nbsp;  int monthValue) {  
    this .value = monthValue;  
}

public int getValue() {  
    return value;  
}

public void setValue(&nbsp;  int value) {  
    this .value = value;  
}  
public void setMin() {  
    this .value =&nbsp;&nbsp;  1 ;  
}  
public void setMax() {  
    this .value =&nbsp;&nbsp;  12 ;  
}

public boolean validate() {  
    if (&nbsp;  this .value >=&nbsp;&nbsp;  1 &&&nbsp;&nbsp;  this .value <=&nbsp;&nbsp;  12 ) {  
        return true ;  
    }&nbsp;&nbsp;  else {  
        return false ;  
    }  
}  
public void monthIncrement() {  
    this .value++;  
}  
public void monthReduction() {  
    this .value--;  
}  

}

class Year {
private int value;

public Year() {  
}

public Year(&nbsp;  int value) {  
    this .value = value;  
}

public int getValue() {  
    return value;  
}

public void setValue(&nbsp;  int value) {  
    this .value = value;  
}

public boolean isLeapYear() {  
    if ((&nbsp;  this .value %&nbsp;&nbsp;  4 ==&nbsp;&nbsp;  0 &&&nbsp;&nbsp;  this .value %&nbsp;&nbsp;  100 !=&nbsp;&nbsp;  0 ) ||&nbsp;&nbsp;  this .value %&nbsp;&nbsp;  400 ==&nbsp;&nbsp;  0 ) {  
        return true ;  
    }&nbsp;&nbsp;  else {  
        return false ;  
    }  
}  
public boolean validate() {  
    if (&nbsp;  this .value >=&nbsp;&nbsp;  1820 &&&nbsp;&nbsp;  this .value <=&nbsp;&nbsp;  2020 ) {  
        return true ;  
    }&nbsp;&nbsp;  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() {&nbsp;&nbsp;  //天数复位为1  
    day.setValue(&nbsp;  1 );  
}  
public void setDayMax() {  
    if (year.isLeapYear()) {  
        mon\_maxnum\[&nbsp;  1 \] =&nbsp;&nbsp;  29 ;  
    }&nbsp;&nbsp;  else {  
        mon\_maxnum\[&nbsp;  1 \] =&nbsp;&nbsp;  28 ;  
    }  
    if (month.getValue() -&nbsp;&nbsp;  1 >&nbsp;&nbsp;  0 ) {  
        day.setValue(mon\_maxnum\[month.getValue()-&nbsp;  1 \]);  
    }&nbsp;&nbsp;  else {  
        day.setValue(mon\_maxnum\[&nbsp;  0 \]);  
    }

}  
public boolean checkInputValidity() {  
    if ( month.validate() && year.validate() &&  
            day.getValue() >=&nbsp;&nbsp;  1 && day.getValue() <= mon\_maxnum\[month.getValue()-&nbsp;  1 \]) {  
        return true ;  
    }&nbsp;&nbsp;  else {  
        return false ;  
    }  
}  
public boolean compareDates(DateUtil date) {&nbsp;&nbsp;  // 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 ;  
    }&nbsp;&nbsp;  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 ;  
    }&nbsp;&nbsp;  else {  
        return false ;  
    }

}  
public String showDate() {  
    return year.getValue() +&nbsp;&nbsp;  "-" + month.getValue() +&nbsp;&nbsp;  "-" + day.getValue();  
}  
public DateUtil getNextNDays(&nbsp;  int n) {  
    for (&nbsp;  int i =&nbsp;&nbsp;  0 ; i < n; i++) {  
        if (year.isLeapYear()) {  
            mon\_maxnum\[&nbsp;  1 \] =&nbsp;&nbsp;  29 ;  
        }&nbsp;&nbsp;  else {  
            mon\_maxnum\[&nbsp;  1 \] =&nbsp;&nbsp;  28 ;  
        }  
        day.dayIncrement();  
        if (day.getValue() > mon\_maxnum\[month.getValue()-&nbsp;  1 \]) {  
            setDayMin();  
            month.monthIncrement();  
        }  
        if (month.getValue() >&nbsp;&nbsp;  12 ) {  
            year.yearIncrement();  
            month.setMin();  
        }  
    }  
    return this ;  
}  
public DateUtil getPreviousNDays(&nbsp;  int n) {  
    for (&nbsp;  int i =&nbsp;&nbsp;  0 ; i < n; i++) {  
        if (year.isLeapYear()) {  
            mon\_maxnum\[&nbsp;  1 \] =&nbsp;&nbsp;  29 ;  
        }&nbsp;&nbsp;  else {  
            mon\_maxnum\[&nbsp;  1 \] =&nbsp;&nbsp;  28 ;  
        }  
        day.dayReduction();  
        if (day.getValue() <=&nbsp;&nbsp;  0 ) {  
            month.monthReduction();  
            setDayMax();  
        }  
        if (month.getValue() <=&nbsp;&nbsp;  0 ){  
            month.setMax();  
            year.yearReduction();  
        }  
    }  
    return this ;  
}  
public int getDaysofDates(DateUtil date) {  
    int daysDifference =&nbsp;&nbsp;  0 ;  
    if (&nbsp;  this .equalTwoDates(date)) {  
        return 0 ;  
    }&nbsp;&nbsp;  else {  
        if (&nbsp;  this .compareDates(date)) {&nbsp;&nbsp;  //date大 求date前的day  
            while (!&nbsp;  this .equalTwoDates(date)) {  
                date.getPreviousNDays(&nbsp;  1 );  
                daysDifference++;  
            }  
        }&nbsp;&nbsp;  else {  
            while (!&nbsp;  this .equalTwoDates(date)) {  
                date.getNextNDays(&nbsp;  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 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 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 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 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 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 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 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 init(){
ArrayList ATMNumbers1 = new ArrayList<>();
ATMNumbers1.add("01");
ATMNumbers1.add("02");
ATMNumbers1.add("03");
ATMNumbers1.add("04");
Bank bank1 = new Bank("中国建设银行",ATMNumbers1);
ArrayList cards1 = new ArrayList(); // 用户拥有的卡
Card card1 = new Card("6217000010041315709","88888888");
Card card2 = new Card("6217000010041315715","88888888");
cards1.add(card1);
cards1.add(card2);
ArrayList 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 accountsOfUser1 = new ArrayList<>();
accountsOfUser1.add(account1);
accountsOfUser1.add(account2);
User user1 = new User("杨过", accountsOfUser1); // 杨过拥有两个账户
ArrayList cards3 = new ArrayList(); // 用户拥有的卡
Card card4 = new Card("6217000010051320007", "8888888");
cards3.add(card4);
ArrayList 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 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 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 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 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 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 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 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 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 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 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 init(){
ArrayList ATMNumbers1 = new ArrayList<>();
ATMNumbers1.add("01");
ATMNumbers1.add("02");
ATMNumbers1.add("03");
ATMNumbers1.add("04");
Bank bank1 = new Bank("中国建设银行",ATMNumbers1);
ArrayList cards1 = new ArrayList(); // 用户拥有的卡
Card card1 = new Card("6217000010041315709","88888888");
Card card2 = new Card("6217000010041315715","88888888");
cards1.add(card1);
cards1.add(card2);
ArrayList 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 accountsOfUser1 = new ArrayList<>();
accountsOfUser1.add(account1);
accountsOfUser1.add(account2);
User user1 = new User("杨过", accountsOfUser1); // 杨过拥有两个账户
ArrayList cards3 = new ArrayList(); // 用户拥有的卡
Card card4 = new Card("6217000010051320007", "8888888");
cards3.add(card4);
ArrayList 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 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.到这个阶段,我们对面向对象的编程思想已经有了学习,做题时不要再想着面向过程去偷懒,练习时多用用平时学到的东西,把自己的基础打扎实。