oop前三次作业总结
前言
这是我第一次写博客,也是第一次接触Java。在没学Java之前,我只接触过C语言,因此在完成作业时总将Java面向对象的特性抛到一旁,用一个类从头写到尾,这个坏毛病在第一次作业里完美体现(笑)。
关于Java:在深入这门课前,我在网上经常看见人说Java多么多么难学,使得我对它一直有一种敬畏之情,然而,在学习一段时间后,我只能说:确实如此(是不是以为我会反驳)。如果说C语言给我的感觉是”行就是行,不行就是不行“,那Java就给我一种“虽然我写不出来,但已经弄懂了”的错觉。
经历了这三次作业的拷打后,我还是学到很多东西的,至少不会一个类走天下了。这三次作业涵盖的知识点还是很全面的。这三次作业的最后一题是层层递进的,难度和复杂度不断上升,这次博客也将着重讲这三道题。
第一次作业
这一次作业就是教我们怎么设计类,题量也不多,最需要注意的是最后一题,主要考察正则表达式的使用与类的设计。
第二次作业
这一次作业在第一次的基础上加了一些新知识点,比如链表,接口等,上网查一下资料就能弄懂。最后一题的正则表达式更复杂了,是第一次的升级版。
第三次作业
这一次就开始上强度了,虽然只有三道题,但题题直击要害,第一题考察封装性,没什么好说的,第二题的工程量就涨上来了,哪怕用了很多新东西还是写了好多,但难度也不大,第三题在之前的难度上更进一步,大量的正则表达式和类的使用搞得我头大,好不容易写完主体,后面的测试点又花了大量时间调试(最后一个测试点直接卡了我两天!)。
设计与分析
这里主要分析有代表性的题目,一些一遍过的就不分析了。
第一次PTA
7-5 答题判题程序-1:
设计
题目类(Question):用于保存一道题目的信息。
private int no;//题号
private String content;//题目内容
private String standardAnswer;//标准答案
答卷类(Answer):保存一张答卷的信息
private String answer;//答案
试卷类(Test):保存和处理一张试卷的信息以及处理的方法
private int num=0;//题目数量
private Question[] question=new Question[100];//题目
private Answer[] answers=new Answer[100];//答案
public void check();//输出题目、答案和判定结果
SourceMontor报表如下:
图中的数据信息如下:(大佬可以跳过了)
-
Lines: 指的是代码总行数
-
Statements:语句的行数,语句是以分号结尾的。这个C中有所不同。
-
Percent Branch Statement:分支数占总语句数的百分比
-
Method Call Statement:方法调用语句数
-
Percent Lines with Comments:注释语句占总语句数的百分比
-
Classes and Interfaces:类和接口数
-
Methods per Class:每个类平均包含函数个数
-
Average Statements per Method:每个函数平均包含的语句个数
函数复杂度(Function Complexity)复杂度指1个函数可履行路径的数目,以下语句为复杂度的值贡献1:if/else/for/while语句,3元运算符语句,if/for/while判断条件中的"&&"或“||”,switch语句,后接break/goto/ return/throw/continue语句的case语句,catch/except语句等。对应有最大复杂度(Max Complexity)和平均复杂度(Avg Complexity)。
函数深度(Block Depth):函数深度是函数中分支嵌套的层数。对应有最大深度(Max Depth)和平均深度(Avg Depth)。
- Line Number of Complex Method:最复杂函数的行号(最复杂指的是McCabe复杂度值为最高)
- Maximum Complexity:该类中最复杂函数的复杂度(最复杂指的是McCabe复杂度值为最高)
- Line Number of Deepest Block:最深层语句块的行号
类图如下:
分析
这道题可以说是梦开始的地方,主要通过问题类、答卷类和批改类解决,一上来就考察了正则表达式,类的设计等知识点,对我一个初学者很不友好。从SourceMontor报表可以看出,我将正则表达式和信息的存入功能全部放在主类中(学C语言养成的坏习惯),导致主类的平均复杂度奇高,同时类与类之间的关系也设计的不行。
采坑心得
虽然题目中没有提到,但在测试点中输入时在很多地方存在大量的空格,需要使用正则表达式或replace将空格消去。
同时还需要注意题目和答案的对应顺序。
改进建议
应该将正则表达式的匹配单独设计成一个类,同时将数据存入类中的过程也单独设计成一个类,此外,还可以简化化正则表达式,优化类与类之间的关系。
第二次PTA
7-4 答题判题程序-2
设计
题目类(Question):用于保存一道题目的信息。
private int no;//题号
private String content;//题目内容
private String standardAnswer;//标准答案
答卷类(Answer):保存一张答卷的信息
private int number;//答卷编号
private int sum;//答案数量
public String[] answer=new String[20];//答案
public boolean[] flag=new boolean[20];//答案对错
试卷类(Paper):保存和处理一张试卷的信息以及处理的方法
private int number;//试卷编号
private int sum;//题目数量
public int[] no=new int[20];//题目编号
public int[] grade=new int[20];//题目得分
public void zongfen();//判定总分是否为100
SourceMontor报表如下:
类图如下:
分析
在第一次作业的基础上,又增加了试卷类,即要对多张试卷进行批改,同时还有乱序输入,导致之前的程序无法完成这些功能,于是我重新设计程序,将问题类先储存到一个链表中,再封装到试卷类中,这样就能达到试卷与答卷一一对应的效果。
采坑心得
这道题并没有很多的坑,唯一要注意的是在用数组储存数据时建议使用动态数组或将数组大小定义地大一点,防止非零返回。
改进建议
这次作业中还添加了答案缺失的测试点和统分功能,每一张试卷,答卷和批改都要一一对应,因此建议用链表来储存问题,用数组来储存试卷和答案。
此外,由于类的逐渐增多,类与类之间的关系也越来越复杂,很容易让类之间粘合在一起,建议多使用代理类处理信息。
第三次PTA
7-2 jmu-java-日期类的基本使用
设计
日期类(Date):用于保存日期和处理信息。
private int year;//年
private int month;//月
private int day;//日
private boolean flag=false;//日期是否合法
private int[] x={0,31,28,31,30,31,30,31,31,30,31,30,31};//日历
public boolean lunnian();//判断闰年
public boolean check();//检查日期是否合法
public int xyear();//计算该日期是当年第几天
public int xmonth();//计算该日期是当月第几天
public int xweek();//计算该日期是当周第几天
public void print();//输出信息
SourceMontor报表如下:
类图如下:
分析
这道题主要考察包的调用,虽然一个日期类就能解决问题,但其中含有许多的方法,比如判断闰年、检查日期是否合法、计算相差天数等,如果一个一个写要花费大量时间,于是可以通过调用LocalDate、DayOfWeek等来简化代码。
采坑心得
一定要注意输入日期的格式一定要符合"YYYY-MM-dd",否则就要输出日期不合法,同时要考虑如果开始日期和结束日期相同时的输出,找到临界点。
改进建议
这道题并没有复杂的类设计,只需要一个日期类就够了,但方法很多,尤其在计算日期相差的天数时,又要考虑闰年,又要考虑二月特殊情况,因此可以先将每个月的天数设计成一个数组,在计算时只需相加就行了。一些计算日期天数的方法可以直接调用其他包中的方法,可以节省很多的时间。
7-3 答题判题程序-3
设计
题目类(Question):用于保存一道题目的信息。
private boolean flag;//题目是否删除
private int no;//题号
private String content;//题目内容
private String standardAnswer;//标准答案
答卷类(Answer):保存一张答卷的信息
private int number;//答卷编号
private int sum;//答案数量
public boolean[] flag=new boolean[100];//题目是否删除
public String[] answer=new String[20];//答案
public boolean[] flag=new boolean[20];//答案对错
学生类(Student):保存学生的信息
private String no;//学号
private String name;//姓名
试卷类(Paper):保存和处理一张试卷的信息以及处理的方法
private int number;//试卷编号
private int sum;//题目数量
public boolean[] flag=new boolean[100];//题目是否删除
public int[] no=new int[20];//题目编号
public int[] grade=new int[20];//题目得分
public void zongfen();//判定总分是否为100
处理类(Test):保存和处理一张答卷的信息以及处理的方法
private Student students;
private LinkedList<Question> questions;
private Paper papers;
private Answer answers;
public void check();//对答卷进行批改并输出信息
public void tongfen();//输出得分并统计输出
SourceMontor报表如下:
类图如下:
分析
这道题是这三次作业中最难的题了,首先在类的设计上就搞得头晕脑胀,光是必须的类就有六七个,还需要匹配、批改、统分等方法,但最难的是对多组试卷、答卷信息的处理,一不小心就容易匹配错误,我也是在写的过程中发现的,于是只好不断调试加新东西,导致代码的结构十分冗杂,从我的平均复杂度也可以看出。
采坑心得
与前一次作业相比,这次有增加了学生类和删除功能,类的总体设计没有太大变化。
这道题有整整28个测试点,前9个就是测试样例,中间几个也都是正常测试,但坑就在最后6个测试点中,首先一定要注意答卷中的序号是与题目在试卷中的位置对应的,而不是与题目编号对应,同时批改时是按照试卷中题目的顺序批改,而不是按回答问题的顺序。比如以下案例:
输出结果应为:
改进建议
由于复杂的信息乱序输出,如果将在批改或输出时再匹配就要使用大量if语句处理信息,增加代码复杂度,因此可以设计一个匹配类,将试卷与答卷一一匹配,在设计一个test类将对应的试卷和答卷绑定,并完成批改,统分,输出操作。此外,还可以参照之前的建议,将功能全部设计成类,降低平均复杂度。
总结
这三次作业的难度循序渐进,同时涵盖了各个方面的知识点。通过这三次练习,我对正则表达式的运用不能说炉火纯青,也是相当熟练了,现在可以在不查资料的情况下写出大部分。
同时我对Java中链表和动态数组的使用也更加熟练,可以根据需求来做出对应的选择。
此外,在处理复杂信息匹配时,我总结出了很多技巧,比如注意信息的顺序、对应关系以及如何避免混淆。同时,我对边界情况和异常情况的处理也变得更加注重,会考虑更多的情况以确保程序的正确性。
最重要的一点是,我对Java面向对象的特点理解更加深刻,再遇到难题时首先会分析类之间的关系和方法的使用,在设计类时,我会将功能模块化、封装成类以提高代码的可读性和可维护性。同时,我会合理地设计类之间的关系,减少代码冗余和重复的部分,不会像之前一样边写边设计,改掉了我的坏毛病。
总的来说,这三次次作业让我受益匪浅,帮助我提升了编程能力和解决问题的能力。在未来的学习和实践中,我会继续加强对类设计、数据结构和算法的理解和应用,不断提升自己的编程技能。同时,我也会更加注重代码的结构和逻辑,避免冗杂和混乱,提高代码的质量和可维护性。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~