题目集7~9总结性blog

(1)前言

       这应该是本学期的最后一次总结性博客,用来总结开学以来的阶段性作业的最后一次了。所以要把这最后三次pta的知识点和题量以及难度都要有所分析。

       首先呢,这三次作业的难度是非常高的,要求我们写的代码行数都是一个题几百行几百行的去完成,其次,会有一些新的知识需要我们去学习完成,比如ArrayList泛型的应用方法还有Comparable接口及泛型的应用,这些都是必须由我们自己去学习实践来掌握,可以说时间是非常非常的紧张。

       题目集7是只有两道题,但两道题都是拿卡片图形作为背景出题,题目中要求我们使用相关的知识点完成代码。题目集7的第一题是对卡片面积进行排序,该题要求用到的知识点应该包括单一职责原则的应用,以及“开-闭”原则的应用,这让我们更加注重对不同图形类的设计,将不同类进行良好的封装,并且完成类的单一职责。在此设计中,我们就出了几个图形自己的类,还有Shape父类,DealCardList类,对卡片校验面积排序,最后完成输出的功能。该代码,完成的是对图形排序的功能,向其中添加代码应该也是比较容易,因此该类的单一性职责完成的比较好。代码的维护性较高。

        题目集7的作业对我们来说相对容易,比较容易实现。但最后两次作业的ATM机的习题相对较复杂,第一次作业不支持跨行取款,而第二次作业要求实现跨行取款,并且要有费用扣除,这就需要我们多查阅资料,想清楚借记卡和贷记卡的关系。

        该套试题的难度,由易到难,需要用到的知识点也不断增多,题量倒不是很大,但单个题目的完成较为困难。

        下面我来以表格的形式总结一下这几次作业要用到的相关知识。

题目集 知识点
题目集7 ArrayList泛型
Comparable接口及泛型的应用
compareTo方法
题目集8 Iterator迭代器使用
 for each语句
 
题目集9  
   
   

(2)设计与分析

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

(7-1)

  

 

(7-2)

 

 

 

 

        这两道题是图形排序问题,输入图形的编号,再依次输入图形的参数,对图形计算面积并排序。第一个要求输出排序前的各图形类型及面积、排序后的各图形类型及面积、所有图形的面积总和,第二道题是要求输出排序前的各图形类型及面积、输出分组后的图形类型及面积、各组内图形排序后的各图形类型及面积和各组中面积之和的最大值输出。这次作业的两个题目功能有所不同,要求是有变化的。关于代码 递进式结构,两者没有什么太多不同,都是有一个父类Shape,各个图形继承父类。在DealCardList类中,完成几种功能,集合其他多种类进行计算,validate校验图形形状是否正确,cardSort对卡片的面积进行排序,getAllArea是计算所求面积之和,showResult用于展示输出结果。

       通过圈复杂度的生成报表我们也能看出,这两个题目的最大复杂度是一样的,也就是说明,在完成两次习题时程序并没有添加太多的if语句使其复杂化,而是尽量避免使用这些复杂语句。

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

        这两次ATM机最明显的特点之一就是类的设计,题目要求中也给出了关于银行ATM机存取款的要求,所需要用到的类的功能及其概念。题目集8要求我们自己完成ATM机的存取款功能,但是不能跨行取款,题目中给出了中国建设银行和中国工商银行,以及几个人物,他们的卡号,账户,因此我就设计了几个类ATM、Message、Messageget、Account、Bank、Card、User。

这些类的关系图如下,以下是题目集8的类图

 

        通过上面类图我们可以看出,各个类的功能是独立的,Message单独为一个类就是把所有的信息存储进去,把人名、ATM机编号、卡号、银行等信息存入。而Messageget判断ATM机编号是否正确,判断卡号是否存在,其他的几个类,像什么ATM,定义的属性是银行的id,创建银行对象。User类创建用户姓名的相关属性,以及使用链表对账户进行存储,对帐户进行添加或删减。而Account类将默认的账户余额设定为10000,创建银行的对象,使其又与银行有所关联,由此可以看出,这些类之间互相功能独立,而又相互依托。在本次作业中,ChinaUnionPay没有什么实际作用,目的是为第二次ATM机实验做准备。

上面题目集8是要求我们自己对代码写并完成,接下来我们分析一下题目集9的设计思路

以下是题目集9的生成类图

 

 

 

 

       题目集9的类图之间关系比较复杂,这次把客户的数据均存储在了Main方法中,与我第一次写的代码不同,第一次是把这些数据存储在了Massage当中,这次直接在主方法中进行存储,这次作业与第一次作业的不同是需要区分借记卡和贷记卡,并且需要在存取款的过程中扣除手续费。因此需要添加贷记账户和借记账户的类,并作为子类继承于父类Account,创建的BankCard继承于Card,进行存钱取钱的操作。

 1 class BankCard extends Card {
 2 
 3     public BankCard(String cardNO, String cardPassword, Account ccbAcc) {
 4         super(cardNO,cardPassword,ccbAcc);
 5     }
 6     
 7     public void access(double money,Bank bank) {//对金额操作的函数
 8         if(money > 0) {
 9             super.getAccount().withdrawal(money,bank);
10         }else {
11             super.getAccount().withdrawal(-money, bank);
12         }
13     }
14 }

       接下来对两次代码的复杂度进行测试

 

 

 

 

       由上图可以看出两次代码的复杂度差1,而且复杂度都过了10,说明这个代码仍可以改进,让复杂度降得更低。以上是我对ATM机两次作业的相关分析,两次代码,一次是要求自己完成,另一次是老师给出了上一次作业的代码,让我们自己看懂代码再做改进,实现银行跨行取款的功能。

