面向对象程序设计——作业集总结1

在本随笔中,我将总结PTA中前三次作业集中所做题目后的知识点、题量难度、设计与心得等。

前言

作业集是对于设计航空器配载与货运管理系统进行迭代设计

  在第一次作业中,要想完成该次作业需要具备认识类图、遵循SRP等知识点,严格按照需求进行编写,总体难度偏简单,但由于我暂时未转变到面向对象的思维,使得有一个测试点没过。

  在第二次作业中,由于作业集是迭代性质的,所以需要我在第一次作业的基础上进行升级修改,所需知识点是要清楚的了解认识到UML中类与类之间的关系,比如组合、聚合、关联、依赖,并在原基础上新增两个类,且要体现出类之间关系。经过第一次的作业与一周的训练,我能够较熟练的运用面向对象思维,总体较简单。

  第三次作业是在第二次作业的基础上再次进行迭代,该次作业需要较为扎实的面向对象的思维模式,类的数量来到了将近十个,这无形之中要求我在编写代码时始终记住每一个类设计时存在的关系,以便在主程序组装时减少突然修改类里的方法导致其余类方法出现错误,该次作业较难,不仅在编写方面,还有对测试点的考验,需要考虑到现实中可能会出现的问题。

 

设计与分析

第一次作业

目的:设计一个基础的航班货运配载模块。系统需要记录航班的基本信息(航班号、最大起飞重量、最大业载重量)。

Cargo类:存储货物的相关数据

  private String CargoName;
    private double CargoWeight;

    public Cargo(String CargoName,double CargoWeight){
        this.CargoName=CargoName;
        this.CargoWeight=CargoWeight;
    }
    public String getCargoName(){
        return this.CargoName;
    }
    public double getCargoWeight(){
        return this.CargoWeight;
    }

Flight类:存储航班数据:

  

    private String flightNo;
    private double maxWeight;

    public Flight(String flightNo,double maxWeight){
        this.flightNo=flightNo;
        this.maxWeight=maxWeight;
    }
    public String getFlightNo(){
        return this.flightNo;
    }
    public double getMaxWeight(){
        return this.maxWeight;
    }

 

 

LoadManifest类:用于将货物存入货舱中

    private ArrayList<Cargo> cargoList;

    public LoadManifest(){
        this.cargoList=new ArrayList<>();
    }
    public void addCargo(Cargo cargo){
        cargoList.add(cargo);
    }
    public ArrayList<Cargo> getCargoList(){
        return cargoList;
    }

 

 

CargoSorter类:对货物进行排序,降序输出,这里采用选择排序

    public static ArrayList<Cargo> BubbleSorter(ArrayList<Cargo> CargoList){
        if(CargoList==null||CargoList.size()<=1){
            return CargoList;
        }


        ArrayList<Cargo> SortedList=new ArrayList<Cargo>(CargoList);
        for(int i=0;i<SortedList.size()-1;++i){
            int maxIndex=i;

            for(int j=i+1;j<SortedList.size();++j){
                Cargo max=SortedList.get(maxIndex);
                Cargo current=SortedList.get(j);

                if(max.getCargoWeight()<current.getCargoWeight()){
                    maxIndex=j;
                }
                else if(current.getCargoWeight()==max.getCargoWeight()){
                    if(current.getCargoName().compareTo(max.getCargoName())<0){
                        maxIndex=j;
                    }
                }
            }

            if(maxIndex!=i){
                Cargo temp=SortedList.get(i);
                SortedList.set(i,SortedList.get(maxIndex));
                SortedList.set(maxIndex,temp);
            }
        }

        return SortedList;
    }

 

 

对代码进行分析,有:

 屏幕截图 2026-05-17 235142

可以看到,最大圈复杂度为 4,远低于建议的警戒线(10-20),说明代码逻辑简单清晰,不容易出 bug。平均每个方法有23条语句,属于可接受范围。由于是在PTA中编写,所以在这里我只设立了一个大类Main。

本次我的程序的类图如下:

 

 屏幕截图 2026-05-17 235946

本次作业属于未通过全部测试点的程序,存在问题

 

 

第二次作业

 目的:设计一个航班货运配载模块,尝试 装入货物,防止货舱超重。

在这里仅展现第二次作业新增的类

