一.前言
题目集8~9都只有三道题,基本上都是继承与多态、再重构拓展等的要求,题目量不多,考察的知识点还是有点难度的但只要认真思考学习方法还是可以写出来的。
题目集8知识点:在点线面问题重构(继承与多态)题目中涉及继承(子类继承父类的属性和方法,实现代码复用),定义一个父类,点、线、面相关类作为子类继承父类,子类可拥有父类的通用属性(如颜色等 )和方法,并可重写或扩展;多态(同一操作作用于不同对象,会产生不同的执行结果),在点线面问题中,可定义统一的抽象方法,不同子类对象调用该方法呈现不同行为。在雨刷程序功能扩展设计中涉及类的设计与封装(将雨刷相关功能如速度控制、启停等封装到类中,通过类的属性和方法实现对雨刷状态和行为的管理)和接口与抽象类。航空货运管理系统(类设计)中涉及类的设计与关系(设计各类实体类如货物类、航班类等,并且运用面向对象思想合理划分职责)。
题目集9知识点:魔方问题涉及面向对象编程基础中的类的定义与属性{需要定义 RubikCube 类以及它的两个子类 SquareCube(正方体魔方)和 RegularPyramidCube(正三棱锥魔方)},并在类中定义颜色、阶数等属性;同时还有子类父类的继承与多态。点线面问题再重构(容器类)涉及容器类的使用:Java 中的容器类如 ArrayList 等,比如用 ArrayList 存储多个点对象,方便进行添加、删除、遍历等操作;还有面向对象的重构:基于容器类对原有的点线面类结构进行重构,进一步优化代码结构,提高代码的复用性和可维护性。航空货运管理系统也是继承与多态。
二.设计与分析
1.题目集8的航空货运管理系统
- 题目:
航空快递以速度快、安全性高成为急件或贵重物品的首选。本题目要求对航空货运管理系统进行类设计。本次题目模拟某客户到该航空公司办理一次货运业务的过程:
航空公司提供如下信息:
航班信息(航班号,航班起飞机场所在城市,航班降落机场所在城市,航班
日期,航班最大载重量)
客户填写货运订单并进行支付,需要提供如下信息:
客户信息(姓名,电话号码等)
货物信息(货物名称,货物包装长、宽、高尺寸,货物重量等)
运送信息(发件人姓名、电话、地址,收件人姓名、电话、地址,所选
航班号,订单日期)
支付方式(支付宝支付、微信支付)
注:一个货运订单可以运送多件货物,每件货物均需要根据重量及费率单独
计费。
程序需要从键盘依次输入填写订单需要提供的信息,然后分别生成订单信
息报表及货物明细报表。
输入:客户编号
客户姓名
客户电话
客户地址
运送货物数量
[货物编号
货物名称
货物宽度
货物长度
货物高度
货物重量
]//[]内的内容输入次数取决于“运送货物数量”,输入不包含“[]”
航班号
航班起飞机场
航班降落机场
航班日期(格式为YYYY-MM-DD)
航班最大载重量
订单编号
订单日期(格式为YYYY-MM-DD)
发件人地址
发件人姓名
发件人电话
收件人地址
收件人姓名
收件人电话
-
题目分析:本题的航空题不难的,主要就是分清楚需要哪些类,把什么东西放进哪个类里就差不多能做出来了。但是要注意一些细节,比如计费重量到底是实际重量还是体积重量,同时还需要考虑题目重点考核的是面向对象设计原则中的单一职责原则、里氏代换原则、开闭原则以及合成复用原则,然后按要求设计代码即可。
-
类图

本类图设计了实体及属性:订单类属性包括 orderId、OrderDate、sendAddress、sendName、sendPhone、receiveAddress、receiveName、receivePhone,均为可变字符类型;物品类:属性有 id、name,width、length、height、weight;客户类:属性包含 id、name,phone、address、number;航班类:属性有 id、planestrat、planesend、planedate,maxweight。他们之间的实体关系是:订单与客户:多对一关系,即多个订单可对应一个客户 ;订单与物品:一对多关系,一个订单可包含多个物品 ;物品与航班:一对多关系,一个航班可运输多个物品 。
- SourceMontor生成报表

