Blog作业03

一、前言

 

题目集7中主要运用到的知识有继承、多态、ArrayList泛型的应用方法、

Comparable接口及泛型的应用、单一职责原则的应用、“开-闭”原则的用。

题目集8和题目集9是ATM机仿真题目,重点考核的知识是继承、多态和抽象类。

三次题目集的题量不大,但每题代码量有所上升,特别是题目集8和题目集9关于ATM机的题目,难度也有所提高。

 

二、设计与分析

题目集77-1)、(7-2)两道题目的递进式设计分析总结

  

7-1:

  • 首先,在一行上输入一串数字(1~4,整数),其中,1代表圆形卡片,2代表矩形卡片,3代表三角形卡片,4代表梯形卡片。各数字之间以一个或多个空格分隔,以“0”结束。例如: 1 3 4 2 1 3 4 2 1 3 0
  • 然后根据第一行数字所代表的卡片图形类型,依次输入各图形的相关参数,例如:圆形卡片需要输入圆的半径,矩形卡片需要输入矩形的宽和长,三角形卡片需要输入三角形的三条边长,梯形需要输入梯形的上底、下底以及高。各数据之间用一个或多个空格分隔。类图如下:

 

  1. Comparable接口,用于实现卡片排序:

interface Comparable{

    public abstract ArrayList CompareTo(ArrayList<Card> cardList);

}

         2.Card类,实现接口Comparable中的排序功能:

     

 

         3.DealCardList类,用于卡片对象的创建、合法性检验、求面积总和、  

  以及输出结果:

 

 

 

 

 

 

 

      4.抽象父类Shape:

           

 

  5.类Circle,继承于抽象类Shape:

    

 

 

 

6.类Rectangle,继承于抽象类Shape:

    

 

 

7.类Triangle,继承于抽象类Shape:

            

           

 

 

8.类Traperoid,继承于抽象类Shape:

 

 

 

 

9.主类:

         

 

 

 

SourceMonitor报表:

 

 

 

 

 

小结:本题主要考类的继承、多态以及对接口的实现。通过上网学习,学会了利用Collections.sort对各图形进行排序。

 

 

 

 

 

7-2

 在一行上输入一串数字(1~4,整数),其中,1代表圆形卡片,2代表矩形卡片,3代表三角形卡片,4代表梯形卡片。各数字之间以一个或多个空格分隔,以“0”结束。例如:1 3 4 2 1 3 4 2 1 3 0

根据第一行数字所代表的卡片图形类型,依次输入各图形的相关参数,例如:圆形卡片需要输入圆的半径,矩形卡片需要输入矩形的宽和长,三角形卡片需要输入三角形的三条边长,梯形需要输入梯形的上底、下底以及高。各数据之间用一个或多个空格分隔。类图如下:

 

7-1不同的地方:

1.将原来所有图形对象放在一个链表中改为将图形分组分别放入不同的链表中。

修改前代码:所有对象放在链表cardlist链表中。

       

修改后代码:

 

 

2.排序以及输出结构:

 

 

 

 

3.增加了求最大面积的方法:

      

 

 

 

SourceMonitor报表:

 

.

 

 

 

小结:本题在7-1基础上增加了对图形面积排序的方法;以及改变了输出的格式;另外图形对象的存储方式改变,方便对图形排序并分组输出。

 

 

 

 

 

题目集8和题目集9两道ATM机仿真题目的设计思路分析总结

 

 

题目集8:7-1

 

编写一个银行 ATM 机的模拟程序,能够完成用户的存款、取款以及查询余额功能。

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

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

查询余额功能输入数据格式: 卡号

类图如下:

   

 

 

 

1.Bank类

私有属性: private String bankNO;

                  private String bankName;

                  private ArrayList<Account> accountList = new ArrayList<Account>();

                  private ArrayList<ATM> ATMList = new  ArrayList<ATM>();

       

 

        

 

 

2.User类

