一、前言
第 8 次题目集围绕基础编程与功能拓展展开。第一题 “点线面重构” 作为基础题型,核心在于严格遵循题目给定的类图进行代码实现,将类图中的类、属性及关系精准转化为代码。实际操作中,主函数的设计是关键,需合理完成各类对象的创建、存储以及结果输出。第二题 “雨刷程序功能扩展设计”,在原有功能基础上新增雨刷,要求运用接口和抽象类进行设计,考验对面向对象设计原则的理解与运用,通过抽象共性行为、定义接口规范,实现代码的扩展性与可维护性。第三题 “航空货运管理系统”,虽然输入信息繁杂,涵盖客户、货物、航班等多方面内容,但计算逻辑清晰,重点在于将业务流程转化为代码逻辑,实现运费计算与订单信息处理功能。
第 9 次题目集进一步深化面向对象编程的应用。第一题需深入理解类图中各类的含义与关系,精准把握类的职责与交互逻辑,是对类图解读能力的直接考察。第二题 “容器类与泛型”,重点在于掌握容器类的使用及泛型特性,通过泛型实现类型安全,同时实现容器的增删遍历等操作,提升数据管理的灵活性与效率。第三题则是对第 8 次题目集航空货运管理系统的拓展,引入不同类型的货物与客户类型,增加了费率计算的复杂性,需要在原有代码基础上,结合新的业务规则进行功能扩展,全面考查代码的扩展性和对复杂业务逻辑的处理能力 。
二、设计与分析
- 第八次题目集
1.点线面问题重构
这道题把将Point类和Line类作为Element类的子类,将Element设置为抽象类,重写display() 方法,主函数中调用
// 使用 Element 引用实现多态
Element element;
element = p1;//起点Point
element.display();
System.out.println();
element = p2;//终点Point
element.display();
System.out.println();
element = line;//线段
element.display();
element = plane;//面
element.display();
- 用父类引用统一管理子类对象,代码简洁。
- 支持后续新增子类(如
Circle),无需修改遍历逻辑。
2.雨刷重构的设计:
这道题一开始并没有写的很顺畅,我觉得我的代码的复杂度很高这道题用switch来直接选择速度会更好一点,我是用的数组,因为两个表的间歇档位的档位数量不同,所以数组大小也不同。把Agent抽象出来,重写了两个方法
// 定义 Agent 接口
interface Agent {
void dealSpeed();
void show(String operationType);
}
3.航空货运管理系统
题目说明:
https://images.ptausercontent.com/499d204b-fcef-4610-a9ca-c8fbf5e346d9.pdf
本次题目模拟某客户到该航空公司办理一次货运业务的过程:
航空公司提供如下信息:
航班信息(航班号,航班起飞机场所在城市,航班降落机场所在城市,航班
日期,航班最大载重量)
客户填写货运订单并进行支付,需要提供如下信息:
客户信息(姓名,电话号码等)
货物信息(货物名称,货物包装长、宽、高尺寸,货物重量等)
运送信息(发件人姓名、电话、地址,收件人姓名、电话、地址,所选航班号,订单日期)
支付方式(支付宝支付、微信支付)
注:一个货运订单可以运送多件货物,每件货物均需要根据重量及费率单独计费。
程序需要从键盘依次输入填写订单需要提供的信息,然后分别生成订单信息报表及货物明细报表
这道题目我把运输类定义为父类Trans,order类整合所有的信息,
// 订单类(整合所有信息)
class Order extends Trans {
private String orderId;
private Customer customer;
private List<Cargo> cargoList;
private Flight flight;
public Order(String orderId, String orderDate, Customer customer,
List<Cargo> cargoList, Flight flight, Trans transInfo) {
super(transInfo.getSenderName(), transInfo.getSenderPhone(), transInfo.getSenderAddress(),
transInfo.getReceiverName(), transInfo.getReceiverPhone(), transInfo.getReceiverAddress(),
transInfo.getFlightNum(), transInfo.getOrderDate());
this.orderId = orderId;
this.customer = customer;
this.cargoList = cargoList;
this.flight = flight;
}
// Getter 方法
public String getOrderId() {
return orderId;
}
public Customer getCustomer() {
return customer;
}
public List<Cargo> getCargoList() {
return cargoList;
}
public Flight getFlight() {
return flight;
}
}
这个货物运费加和时运用的方法有点高级,我们可以换成下一种
return cargoList.stream() // 将列表转换为Stream流
.mapToDouble(Cargo::cal_Money) // 映射每个货物到其费用
.sum(); // 累加所有费用
private static double calculateTotalCost(List<Cargo> cargoList) {
double total = 0.0;
for (int i = 0; i < cargoList.size(); i++) {
Cargo cargo = cargoList.get(i);
total += cargo.cal_Money(); // 累加单件费用
}
return total;
}
![]()
![]()
- 代码行数(Lines):465
- 语句数量(Statements):134
- 代码结构相关(Percent Branch Statements):分支语句所占百分比,为 0.0% ,反映代码中使用如if - else 、switch等分支结构的比例情况。
- 方法调用语句数量(Method Call Statements):8
- 含注释的代码行所占百分比(Percent Lines with Comments):1.9%
- 类和接口的数量(Classes and Interfaces):4
- 平均每个类的方法数(Methods per Class):13.50
- 平均每个方法的语句数(Average Statements per Method): 2.26
- 最复杂方法所在的行号(Line Number of Most Complex Method): 103
- 最复杂方法的名称(Name of Most Complex Method):Normal
- 最大复杂度(Maximum Complexity): 1
//衡量方法逻辑复杂程度,数值越高逻辑越复杂
平均复杂度(Average Complexity):1.0
类图:
![]()
分析:
面向对象设计思想明确
-
- 代码通过多个类(
Trans、Cargo、Customer、Flight、Order)封装不同领域的概念,符合单一职责原则。
- 使用继承(如
NormalCargo继承Cargo)和接口(PaymentMethod)实现多态,例如支付方式可扩展(支付宝、微信支付),符合开闭原则。
模块化结构清晰
-
- 类职责划分明确:
Trans负责运输信息,Cargo处理货物计算,Flight管理航班信息,Order整合所有数据。
PaymentMethod接口分离支付逻辑,便于后续扩展其他支付方式(如银联支付)。
数据校验与业务逻辑分离
-
- 在
main方法中检查货物总重量是否超过航班载重,逻辑清晰,避免业务逻辑混入类内部。
代码复用性较好
-
Cargo类的calWeight和cal_Money方法可被所有子类继承,减少重复代码。
calculateTotalCost静态方法复用货物费用计算逻辑。
第九次习题集
1.魔方问题:
类图:
![]()
弄明白一个类是每一块体积,下面的类是整个的魔方体积
2.点线面问题的重构
主要是多加了一个容器类和主函数的变化
3.航空货运管理系统
https://images.ptausercontent.com/b9cec79b-8012-4901-843e-3d48f27d28a6.pdf
![]()
![]()
- 代码行数(Lines):516
- 语句数量(Statements):214
- 代码结构相关(Percent Branch Statements):分支语句所占百分比,为 2.3% ,反映代码中使用如if - else 、switch等分支结构的比例情况。
- 方法调用语句数量(Method Call Statements):45
- 含注释的代码行所占百分比(Percent Lines with Comments):9.1%
- 类和接口的数量(Classes and Interfaces):9
- 平均每个类的方法数(Methods per Class):6.22
- 平均每个方法的语句数(Average Statements per Method): 1.43
- 最复杂方法所在的行号(Line Number of Most Complex Method): 16
- 最复杂方法的名称(Name of Most Complex Method):ALiPay
- 最大复杂度(Maximum Complexity): 1
//衡量方法逻辑复杂程度,数值越高逻辑越复杂
类图:
![]()
三、踩坑心得
航空货运系统主要是添加了不同的货物类,客户类
![]()
我定义了三种不同货物的子类 ,Normal/Expedite/Dangerous,重写费率和运费方法,定义了两种客户类型Individual/Corporate,加上获取折扣率的方法,因为继承客户类,直接在Order订单类中直接 * customer.getDiscountRate();算出单件运费,货物类相同
主要是在考虑主函数如何输入,如何创建对象
Customer customer;
if ("Individual".equals(kind)) {
customer = new individualCustomer(customerId, customerName, customerPhone, customerAddress);
} else if ("Corporate".equals(kind)) {
customer = new corporateCostomers(customerId, customerName, customerPhone, customerAddress);
} else {
customer = new Customer(customerId, customerName, customerPhone, customerAddress);
}
//---------------------------------------------------------------------
// 根据货物类型创建对应实例(修复构造函数调用)
switch (kindCargo) {
case "Normal":
cargoList.add(new NormalCargo(id, name, length, width, height, weight));
break;
case "Expedite":
cargoList.add(new ExpediteCargo(id, name, length, width, height, weight));
break;
case "Dangerous":
cargoList.add(new DangerousCargo(id, name, length, width, height, weight));
break;
default:
throw new IllegalArgumentException("无效的货物类型");
}
}
另外在提交之后发现答案错误,
最后发现是在表格中的实际重量打印成了质量重量,把getWeight();改成calWeight();之后答案正确
四、改进建议
代码中注释含量明显较少,可能需要添加更为详细的代码注释,Order 类职责过多,拆分计算费用的逻辑到单独的服务类。可以将 Customer 改为接口或抽象类,让 Order 依赖抽象而非具体类;使用组合代替继承(Order 和 Trans 的关系)。抽象接口(ICustomer、PaymentMethod)的使用降低高层模块对具体类的依赖。
五、总结
通过这两次题目集的实践,我系统掌握了面向对象编程的核心思想与设计原则。在类的设计上,接口(如PaymentMethod)规范行为,通过继承与多态实现代码复用(如不同货物类型的运费计算)。理解了单一职责原则的重要性,例如将Order的职责拆分为数据存储与费用计算,提升代码内聚性。 深刻体会开闭原则“对扩展开放、对修改封闭”的优势。同时,通过输入校验、重量超限检查等细节,增强了代码健壮性意识。 此外,认识到命名规范、注释完整性对代码可读性的影响,以及组合优于继承的设计原则(如`Order`与`Trans`的关系)。