Java第三次总结
Java 第三次总结
一、前言
从题目集七开始,我们开始了真正的关于编程思想的学习及运用。
(1)题目集七:主要训练我们关于类的继承,多态,接口的使用。题目集七的两道题目为递进式,第一题是对于卡片上图形面积的排序,第二题则是先进行图形分类,在进行排序。在题目难度上都很简单,只是基础应用,题目的代码数量相较于前几次也有明显上升。这两道题目都涉及到了类的多态性的使用,即一个抽象的图形父类及多个不同图形的子类,这明确使用了类的继承,然后在处理类中则使用父类的引用和子类的对象,实现类的多态性。本次使用的接口则是Comparable<>接口,这是系统文件中自带的接口,我在类中进行了重写compareTo方法,使得它可以排序按照要求我们的卡片类,为此使用了泛化,泛化为实体卡片类。在该题目中,还涉及了ArrayLIst的泛化使用及设计原则(开—闭原则,单一原则)的运用,巩固了以前的知识点。
(2)题目集八和九则是要求我们设计ATM机的取款程序的设计,都是对于以前学习过的知识点进行综合的运用,重点在于对于我们编程思想的运用,题目集八程序要求实现存取款和查询余额的功能,没有特殊要求,考察的是类与类间关系的设计,代码量在600多行左右。题目集九则是要求了可以跨行取款,设置了借记卡和贷记卡两种,加大了难度,主要涉及到了多态与继承的使用,对于类与类间关系的设计要求更加的严格了。
对于这三次题目集,题目的数量很少质量却很高,加大了题目难度以及题目代码的行数,对于基础知识点进行了综合运用,着重训练了我们的设计思维能力,加深了对于设计基本原则的理解(如:开闭原则,单一原则......)。
二、设计与分析
(1)题目集七
第一题和第二题的都是重点于类的继承、多态及接口的使用,而且前言所说,两者为递进式的题目,在题目中,给出了类图,让我们可以思考为什么要这么设计及这样设计的好处。第一题的类图如下:

如该类图所示,设计了一个父类:shape类,该类有着图形所共有的属性:图形的名字及部分方法。其中的getArea()(计算面积) 及 validata()(检验输入数据) 方法由于每个图形的都不同,所以我设计成抽象方法,从而运用了多态的方法,使得每个图形子类可以拥有自己的计算面积的方法,利用继承,可以使用父类的引用子类的对象,该种方式也是多态的一种,利用同一种父类引用,我们的程序可以更加的灵活多变,如图:

利用父类的引用,我们的card类可以包含每一种图形,然后在处理类中就可以利用card类一个类,从而联系到每一个实体类,从而简化我们的程序,如图,关联关系就只有父类与card类才有,使得程序的结构也更加的简便,维护起来更加容易。这里的card类中继承了一个接口,该接口为Java中自带的接口,通过重写该接口,我可以在排序中使用该接口,按照我自己的设计来进行排序,下图为我重写的接口:

通过改写该接口,我可以直接使用sort方法来排序我的卡片面积。
这次老师给出的程序设计还有个处理类,该类也是一个设计中的重点,利用处理类,将众多实体类联系到一起,但实体类之间没有任何关系,会不影响,这样也会使得程序越发的结构清楚简单,利于维护。
在程序复杂度方面,通过软件分析如下图:

复杂度都小于10,符合程序设计要求,处理类和三角形类的复杂度为7,都是由于我的过度使用if else 语句进行输入的判定,我认为还是可以简化下程序,但现阶段没有任何方法。
第二题则是前一题的递进式,第二题不但要求我们进行排序,而且要求我们先分类,再排序。虽然第二题变得更加的复杂,但是由于第一题的铺垫,第二题还是非常的简单的,类图都与第一题一样,还是实体类还是使用了继承,第二题我学会了一种新的输出格式,
可以针对于各个类的类名进行输出,如图:

通过改写类的toString()方法,进而改变类的输出形式,这也是一种很方便的输出方法。对于复杂度来说,该题和上一题并无太大区别。
通过这两道题,我清楚的理解了继承和多态的使用,也了解到了接口的使用,一般对于动作操作我们使用接口继承,对于实体类,我们则使用抽象类去继承。不仅对于继承和多态,在程序设计结构上,我认为这种设计真的使得程序很简单明了,按照老师这种程序设计,该程序遵循了开闭原则,单一原则等设计原则,使得程序具有良好的可扩展性和维护性,即使我们在这个基础上再次加上一些其他的图形,也可以重写求面积方法从而使得我们加上这个新的图形类,最后改一下输入便使得程序可以正常运行,这也体现了Java语言在面对对象设计上的优势,即使程序相较于C语言会更为复杂一点,但是在可维护性和可扩展性上却有着非常大的优势,使得我理解了Java语言的学习重点在于设计上。
(2)题目集八和九
对于题目集八和题目集九,则是老师对我们Java设计上的综合训练,都是关于ATM机的取款和查询余额的操作模拟程序。对于题目集八来说,相较于前面的第七次题目集,题目集八虽然只有一道题目,但是老师却没有提供任何的设计类图,靠我们自己思考如何去设计一个良好的Java程序。如下图,则是我设计程序的类图:

在我的想法是分级从属关系,如下图代码,银联类中有一个银行链表,说明可以拥有多家银行。

每个银行中又有着多个用户,多个用户又有着多个账号,多个账号有着多张卡,一级一级从属下去,最后我只要一个初始话了的unionPay类对象,就可以知道存储的每个信息。整个实体类结构就是这样,然后我分出了一个操作类,该类中有着许许多多的处理方法,如:判断输入,进行存取款操作以及余额查询操作,整个程序的结构很简单,进行的操作也很简单,首先对于老师给的初始化数据进行了初始化操作,在进行输入操作后,进行判断,卡号,密码,atm机号是否正确,由于不能跨行取款,所以还判断了是否跨行,进行一系列的判断后,就开始了查找操作,如下图:这就是其中查找卡号的操作方法,可以看出,就是简单的遍历查找。