该图共384行,含196条语句,分支语句15条,方法调用语句5条,注释行占比仅4.2% ,代码可读性欠佳。文件定义了2个类和接口,平均每个类有40.5个方法,每个方法平均2.27 条语句。最复杂方法为Main.main() ,位于第5行,复杂度为4 ,含42条语句,最大深度3 ,调用37次。文件最大复杂度为4 ,最深代码块在第20行,最大块深度3 ,平均块深度0.87 ,平均复杂度4 。雷达图展示了各度量维度情况,柱状图表明代码块深度集中在0 - 2 ,语句数较多,深度 3 及以上语句数大幅减少 。 整体而言,该文件代码注释稀缺,类与方法数量较多,主方法复杂度高,代码结构和可读性有优化空间。
2.题目集9的航空货运管理系统
- 题目:
航空快递以速度快、安全性高成为急件或贵重物品的首选。本题目要求对航空货运管理系统进行类设计,具体说明参看说明文件。本次题目模拟某客户到该航空公司办理一次货运业务的过程:航空公司提供如下信息:
航班信息(航班号,航班起飞机场,航班降落机场,航班日期,航班最大载重量)
客户填写货运订单并进行支付,需要提供如下信息:
客户信息(姓名,电话号码等)
货物信息(货物名称,货物包装长、宽、高尺寸,货物重量等)
运送信息(发件人姓名、电话、地址,收件人姓名、电话、地址,所选
航班号,订单日期)
支付方式(支付宝支付、微信支付、现金支付)
注:一个货运订单可以运送多件货物,每件货物均需要根据重量及费率单独
计费。
程序需要从键盘依次输入填写订单需要提供的信息,然后分别生成订单信
息报表及货物明细报表。
输入格式:
按如下顺序分别输入客户信息、货物信息、航班信息以及订单信息。
客户类型[可输入项:Individual/Corporate]
客户编号
客户姓名
客户电话
客户地址
货物类型[可输入项:Normal/Expedite/Dangerous]
运送货物数量
[货物编号
货物名称
货物宽度
货物长度
货物高度
货物重量
]//[]内的内容输入次数取决于“运送货物数量”,输入不包含“[]”
航班号
航班起飞机场
航班降落机场
航班日期(格式为YYYY-MM-DD)
航班最大载重量
订单编号
订单日期(格式为YYYY-MM-DD)
发件人地址
发件人姓名
发件人电话
收件人地址
收件人姓名
收件人电话
支付方式[可输入项:Wechat/ALiPay/Cash]
输出格式:
如果订单中货物重量超过航班剩余载重量,程序输出The flight with flight number:航班号 has exceeded its load capacity and cannot carry the order. ,程序终止运行。
如果航班载重量可以承接该订单,输出如下:
客户:姓名(电话)订单信息如下:
航班号:
订单号:
订单日期:
发件人姓名:
发件人电话:
发件人地址:
收件人姓名:
收件人电话:
收件人地址:
订单总重量(kg):
[微信/支付宝/现金]支付金额:
货物明细如下:
明细编号 货物名称 计费重量 计费费率 应交运费
1 ...
2 ...
注:输出中实型数均保留1位小数。
-
题目分析:本题的航空类迭代题也不难,输入上多了选择客户类型、货物类型和支付方式。客户类型分为个人和集团,可分别享受9折和8折的优惠。货物类型决定着基础运费的费率大小。
-
类图

这张类图围绕航空货运管理系统展开设计。包含运输工具抽象类 Transport 及子类 Plane ,订单类 Order 、客户类 Customer 、物品类 Goods 、业务计算类 BusinessCalculator 、输出显示类 OutputDisplayer 以及主类 Main 。类间存在继承(Plane 继承 Transport )和关联(如 Order 关联 Customer、Goods、Transport 等 )关系。各有属性与方法,涵盖业务计算、信息展示等功能,Main 类为程序入口,共同构建系统架构
- SourceMontor生成报表