私有属性: private String ID;

                  private String name;

                  private String Phone;

                  ArrayList<Account> list = new ArrayList<Account>();

 

 

 

 

 

 

3.Account类

私有属性: private String accountNO;

                 private double balance = 0;

                 private User user = null;

                 private Bank bank = null;

                 private static ArrayList<Card> list = new

                 ArrayList<Card>();

 

         

        

 

 

 

4.Card类

私有属性: private String cardNO;

                  private String cardPassword;

                  private Account account = null;

 

 

 

 

 

 

5.ATM类

私有属性: private String ATMID;

                 private Bank bank = null;

    

 

 

6.UnionPay类

私有属性: private ArrayList<Bank> bankList = new ArrayList<Bank>();

 

 

 

 

 

7.Withdraw类

私有属性:private UnionPay unionPay;

                private String cardNO;

                private String cardPassword;

                private String ATMID;

                private double amount;

 

    

      

      

       

 

 

 

 

 

8.ValidateData类

 

 

 

 

 

 

9.GetBalance类

私有属性:private UnionPay unionPay;

       

 

SourceMonitor报表:

 

 

 

 

 

小结:本题首先是对输入的字符串进行操作,运用到了split、String.format等方法;然后在Account类中创建Bank类和User类,巧妙地解决了如何反向查找信息。

 

 

 

 

题目集9:7-1

 

在题目集8的基础上修改了规则:

①银行账户分为借记账户和贷记账户两种,其中,借记账户不能够

透支取款,而贷记账户可以透支取款(可能需要支付手续费)。

根据账户 的不同,银行卡一般分为借记卡(针对借记账户)和信用卡针对贷记账户)两类。

类图如下:

 

 

 

 

 

1.Bank类:增加跨行手续费

 

私有属性:private String bankNO;

                  private String bankName;

                  private double kuahang_servicecharge;//跨行手续费

                  private ArrayList<Account> accountList = new ArrayList<Account>();

                  private ArrayList<ATM> ATMList = new ArrayList<ATM>();

 

 

2.Account类:改为抽象类

增加贷款手续费、贷款限额

 

私有属性:private String accountNO;

                  private double balance = 0;

                  private User user = null;

                  private Bank bank = null;

                  private double daikuan_servicecharge;//贷款手续费

                  private double daikuan_quota;//贷款限额

                  private static ArrayList<Card> list = new ArrayList<Card>();

 

   

 

 

 

3.DebitAccount类:继承于Account类,借记卡;

 

 

4.CreditAccount类:继承于Account类,信用卡;

 

 

 

 

 

 

5.Withdraw类:修改合法性检验、增加取款方法。

    

 

 

 

SourceMonitor报表:

 

 

 

 

小结:本题在题目集8的基础上将账户抽象,增加信用卡和借记卡两种账户类型,其中借记卡可以透支取款;另外增加款行取款的取款方式,并收取跨行手续费。

 

 

 

 

 

 

三、采坑心得

 

题目集七7-1:利用Collections.sort对链表进行排序:

 

public ArrayList CompareTo(ArrayList<Card> cardList) {

       Collections.sort(cardList, new Comparator<Card>() {

             public int compare(Card o1, Card o2) {

                   return (int) (o1.getShape().getArea() - o2.getShape().getArea());

             }

       });

       return cardList;

}

           

 

题目集七7-2:在题目集七7-1中只用到一个List来存储图形对象,在7-2中发现这样排序很复杂,而且很难做到分组输出。所以7-2中改为每种图形分别放在一个List中,然后分别进行排序、输出。

 

修改后:

class DealCardList{

ArrayList<Card> cardList=new ArrayList<Card>();

ArrayList<Card> CircleList=new ArrayList<Card>();

ArrayList<Card> RectangleList=new ArrayList<Card>();

ArrayList<Card> TriangleList=new ArrayList<Card>();

ArrayList<Card> TrapezoidList=new ArrayList<Card>();

public DealCardList() {

 

}

public DealCardList(ArrayList<Integer> list) {

for(int i = 0;i < list.size();i++){

if(list.get(i) == 1) {

double r = Main.input.nextDouble();

Circle circle = new Circle(r);

Card card = new Card(circle);

card.getShape().setShapeName("Circle");

cardList.add(card);

CircleList.add(card);

}

if(list.get(i) == 2) {

double width = Main.input.nextDouble();

double length = Main.input.nextDouble();

Rectangle rectangle = new Rectangle(width,length);

Card card = new Card(rectangle);

card.getShape().setShapeName("Rectangle");

cardList.add(card);

RectangleList.add(card);

}

if(list.get(i) == 3) {

double side1 = Main.input.nextDouble();

double side2 = Main.input.nextDouble();

double side3 = Main.input.nextDouble();

Triangle triangle = new Triangle(side1,side2,side3);

Card card = new Card(triangle);

card.getShape().setShapeName("Triangle");

cardList.add(card);

TriangleList.add(card);

}

if(list.get(i) == 4) {

double topside = Main.input.nextDouble();

double bottomside = Main.input.nextDouble();

double height = Main.input.nextDouble();

Traperoid traperoid = new Traperoid(topside,bottomside,height);

Card card = new Card(traperoid);

card.getShape().setShapeName("Trapezoid");

cardList.add(card);

TrapezoidList.add(card);

}

}

}

public boolean validate(){

for(int i = 0;i < cardList.size();i++) {

if(!cardList.get(i).getShape().validate()) {

return false;

}

}

return true;

}

    public void cardSort() {

     Card a = new Card();

     cardList = a.CompareTo(cardList);

     cardList = a.CompareTo(CircleList);

     cardList = a.CompareTo(RectangleList);

     cardList = a.CompareTo(TriangleList);

     cardList = a.CompareTo(TrapezoidList);

}

public double getAllArea(ArrayList<Card> list) {

double sum = 0;

for(int i = 0;i < list.size();i++) {

sum = sum + list.get(i).getShape().getArea();

}

return sum;

}

public double maxArea() {

double allCircleArea = getAllArea(CircleList);

double allRectangleArea = getAllArea(RectangleList);

double allTriangleArea = getAllArea(TriangleList);

double allTrapezoidArea = getAllArea(TrapezoidList);

double a = Math.max(allCircleArea , allRectangleArea);

double b = Math.max(allTriangleArea, allTrapezoidArea);

return Math.max(a,b);

}

public void showResult() {

 System.out.println("The original list:");

 System.out.print("[");

 for(int i = 0;i < cardList.size();i++) {

 System.out.print(cardList.get(i).getShape().getShapeName()+":"+String.format("%.2f",cardList.get(i).getShape().getArea())+" ");

 }

 System.out.print("]");

 

 System.out.println();

 

 System.out.println("The Separated List:");

 System.out.print("[");

 for(int i = 0;i < CircleList.size();i++) {

 System.out.print(CircleList.get(i).getShape().getShapeName()+":"+String.format("%.2f",CircleList.get(i).getShape().getArea())+" ");

 }

 System.out.print("]");

 System.out.print("[");

 for(int i = 0;i < RectangleList.size();i++) {

 System.out.print(RectangleList.get(i).getShape().getShapeName()+":"+String.format("%.2f",RectangleList.get(i).getShape().getArea())+" ");

 }

 System.out.print("]");

 System.out.print("[");

 for(int i = 0;i < TriangleList.size();i++) {

 System.out.print(TriangleList.get(i).getShape().getShapeName()+":"+String.format("%.2f",TriangleList.get(i).getShape().getArea())+" ");

 }

 System.out.print("]");

 System.out.print("[");

 for(int i = 0;i < TrapezoidList.size();i++) {

 System.out.print(TrapezoidList.get(i).getShape().getShapeName()+":"+String.format("%.2f",TrapezoidList.get(i).getShape().getArea())+" ");

 }

 System.out.print("]");

 System.out.println();

 

 cardSort();//排序

 System.out.println("The Separated sorted List:");

 System.out.print("[");

 for(int i = CircleList.size() - 1;i >= 0;i--) {

 System.out.print(CircleList.get(i).getShape().getShapeName()+":"+String.format("%.2f",CircleList.get(i).getShape().getArea())+" ");

 }

 System.out.print("]");

 System.out.print("[");

 for(int i = RectangleList.size() - 1;i >= 0;i--) {

 System.out.print(RectangleList.get(i).getShape().getShapeName()+":"+String.format("%.2f",RectangleList.get(i).getShape().getArea())+" ");

 }

 System.out.print("]");

 System.out.print("[");

 for(int i = TriangleList.size() - 1;i >= 0;i--) {

 System.out.print(TriangleList.get(i).getShape().getShapeName()+":"+String.format("%.2f",TriangleList.get(i).getShape().getArea())+" ");

 }

 System.out.print("]");

 System.out.print("[");

 for(int i = TrapezoidList.size() - 1;i >= 0;i--) {

 System.out.print(TrapezoidList.get(i).getShape().getShapeName()+":"+String.format("%.2f",TrapezoidList.get(i).getShape().getArea())+" ");

 }

 System.out.print("]");

 System.out.println();

 System.out.println("The max area:"+String.format("%.2f",maxArea()));

}

}

 

 