(3)踩坑心得

题目集7

       两个题难度不是很大,需要我们掌握ArrayList的用法以及更进一步加强对开闭原则的理解,就像我们我们从本学期开始起,老师告诉我们的Java是一种面向对象编程思维的语言一样。不管怎么样,学习从来不是一件轻松的事,它需要我们琢磨,改进自己的思维方式。

       在该题中,主方法已经给出,为我们完成此题给出了很多提示。首先,在完成题目集7的过程中,先创建那几个图像类,要求对图形求面积,我们可以先写好几个方法,比如按照作业要求的父类Shape,先写好Shape中的属性和方法如下

abstract class Shape{
    String shapeName;
    abstract double getArea();
    abstract boolean validate();
    public Shape() {
        
    }
    public Shape(String shapeName) {
        super();
        this.shapeName = shapeName;
    }
    String getShapeName() {
        return shapeName;
        
    }
    public void setShapeName(String shapeName) {
        this.shapeName = shapeName;
    }
    public String toString() {
        return shapeName;
        
    }
}

        然后各图形继承Shape,在图形中重写计算图形面积的方法,并且validate方法校验图形输入的数据是否正确。所有图形内部的方法和属性写起来比较相似。最后我们还要创建一个Card类,主要的一点其实是写DealCardList类,在该类中我们要用到ArrayList泛型,这时我们就需要上网查阅一下资料。关于ArrayLIst泛型的用法。可以对其中的元素进行增删改查,这对我们存储数据有着极大的便利。接下来是我们对DealCardList类中的ArrayList的使用做些分析,其中的Card为泛型,用于设置对象的数据类型。变量设成cardList,在构造方法中将卡牌名称添加到cardList里去。

        题目集7的第二题是对第一题的代码进行了改进,可能会用到的新的知识点是Comparable、Comparator 接口,在这里我使用的是Comparable接口。在这里,我加深了对Comparable接口于compare方法使用上的区别,当要比较的数字是Byte, Double, Integer, Float, Long 或 Short 类型之外的数据类型:如int,或者char类型的数据就无法直接使用compareTo方法,我们就需要使用Comparable接口。代码如下。

 1 class Card implements Comparable<Card>{
 2     private Shape shape;
 3     
 4     /**
 5      * @param shape
 6      */
 7     public Card(){
 8         
 9     }
10     public Card(Shape shape){
11         this.shape = shape;
12     }
13     public Shape getShape() {
14         return shape;
15     }
16     public void setShape(Shape shape) {
17         this.shape = shape;
18     }
19     @Override
20     public int compareTo(Card card) {
21 
22         if(this.getShape().getArea()<card.getShape().getArea())//this.小则返回1,大则返回-1
23             return 1;
24         else if(this.getShape().getArea()==card.getShape().getArea())
25             return 0;
26         else
27             return -1;
28     }
29     
30 }

       两道题改动不是很大,但是有我需要学习的新的知识点,在于动手操作方面还是需要我们多加练习的,不多加练习,还是有很多方法不能灵活运用。