InputValidtor类:检验输入是否合理

    public boolean CargoCompartmentValidtor(double cargoCurrentWeight,double maxCompartmentWeight){
        if(cargoCurrentWeight>maxCompartmentWeight){
            return false;
        }
        return true;
    }
    
    public boolean TakeoffValidtor(double cargoCurrentWeight,double maxTakeoffWeight){
        if(cargoCurrentWeight>maxTakeoffWeight){
            return false;
        }
        return true;
    }
    public boolean PayloadValidtor(double cargoCurrentWeight,double maxPayloadWeight){
        if(cargoCurrentWeight>maxPayloadWeight){
            return false;
        }
        return true;
    }
    public boolean CountLinesValidtor(int m){
        if(m>5||m<1){
            return false;
        }
        return true;
    }
    public boolean CargoCountValidtor(int n){
        if(n>100||n<1){
            return false;
        }
        return true;
    }

对代码进行分析,有:

屏幕截图 2026-05-18 001723

 

 可以看到最大圈复杂度只有 5,远低于建议的警戒线(10-20),代码逻辑清晰,不容易出 bug。每个方法平均只有 4 条语句,说明方法职责单一,可读性好。但最大嵌套深度为6,说明嵌套较深,可能是在我编写时遗漏了这一点,可稍作修改,将循环嵌套或if-else简化一下。

对应类图为:

屏幕截图 2026-05-18 002332

本次作业无问题,程序可正常运行

 

 

第三次作业

目的:航空器配载与货运管理系统——配平计算,即要与现实搭钩,在装入货物和旅客登机时要注意航班整体的重心是否在正常范围内

在此处仅展示新增类

Luggage类:乘客的行李,主要是记录行李的重量

    private double weight;

    public Luggage(){

    }
    public Luggage(double weight){
        this.weight=weight;
    }
    public void setWeight(double weight){
        this.weight=weight;
    }
    public double getWeight(){
        return this.weight;
    }

 

WeightBalanceCalculate类:纯计算类,用于计算航班的重心位置,总重量,总力矩等

    public static final double FLIGHT_WEIGHT=40000;
    public static final double FLIGHT_WEIGHT_ARM=16.25;
    public static final double PASSENGER_WEIGHT=75;
    public static final double PASSENGER_AVERAGE_ARM=18;
    public static final double[] COMPARTMENT_ARMS={12,22};
    public static final double MAC_LENGTH=5;
    public static final double MAC_DISTANCE=15;

    public static void generateLoadSheet(Flight flight){
        double passengerWeights=0;
        double passengerMoments=0;
        double compartmentWeights=0;
        double compartmentMoments=0;
        double flightTotalWeights=0;
        double flightTotalMoments=0;
        double realCG=0;
        double cgOfMAC=0;
        List<Passenger> passengers=flight.getPassengers();
        List<CargoCompartment> compartments=flight.getCompartments();


        for(Passenger person:passengers){
            passengerWeights+=PASSENGER_WEIGHT;
            passengerWeights+=person.getLuggageWeight();
        }
        passengerMoments=passengerWeights * PASSENGER_AVERAGE_ARM;

        for(int i=0;i<2;++i){
            double CCWeight=compartments.get(i).getCurrentWeight();
            compartmentWeights+=CCWeight;
            compartmentMoments+=CCWeight * COMPARTMENT_ARMS[i];
        }

        flightTotalWeights=FLIGHT_WEIGHT + passengerWeights + compartmentWeights;
        flightTotalMoments=FLIGHT_WEIGHT * FLIGHT_WEIGHT_ARM + passengerMoments + compartmentMoments;
        realCG=flightTotalMoments / flightTotalWeights;

        cgOfMAC=((realCG - MAC_DISTANCE) / MAC_LENGTH) * 100;
        System.out.println("======================================");
        System.out.println("     航班 "+flight.getFlightNo()+" 载重平衡舱单");
        System.out.println("======================================");
        System.out.println("【基础数据】");
        System.out.printf("空机重量: %.1f kg  | 力臂: %.1f m\n",FLIGHT_WEIGHT,FLIGHT_WEIGHT_ARM);
        System.out.println("【旅客数据】");
        System.out.println("旅客人数: "+passengers.size()+"  | 总重(含行李): "+passengerWeights+" kg");
        System.out.println("【货物数据】");
        int k=1;
        for(int i=0;i<2;++i) {
            System.out.println("[" + (i+1) + "] 装载: " + compartments.get(i).getCurrentWeight() + "kg / " + compartments.get(i).getMaxWeight() + "kg (力臂: " + COMPARTMENT_ARMS[i] + "m)");
            List<Cargo> cargos = compartments.get(i).getCargos();
            for (Cargo cargo : cargos) {
                System.out.println("  ->[" + k + ", " + cargo.getWeight() + "kg]");
                k++;
            }
        }
        System.out.println("【汇总计算】");
        System.out.println("起飞总重量: "+flightTotalWeights+" kg");
        System.out.println("总力矩:"+flightTotalMoments+" kg·m");
        System.out.printf("实际重心(CG): %.1f m\n",realCG);
        System.out.printf("重心百分比(%%MAC): %.1f%%\n",cgOfMAC);
        System.out.println("======================================");
        System.out.print("配平评估: ");
        if(InputValidator.CheckCCNum(25,cgOfMAC,38)){
            System.out.println("安全 (GREEN)");
        } else {
            System.out.println("危险 (RED - 超出极限重心范围)");
        }
        System.out.print("======================================");
    }

 

 

