面向对象设计与构造——第一单元总结
第一次作业
作业要求:
设计一个基础的航班货运配载模块。系统需要记录航班的基本信息(航班号、最大起飞重量、最大业载重量)。地勤人员可以按照货物重量从高到低向该航班添加货物(货物名称、重量)。系统需要实时计算当前已装载的总重量,并判断是否超载。
前言:
知识点:
1.封装:使用private属性和get/set方法保护数据。
2.方法调用:对象之间通过方法(如addCargo()、getTotalWeight()、getTotalWeight())交互。
3.选择排序:在CargoSorter.sortByWeightDesc()中实现对货物按重量降序排序。
题量:较少。
难度:较低。
实现方式:
- 读取航班信息(航班号和最大载重)以及若干货物信息(名称和重量)。
- 将货物按重量从大到小排序。
- 计算总货物重量。
- 判断是否超载并打印货物清单和状态。
设计与分析:

- Cargo 与 Flight 为数据实体类,只包含属性和 getter/setter。
- CargoSorter 为工具类,提供静态排序方法,依赖于 Cargo 的参数类型。
- LoadManifest 聚合了 Flight(1对1关联)和 Cargo(1对多关联),并在 printManifest() 中调用 CargoSorter,因此两者之间存在 use 依赖。
- Main 作为入口点,创建 Flight、Cargo 和 LoadManifest 对象,与这些类存在依赖关系。
踩坑心得:
第一次作业较简单没啥大问题。
改进建议:
- 选择排序在货物多的情况下效率不够,可以改进使用list.sort()方法。
- 每次调用 getTotalWeight() 都要遍历整个列表累加,可以在 addCargo() 时累加重量,调用时直接返回,这样就能减少重复计算提高效率。
第二次作业
作业要求:
设计一个扩展的航班货运配载模块,实现以下功能:
- 航班信息管理:
记录航班号、最大起飞重量、最大业载重量。 - 货舱管理:
每个货舱有唯一标识(如“前舱”)、最大载重、行数、列数(组成位置网格)。
货舱与其位置是组合关系(CargoCompartment 创建时内部生成 Position 列表)。
货舱与装载的货物是聚合关系(Cargo 可独立存在)。 - 货物装载:
输入所有待装载货物(名称、重量、目标货舱ID)。
系统先按货物重量从高到低排序,再依次尝试将货物装入指定的货舱。
如果目标货舱的当前重量 + 该货物重量 ≤ 该货舱最大载重,则装载成功,否则装载失败并给出提示。 - 输出要求:
按排序后的顺序输出每件货物的装载结果(成功或失败)。
输出每个货舱的已装载总重量及状态(是否超载)。
输出航班整体总重量及与最大起飞重量、最大业载重量的对比,判断整体是否超载。
前言
知识点:
1.封装:使用private属性和get/set方法保护数据。
2.使用ArrayList存储货舱中的Position和Cargo、航班的CargoCompartment列表、所有待装载货物等。
3.使用插入排序(LoadDispatcher.sortCargosByWeightDesc)对货物列表进行排序。
4.通过累加和比较判断总重量是否超出航班承载能力。
题量:中等。
难度:中等
实现方式:
- 读入航班和货舱信息,用 ArrayList 存储每个货舱及其位置。
- 读入货物信息,用 ArrayList 存储货物。
- 按重量降序排序货物后,依次尝试装入目标货舱,累加重量并判断超载,最后输出每件货物的装载结果、货舱状态及航班总重量和配载状态。
设计与分析:

- Position:独立的数据类,表示舱位位置。
- Cargo:货物实体,记录目标货舱 ID(字符串形式关联)。
- CargoCompartment:货舱类,包含位置列表(*-- 组合关系,因为 Position 对象在构造函数中创建且生命周期由货舱管理)和货物列表(o-- 聚合关系,货物从外部添加,可独立存在)。
- Flight:航班类,聚合多个 CargoCompartment。
- LoadDispatcher:工具类(<
>),提供静态排序和查找方法,依赖 Cargo 类型。 - InputValidator:独立验证工具类,无依赖其他领域类。
- Main:入口点,依赖所有类以创建对象和调度流程。
踩坑心得:
这次作业有两个测试点没过去,我事后再次检查了整个代码,认为问题主要在:
- 货舱装载判断没有考虑行列限制,题目要求每个货舱有固定的行列位置网格,当前代码只判断重量,不判断货舱是否还有空余位置,如果货物数量超过位置数,即使重量允许,仍应该装不下。
- 相等重量货物排序问题,同等重量的货物按输入顺序排序,我的代码在 LoadDispatcher.sortCargosByWeightDesc() 中使用的是插入排序(while 循环),比较条件是 cargos.get(j).getWeight() < key.getWeight(),如果两个货物重量相等,插入排序会将后来的货物插到前面,从而破坏原输入顺序,所以我在比较时加上等号判断。
改进意见:
- 多货舱装载调度优化,我的代码每次通过循环查找目标货舱,复杂度 O(n*m),可使用 Map<String, CargoCompartment> 快速定位货舱,复杂度降为 O(n)。
- 可封装一个方法打印货舱或航班信息,避免重复 System.out.printf。
- 我的代码只用 InputValidator 验证整数范围,可增强:验证浮点数范围(重量不能为负数)、验证货舱 ID 和货物目标 ID 是否匹配,避免异常。
第三次作业:
作业要求:
- 系统预设常量(需在计算类中定义为静态常量)
- 引入旅客实体:新增旅客及行李的管理,旅客体重按标准值(75kg)自动计算。
- 引入核心业务算法:新增基于物理力矩的“航空器载重平衡计算”功能。
- 增强鲁棒性要求:在数据录入过程中,要对数据进行合法性验证,如果发现有非法输入,立即停止应用程序运行。
前言:
知识点
1.组合关系:
CargoCompartment 包含多个 Position(组合关系,货舱内部有固定位置网格)。
Flight包含多个CargoCompartment和Passenger聚合关系,航班管理货舱和乘客)。
2.聚合关系:
Passenger聚合Luggage,表示乘客拥有行李,但行李可以独立存在。
3.List 接口使用:接口编程,便于后续扩展或替换集合实现。
4.LoadDispatcher.sortCargosById 使用 冒泡排序 对货物按 ID 排序,双层循环比较相邻元素,按升序交换。
题量:大。
难度:高。
实现方法:
读入航班、货舱、乘客和货物信息,使用 ArrayList 存储乘客和货物,按 ID 排序货物后依次装入货舱,累加重量并计算总力矩和重心,最后输出载重平衡舱单和配平安全评估。
设计与分析:

实体类:Position、Cargo、Luggage 为纯数据对象。
- 乘客与行李:Passenger 与 Luggage 是组合关系(黑色菱形),行李随乘客创建且不外露。
- 货舱与位置:CargoCompartment 与 Position 是组合关系,位置在构造时批量生成,生命周期与货舱绑定。
- 货舱与货物:CargoCompartment 与 Cargo 是聚合关系(白色菱形),货物由外部创建并传入,可独立存在。
- 航班与子组件:Flight 分别聚合 CargoCompartment 和 Passenger。
工具类: - LoadDispatcher:提供静态排序方法,依赖 Cargo。
- WeightBalanceCalculator:重心计算工具,包含静态常量、静态方法,并定义了内部类 BalanceResult,两者为创建依赖关系。
- InputValidator:输入校验工具,依赖 Scanner(外部类)。
入口点:Main 依赖所有业务类,完成组装与流程调度。
踩坑心得:
- 因为忽略了相同情况下的排序而导致排序输出发生错误,所以改成按id排序之后就解决了。
- 因为没考虑到件事的要求,而导致前舱不足的会自动排到后舱而导致后舱出现问题而没发生警报,关键改动在main末尾的装载循环:先按id排序,然后逐件检查当前载重+新货物重量是否超过最大值。如果超过,就在装入这件货物之前输出警告,此时 getCurrentWeight() 还是装入前的累计值。
改进意见:
- CargoCompartment.addCargo() 直接累加重量,不返回是否超载给调用者处理,对于超载直接打印错误并退出,改进方法:修改 addCargo()返回boolean,表示装载是否成功,由调用者决定处理方式。
- LoadDispatcher.sortCargosById() 使用冒泡排序,效率低,且可读性差,改进方法:使用 Java 内置排序。
总结:
- 本阶段通过三次作业的航班货物配载代码,我掌握了面向对象建模、集合管理、排序、重量和重心计算、输入校验、格式化输出等核心技能;同时理解了SRP 和类之间组合/聚合关系的设计思想。
- 需要进一步提升的地方包括异常处理、浮点精度管理、算法优化、可扩展设计、单元测试和可视化,这些都是实际航班配载系统开发中非常重要的知识点。

浙公网安备 33010602011771号