表图文件可看出代码共503行,含322条语句,分支语句占16.5%,方法调用语句46条,注释行仅占5.6% 。有2个类和接口,平均每个类52.50个方法,每个方法平均2.95条语句 。最复杂方法是Main.main() ,位于第 5 行,复杂度4, 含45条语句,最大深度3 ,调用45次 。文件最大复杂度4 ,最深代码块在318行,最大块深度1.64 ,平均块深度1.64 ,平均复杂度4.00 。雷达图和柱状图分别展示了代码在各维度的表现及不同代码块深度的语句分布情况。整体来看,该文件存在注释少、部分方法复杂、类的方法过多等问题,可维护性和可读性欠佳。
三.踩坑心得
①分析题目,给出类图
我开始做航空货物题的时候只有几个类,没有把货物,订单,客户分开各位一类,所以开始按照这种思路写的时候很满,一个类里有很多属性,到后面发现这样写结构思路太不清晰了,之后就重新划分了类及其属性方法,便于给出代码思路。
②遵循Java规则,注重细节
我在调试过程中总是遇到编译错误,如图。由于每个类都有很多属性,有Id,name等等相似的属性,我时不时搞混他们的含义,因此我们在给属性命名时用遵循命名规范,比如货物名称z则会命名为goodName,这样便于管理理解,不会因为类太多而搞混。此外,在这个过程中我们还需要实例化对象,由于每个类的参数很多,就可能会遗落一些参数,导致传递给构造器的参数与构造器定义的参数不匹配,因此我们需要细心一点,仔细对照参数个数,确保实际参数列表和形式参数列表长度相匹配。

③注意消耗多余换行符
在我使用Scanner类输入并且输入内容较多时,可能会导致Scanner 输入混淆,因为Scanner 类读取输入时,不同读取方法对换行符处理不同。像nextInt(),nextDouble()等方法读取到空格或换行符就会停止读取,但换行符会留在输入缓冲区。如果后续紧接着使用nextLine()方法读取字符串,不消耗缓冲区的换行符,nextLine() 会直接读取到这个换行符,把它当作输入内容,导致获取的字符串为空或不是预期值 。所以我很多次都提示答案错误并且测试用例时也得不到正确答案。
④记得导入合适的包
Java提供了丰富的类库,像java.util 包下有集合类(ArrayList、HashMap 等 )、工具类(Collections ),java.io 包用于输入输出操作等。当你需要使用这些包中的类时,就必须导入对应的包,否则编译器无法识别这些类。在这两题中,我们使用到了ArrayList和List来储存数据,因此需要导入import java.util.ArrayList;和import java.util.List;才能使用里面的类。如果不导入 java.util.ArrayList ,代码中使用 ArrayList 就会报错,提示找不到该类。
四.改进建议
总结SourceMontor生成报表:
1.增加注释
我的代码可读性较低,注释行占比仅 5.6% ,严重不足。应在关键代码段、方法定义(说明方法功能、参数含义、返回值意义 )、类定义(阐述类的职责 )添加注释。比如在一些计算逻辑的方法中,添加注释解释计算原理和用途,方便自己和他人理解代码。
2.拆分复杂方法
在第九次题目里Main.main() 方法复杂度为4 ,含45条语句且调用40次,功能可能过于集中。可将其中不同功能逻辑抽取出来,封装成独立方法,降低单个方法的复杂度。例如,若 main 方法中包含数据读取、业务计算、结果输出等多部分逻辑,可分别拆分为 readData()、calculateBusiness()、displayResult() 等方法。
3.优化类的职责
航空货物系统中代码平均每个类有52.50个方法,可能导致类的职责不单一。遵循单一职责原则,对类进行重构,将相关功能聚合到一起,不相关功能拆分到新类,这样可动态管理代码。
五.总结
1.收获
在这两次题目集中,加强了我分析题目的能力,能够清晰的划分类和各部分职责了。点与面的题目进行迭代训练,考察继承与多态,能够基本上掌握抽象父类与子类之间的关系及其方法调用,并且在继承关系中,创建的对象是子类不是父类。同时也运用到了容器类ArrayList和List等等来创建链表,存储数据,学会了用for-each增强循环来历遍链表。
2.改进
通过这两次题目集,我发现个人的划分类和分析类间关系能力还不强,类的结构不够清晰简单,太过复杂不利于理解和改进方法代码,给迭代作业增加了难度。此外,我对于抽象父类和子类之间的方法调用还不太熟悉,有点无从下手的感觉。所以我会加强对继承与多态的知识点的学习,掌握抽象类、父类、子类的关系及其知识点;同时还有容器类ArrayList和List的学习,加强联系。
浙公网安备 33010602011771号