对代码进行分析,有:

屏幕截图 2026-05-18 003410

 

 可以看到最大圈复杂度为 5,远低于警戒线,代码逻辑清晰。每个方法平均只有 2.55 条语句,方法职责非常单一,符合“小方法”设计原则。最大深度 5 处于可接受范围,平均深度 1.78 说明代码整体扁平易读。与第二次作业相比较,本次有1.0% 的注释覆盖率,比 task2 的 0% 略有进步,但仍有提升空间。

 

类图如下:

屏幕截图 2026-05-18 004030

 

本次代码无问题。

 

对比三次作业的类图来看,一次比一次复杂,对于我的考验也一次比一次大,但除了第一次编写程序有误外,后两次作业都可以体现出我的代码在不断的完善与进步,但仍然存在一些问题,比如代码注释较少,可读性差等。

 

 

踩坑心得

仍记得第一次编写作业的程序时,还以为老一套的思维可以支撑我编写,于是出现了未按照设计要求编写类与程序导致不得分的情况,在吸取了第一次的教训后,我在第二次甚至第三次的作业中取得了进步,印象最深刻的还是第三次作业,看到将近十个类的我差点两眼一黑晕过去,在编写完程序后,提交编译测试时又是在十个测试点只过了两个,有五个测试点是单纯的因为输出的中英文问题,因为这个小小的问题使得我浪费了将近一个半小时时间修改测试代码,最终在同学的提醒下“结束战斗”,这提醒我在输出时一定要看仔细需求,以及最重要的,不要随意”放过“任何一个类,所有类都要在严格细致的检查下进行,像我第三次作业中的类InputValidtor(用于测试边界)

屏幕截图 2026-05-18 005511因为没有仔细检查图中的CheckCCNum方法,导致对前舱和后舱的容量检查出现问题:屏幕截图 2026-05-18 005624,在编写时一定要多多检查编写的类与方法,防止出现数值赋值错误或某个变量名书写错误。

 

 

改进建议

对于第一次作业,修改检查排序、超载的方法,改正代码。对于第二次作业,可以给货物指定放置目标货舱的位置,使得Position发挥作用。对于第三次作业,将货物排序后从大到小装入货舱中,优先装入更重的货物,以及新增一个只用于输出的类printer,将纯计算generateLoadSheet中的输出部分用新增类printer输出。

 

 

总结

总的说来,对于这次题目集的三次迭代,我从一开始的一头雾水写编程,到第三次作业时不断完善面向对象的需求,从对UML的初步认识,到熟悉使用java语言,再到对解耦的探究与实践,每一次作业集我都能学习到许多新的知识,包括但不限于java中方便的工具包、对编程的不同角度思考,以及在面向对象、步入现实情境时的思维、方案与策略,都是我在本次题集的心得体会。再有,我将加强对java语言的学习,以及对面向对象思维的训练,以迎接未来的机遇与挑战。

 

posted @ 2026-05-18 01:22  落枫yy  阅读(12)  评论(0)    收藏  举报