在查找上,我是用的是for each()查找方法,也就是我初始化了的链表进行分级遍历操作,从而查询到输入的卡号,找到卡号和账户后,进行操作就是尤其简单的了。但是我发现,如果程序中初始化了的数据很多,那么程序运行的时间将大大提升。在做完这道题目后,我发现了一个很致命的设计,就是对于我的程序结构,没有符合开闭原则,我这个程序完全不能进行修改操作,如:加上一个转账功能啊,加入新的账号类型啊,都会大幅改变我的程序结构,所以这次的程序设计不算成功。
对于复杂度进行分析:

发现最大复杂度很小,完全符合复杂度要求,重点问题在于程序结构上。
题目集九则是对于题目集八的一次迭代,题目集九要求我们有着不同的账户,有着借机账户和贷记账户两种,还允许了跨行取款。经过老师的指导,我重构了本次实验程序的结构,如下图:

本次实验的类图看似复杂,却结构简单。首先,银行类与用户类不在有任何关联了,因为用户不属于银行所以单独分割出去,两者的关系则由账号关联起来,其次,由于多了一种账户类型,所以我使用了继承,方便以后的扩展,在继承中,我的贷记账户多了一个透支额度,我设为了子类的私有属性,在调用中,因为是父类的引用,子类自己的方法是不可以使用的,所以,我在这使用了强制类型转换,如下图:

将父类转换为子类即可。在进行类型转换前,我使用了instanceof进行类的判定:

该判定可以让我知道到底是哪一种子类,而且,在取款方法上,我也做出了继承,分为了两种取款方式,判断了取款账户后,就可以很清楚的利用相对应的取款方式进行取款。
本次程序最重要的便是结构图中的双向链表,在每个下一级的类中,存放着上一级的类,如图:

在这个账户类中,不仅有着卡类的链表,还有这账户所隶属于银行、用户的对象,找到该账户后,即可通过getter方法直接找到它所隶属的银行和用户,大大减少了查找时间。
这次实验我把存取款和查询余额的方法变成了一个实物类,符合了单一原则,不像上次程序,要改变代码才能增加新的功能,这样设计方便我们以后再次增加新的功能而不用改变原来写好的类,可以直接加上新的类。这次题目集的重点在于对程序的结构进行了重构,使得程序更加符合设计要求。
三、踩坑心得
由于前面大量的时间练习,现在我在编写程序时考虑问题逐渐变得很全面,所以在错误方面逐渐减少。在本月代码编写过程中,由于第七次题目集的类图是已经给出了的,所以该次题目集在编写过程中没有过多问题,按照老师给出的类图一步一步编写下来,思考老师为什么要这么设计,最后提交时只有轻微的格式错误,修改输出格式后便没有了问题。而题目集八和九却没有任何的类图和提示,刚开始老师给出了一种分级设计的思想,我按照该思想一步一步编写下去,遇到了一些有关设计上的问题,比如:输入数据的判断方法应该放在哪一个类中,其实最开始我是放在操作类中,在第八次程序中体现的很完全,但是后来的程序编写时,老师给的样例带给了我启发,我把他们全部放在了一个判断类中,使用静态方法进行设计,从而我每个类都可以直接使用这些静态方法,从而判断输入。其次,设计中最难思考的问题在于继承和组合上,到底对于账户类的不同类型,是使用组合好还是继承好,最后考虑到这是两种卡,拥有着不同的属性。所以不同类型还是使用继承好一点。在语法上的错误几乎没有了。
四、改进建议
在题目集八中改进的部分就是类的设计上,我认为还是应该把存取款、查询余额都单独拿出来,作为一个业务类,这样会大大方便我们进行扩展,对于从属关系上,用户确实不应该和银行直接联系起来,毕竟在实际上用户和银行独立存在的。这些在题目集九中已经改进了大部分,但是在题目集九中,还是存在着好多问题,其中取款的操作可以不用继承,依旧使用一种综合的取款方式,就是先算出手续费和取款金额,然后直接取款,毕竟在这之前会判断能否取款成功的。对于其他的改进现阶段没有什么能想到的了。
五、总结
对于本月题目集,学会最多的就是关于程序设计的设计要求及设计原则的运用,其中,运用最多的便是单一原则和开闭原则,在这三次题目集中,这两个原则都运用的很多,其次,则是类的继承和多态,继承则包括了接口继承和实体类继承,在题目集七中,明显的运用了继承和多态,对于许多有着相同属性的类,可以创建一个父类,通过继承,重写,生成一个一个单独的子类,在程序中使用父类的引用和子类的对象可以使得程序更加的灵活多变,利于维护修改。题目集八则是对于我们设计技术的运用,在该次题目集中,虽然程序在设计上存在很大问题,可通过老师的讲解,使我对程序设计上的结构更为的清楚,更深的理解了单一原则和开闭原则,也让我知道遵循开闭原则设计的程序在扩展上有着巨大的优势。 在基础语法上面,这三次题目集首先是接口comparable的使用,可以改写里面的conpareTo方法从而改写sort方法。对于子类自己所拥有的属性方法,父类无法调用,可以强制类型转换来调用它,只是该对象一定是子类的对象。判断子类的对象也可以使用instanceof 关键字来进行判断,从而判断该引用的对象是属于哪一个子类的。
总的来说,三次题目集给我最大的收获还是在程序设计思想上吧。

浙公网安备 33010602011771号