题目集八7-1:

1.在做题之前,老师提到要实现双向链表的功能,当时自己想的是用多个迭代器来实现,但发现太复杂。经过老师讲解,可以用以下方法:

在Account类中创建User对象和Bank对象,这样就可以通过账户找到账户对应的用户以及账户所在银行。

同样的在Card类中创建Account对象。在ATM类中创建Bank对象。

这样就达到了双向链表的功能。

 

代码:

  

          

            

 

          

2.在遍历链表时老是报错说某张卡为null,或者某给账户为null。

 

 原因:一开始时遍历链表是用for循环语句,没有判断是否为空。

修改前:

          

 

修改后:

           

 

        老师讲解并修改后采用迭代器:

    

 

 

 

题目集九7-1:

        在测试数据时发现借记卡在反复取款直到余额为0,再取款时发现可以透支取款。

 

修改后代码:

 /**

 * 校验是否为跨行取款

 */

if (account.getBank().getBankNO() !=

aTM.getBank().getBankNO()) {

/**

 * 校验在跨行情况下取款金额是否大于余额

 */

if (amount * (1 + kuahang_servicecharge) >

account.getBalance() + daikuan_quota) {

   System.out.println("Sorry,your account

balance is insufficient.");

   System.exit(0);

  }

 

}

 

 

 

四、改进建议

 

  1. 对于Java设计的七大原则还需练习,在实际写代码中时常忽略掉一些原则。
  2. 对于类之间的关系还需多加练习。就拿题目集八的ATM机题目来说,在老师讲之前对于每个类之间的关系不太明确,与老师讲的有所不同,在老师讲解后对每个类之间的关系更加明确、清晰。
  3. 有很多Java已有的类的方法不了解或是根本不知道,在写代码时有时会运用比较复杂的方法,所以在以后的学习中还要学习更多的已有的方法。

 

 

 

 

五、总结

 

    1.通过题目集七7-1、7-2学会运用Collections.sort对List进行排序。

 

public ArrayList CompareTo(ArrayList<Card> cardList) {

Collections.sort(cardList, new Comparator<Card>() {

    public int compare(Card o1, Card o2) {

        return (int) (o1.getShape().getArea() - o2.getShape().getArea());

    }

});

return cardList;

}

 

        2.通过题目集八7-1学会了双向链表的使用;对代码类的关系设计更加清晰,另外对于“单一原则”更加明确;学会了迭代器的使用,并使用迭代器遍历List。

 

    3.通过题目集九7-1对于“开闭原则”更加明确;对于类的继承、多态以及组合的使用更清晰;

 

 

posted @ 2021-06-17 18:40  某人某码  阅读(60)  评论(0)    收藏  举报