题目集8

       关于ATM存款机的问题,感觉除了麻烦还是麻烦。当自己连好多方法都还不会用的时候,就会手忙脚乱。看着那么长的题目背景,一开始的思路只有把这几个类先搞出来。与以往不同的是这次作业的题目老师没有给出类图,需要自己设计,就一定要清楚类与类之间应该创建什么样的关系。一开始没什么思路,想的也比较单纯。把几个类先写出来ATM,Bank,User,Account,Card和ChinaUnionPay,这几个类关于如何让其关联又成了问题。后来借助了别人的一点思路,要把那些用户信息专门存起来,存信息我也就专门创建了一个类Message类,信息存储如下。

 1 class  Message{
 2     ChinaUnionPay chinaUnionPay = new ChinaUnionPay();
 3     ATM atm[]={
 4             new ATM("01", chinaUnionPay.CCB, chinaUnionPay),
 5             new ATM("02", chinaUnionPay.CCB, chinaUnionPay),
 6             new ATM("03", chinaUnionPay.CCB, chinaUnionPay),
 7             new ATM("04", chinaUnionPay.CCB, chinaUnionPay),
 8             new ATM("05", chinaUnionPay.ICBC, chinaUnionPay),
 9             new ATM("06", chinaUnionPay.ICBC, chinaUnionPay)
10     };
11     User user[]={
12             new User("杨过"),
13             new User("郭靖"),
14             new User("张无忌"),
15             new User("韦小宝")
16     };
17     Account account[] = {
18             new Account(chinaUnionPay.CCB,user[0],"3217000010041315709",10000.00),
19             new Account(chinaUnionPay.CCB,user[0],"3217000010041315715",10000.00),
20             new Account(chinaUnionPay.CCB,user[1],"3217000010051320007",10000.00),
21             new Account(chinaUnionPay.ICBC,user[1],"3222081502001312389",10000.00),
22             new Account(chinaUnionPay.ICBC,user[2],"3222081502001312390",10000.00),
23             new Account(chinaUnionPay.ICBC,user[2],"3222081502001312399",10000.00),
24             new Account(chinaUnionPay.ICBC,user[2],"3222081502051320785",10000.00),
25             new Account(chinaUnionPay.ICBC,user[3],"3222081502051320786",10000.00),
26     };
27      Card card[] = {
28             new Card("6217000010041315709",account[0],chinaUnionPay,"中国建设银行"),
29             new Card("6217000010041315715",account[0],chinaUnionPay,"中国建设银行"),
30             new Card("6217000010041315718",account[1],chinaUnionPay,"中国建设银行"),
31             new Card("6217000010051320007",account[3],chinaUnionPay,"中国工商银行"),
32             new Card("6222081502001312389",account[4],chinaUnionPay,"中国工商银行"),
33             new Card("6222081502001312390",account[5],chinaUnionPay,"中国工商银行"),
34             new Card("6222081502001312399",account[6],chinaUnionPay,"中国工商银行"),
35             new Card("6222081502001312400",account[6],chinaUnionPay,"中国工商银行"),
36             new Card("6222081502051320785",account[7],chinaUnionPay,"中国工商银行"),
37             new Card("6222081502051320786",account[7],chinaUnionPay,"中国工商银行"),
38     };
39      ATM jiaoyan(String str){
40          for(ATM i:atm){
41              if(i.BankID.equals(str)){
42                  return i;
43              }
44          }
45          return null;
46      }
47 }

       将用户信息都存储到该类之中,然后就是Messageget类,对信息进行处理,检查ATM的编号是否正确,检查银行卡是否存在。该代码中关于新的知识点并没有多少,但是需要我们对代码的设计有了更高的要求,没有了之前老师给的类图,只能是自己动手设计,难度提升了不少。希望在以后的学习中,我们可以更多的动手操作,思考代码的构造。

题目集9

       题目集9是修改老师的代码,要求我们必须看懂老师的代码。老师的代码是直接存储在了主方法中。这次需要主义的是要添加借记账户和贷记账户

 

      这就需要我们理解借记账户和借记账户的概念,借记卡是要收取手续费的,而贷记卡则有最大透支金额的限制。在老师的代码中用到了迭代器,迭代器的用法

 1 while(bankItr.hasNext()) {
 2             bank = bankItr.next();
 3             Iterator<ATM> aTMItr = bank.getATMList().iterator();    
 4             
 5             while(aTMItr.hasNext()) {
 6                 aTM = aTMItr.next();
 7                 if(aTM.getATMID().equals(ATMID)) {
 8                     return aTM;
 9                 }
10             }
11         }        

 (4)改进建议

       题目集7的代码复杂度有些高,我希望的是能够将能修改的if语句都用switch语句代替,降低复杂度。题目集8中和题目集9中运用到了ArrayList泛型,但是我又对Map和Set有所了解,Map集合所涵盖的方面更广阔。可以多个银行卡对应一个账户,也可以用多个账户对应一个用户,也应该会方便一些。

(5)总结

       这学期的pta作业结束了,我们从一次次作业中获得了学习Java的方法,可以帮助我们在今后学习Java的路途上走的更远。对这几次作业而言,大概也是这学期对我们考验最大的代码。对于题目集7来说,这次代码有几百行,图形较多,每个图形都是一个类,整合后实现功能。包括后面的改进后的图形卡片游戏,思路都大致一样。

       随后的ATM机的两次作业大大提升了我们编写代码和设计代码的能力,让我们更好的运用进去。

       重点总结一下,ATM机,功能作用在于简单的存取款与查询余额。类间关系设计以及对于“开-闭”原则,单一职责原则的掌握。跟题目集8的7-1有所不同的是添加一种信用卡,可以进行贷记操作,以及银联有了超额度的服务费扣取功能,跨行收费。主类中都是根据正则表达式以及if语句决定功能走向的分支。不同点在于会在题目集9的代码中不同的银行添加不同的利率属性,在业务类中添加对跨行后的收费处理以及透支判断等。以及迭代到的不仅是相同背景内容的功能添加,更有考虑到类间关系,去充分利用实体类的属性绑定以及方法调用。

       这三次作业,我学习到了ArrayList泛型,迭代器的使用,并且更好的理解了类的开闭原则,类的封装性。但对于Map,Set等等工具的用法还不熟练,还需深入研究,进行实操,多掌握代码的使用方法。Java这门课程使用的线上线下的教育模式,效果还可以,就是感觉平时自学的效果不太好,网上资料很杂乱,有许多都看不懂,希望能够有一些更多的实例供我们学习参考。

posted @ 2021-06-15 10:13  zbm123  阅读(64)  评论(0)    收藏  举报