第二次博客作业

一、前言

第四次作业:第四次大作业只有一道菜单计价题目,本次题目在菜单以及点菜部分未做过多改变,主要是增加一些异常情况的处理,是基于第三次大作业的一个衍生系列,十几条异常处理分布于各个地方,使代码量相较于第三次而言翻了几乎一倍(仅仅对我来说是这样的),而异常情况的处理也并不容易,不是报错就是在报错的路上。

第五次作业:第五次大作业也同样只有一道菜单计价题目,也是基于第三次大作业的一个衍生系列,与第四次大作业的内容“完全不同”。此次大作业是基于菜单方面做出的调整,主要增加了特色菜的口味类型和口味值,代码量似乎与第四次差不多,但是难度似乎没有菜单计价-4高,只需要对菜谱等类做一些改动,而4是代码“大改特改”。

期中考试:期中考试的题目难度整体不大,基本就是“看图说话”的类型,只要代码没有语法问题,测试点就都能过。

 

二、设计与分析

1.第四次作业

7-1.菜单计价程序-4

 

复制代码
本次课题比菜单计价系列-3增加的异常情况:

1、菜谱信息与订单信息混合,应忽略夹在订单信息中的菜谱信息。输出:"invalid dish"

2、桌号所带时间格式合法(格式见输入格式部分说明,其中年必须是4位数字,月、日、时、分、秒可以是1位或2位数),数据非法,比如:2023/15/16 ,输出桌号+" date error"

3、同一桌菜名、份额相同的点菜记录要合并成一条进行计算,否则可能会出现四舍五入的误差。

4、重复删除,重复的删除记录输出"deduplication :"+序号。

5、代点菜时,桌号不存在,输出"Table number :"+被点菜桌号+" does not exist";本次作业不考虑两桌记录时间不匹配的情况。

6、菜谱信息中出现重复的菜品名,以最后一条记录为准。

7、如果有重复的桌号信息,如果两条信息的时间不在同一时间段,(时段的认定:周一到周五的中午或晚上是同一时段,或者周末时间间隔1小时(不含一小时整,精确到秒)以内算统一时段),此时输出结果按不同的记录分别计价。

8、重复的桌号信息如果两条信息的时间在同一时间段,此时输出结果时合并点菜记录统一计价。前提:两个的桌号信息的时间都在有效时间段以内。计算每一桌总价要先合并符合本条件的饭桌的点菜记录,统一计价输出。

9、份额超出范围(123)输出:序号+" portion out of range "+份额,份额不能超过1位,否则为非法格式,参照第13条输出。

10、份数超出范围,每桌不超过15份,超出范围输出:序号+" num out of range "+份数。份数必须为数值,最高位不能为0,否则按非法格式参照第16条输出。

11、桌号超出范围[1,55]。输出:桌号 +" table num out of range",桌号必须为1位或多位数值,最高位不能为0,否则按非法格式参照第16条输出。

12、菜谱信息中菜价超出范围(区间(0,300)),输出:菜品名+" price out of range "+价格,菜价必须为数值,最高位不能为0,否则按非法格式参照第16条输出。

13、时间输入有效但超出范围[2022.1.1-2023.12.31],输出:"not a valid time period"

14、一条点菜记录中若格式正确,但数据出现问题,如:菜名不存在、份额超出范围、份数超出范围,按记录中从左到右的次序优先级由高到低,输出时只提示优先级最高的那个错误。

15、每桌的点菜记录的序号必须按从小到大的顺序排列(可以不连续,也可以不从1开始),未按序排列序号的输出:"record serial number sequence error"。当前记录忽略。(代点菜信息的序号除外)

16、所有记录其它非法格式输入,统一输出"wrong format"

17、如果记录以“table”开头,对应记录的格式或者数据不符合桌号的要求,那一桌下面定义的所有信息无论正确或错误均忽略,不做处理。如果记录不是以“table”开头,比如“tab le 55 2023/3/2 12/00/00”,该条记录认为是错误记录,后面所有的信息并入上一桌一起计算。

本次作业比菜单计价系列-3增加的功能:

菜单输入时增加特色菜,特色菜的输入格式:菜品名+英文空格+基础价格+"T"

例如:麻婆豆腐 9 T
复制代码

 

 

 

代码实现:

类的设计与第三次作业一致,只是增加了异常情况的处理。对于格式一场的处理,我采用的是try catch表达式,例如:输入的数值理应是数字但实际却是其它类型的数据,这时Integer.parseInt()错误,就会抛出异常,抛出异常之后,进入到catchcatch接收,输出“Wrong Format”。另外,对于判断桌号时间是否合法,我采用的是length()直接判断年份、月份、日等是否是合法的格式(但是这个对于判断是否是数字就不适用了)。而对于份额、份数、桌号超出范围是直接用if语句判断并输出结果,此次代码在主类中新增了一个判断方法,主要是判断输入的一行语句首字母是否为数字来区分菜单、桌号信息和订单。

 

复制代码
public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        Menu menu = new Menu();
        Table table = new Table();
        int tableNum = 0;
        int[] tablenum=new int[20];
        int tabnum=0;
        int[] shanrecord=new int[20];
        int sharecord=0;
        String s = input.nextLine();
        String[] str = s.split(" ");
        Boolean menuTag = false;
        int errorNum = 0;
        int fenNum = 0;

        while (!(str[0].equalsIgnoreCase("end"))) {
            if (check(str[0])) {
                menuTag = false;
                if (str[0].equalsIgnoreCase("table")) {
                    menuTag = true;
                    char c=str[1].charAt(0);
                    Time t=new Time(str[2],str[3]);
                    int flag=0;
                    errorNum=0;
                    sharecord=0;
                    if(c=='0')
                        System.out.println("wrong format");
                    String[] str1=str[2].split("/");
                    String[] str2=str[3].split("/");
                    try {
                        tableNum = Integer.parseInt(str[1]);
                        int year=Integer.parseInt(str1[0]);
                        if(tableNum<1||tableNum>55)
                        {
                            System.out.println(tableNum+" table num out of range");
                            flag=1;
                        }
                        else if(year<2022||year>2023)
                        {
                            System.out.println("not a valid time period");
                            flag=1;
                        }
                        else
                        {
                        tablenum[tabnum++]=tableNum;
                        System.out.println("table " + tableNum + ": ");
                        table.addTable(tableNum, str[2], str[3]);
                        }
                    } catch (Exception e) {
                        System.out.println("wrong format");
                        break;
                    }
                    if(flag==1)
                    {
                        while(true)
                        {
                            s = input.nextLine();
                            str = s.split(" ");
                            if(str[0].equalsIgnoreCase("end")||str[0].equalsIgnoreCase("table"))
                                break;
                        }
                        continue;
                    }
                } else {
                    System.out.println("wrong format");
                }


            } else if (Character.isDigit(str[0].charAt(0))) {
                if (errorNum >= Integer.valueOf(str[0]) && !str[1].equalsIgnoreCase("delete")) {
                    System.out.println("record serial number sequence error");
                } else if (Character.isDigit(str[1].charAt(0)))
                {
                    int flag=0;
                    for(int i=0;i<tabnum;i++)
                    {
                        if(Integer.parseInt(str[0])==tablenum[i])
                        {
                            flag=1;
                            break;
                        }
                    }
                    if(flag==1)
                        table.order[tableNum].addRecord(menu, Integer.parseInt(str[1]), str[2], Integer.parseInt(str[3]), Integer.parseInt(str[4]), 2, Integer.parseInt(str[0]), true);
                    else
                        System.out.println("Table number :"+str[0]+" does not exist");
                }
                    else if (str[1].equalsIgnoreCase("delete")) {
                    shanrecord[sharecord++]=Integer.parseInt(str[0]);
                        for(int i=0;i<sharecord-1;i++)
                        {
                            if(Integer.parseInt(str[0])==shanrecord[i])
                            {System.out.println("deduplication " + str[0]);
                             break;}
                        }
                        table.order[tableNum].delARecordByOrderNum(Integer.parseInt(str[0]));
                    table.order[tableNum].delRecord(Integer.parseInt(str[0]), true);
                } else if (Integer.parseInt(str[3]) > 15)
                    table.order[tableNum].addRecord(menu, Integer.parseInt(str[0]), str[1], Integer.parseInt(str[2]), Integer.parseInt(str[3]), 3, 0, true);
                else {
                    char c=str[0].charAt(0);
                    char d=str[3].charAt(0);
                    if(c=='0'||d=='0'||str[2].length()>1)
                            System.out.println("wrong format");
                    else
                    table.order[tableNum].addRecord(menu, Integer.parseInt(str[0]), str[1], Integer.parseInt(str[2]), Integer.parseInt(str[3]), 1, 0, false);
                    if(Integer.parseInt(str[2])==1||Integer.parseInt(str[2])==2||Integer.parseInt(str[2])==3)
                        errorNum = Integer.parseInt(str[0]);
                }
            }
            else {
                if (menuTag) {
                    System.out.println("invalid dish");
                } else {
                    int unit_price = 0;
                    try {
                        char c=str[1].charAt(0);
                        unit_price = Integer.parseInt(str[1]);
                        if(unit_price<=0||unit_price>=300)
                            System.out.println(str[0]+" price out of range "+unit_price);
                        else
                        {
                        if(c=='0')
                            System.out.println("wrong format");
                        if (str.length ==2) {
                            menu.addDish(str[0], unit_price, false);
                        } else if(str.length ==3){
                            if (str[2].equals("T")) {
                                menu.addDish(str[0], unit_price, true);
                            }
                            else
                                System.out.println("wrong format");
                        }
                            else
                                System.out.println("wrong format");
                        }
                    } catch (Exception e) {
                        System.out.println("wrong format");
                    }
                }

            }
            s = input.nextLine();
            str = s.split(" ");
            if(s.length()==0)
            {
                System.out.println("wrong format");
                s = input.nextLine();
                str = s.split(" ");
            }
        }
        int sumPrice;
        int totalprice;
        for (int i = 0; i <tabnum; i++) {
            int k;
            try {
                k=tablenum[i];
                Order order = table.order[k];
                int a = 0;
                ArrayList<Integer> integers = new ArrayList<>();
                if (order != null) {
                    for (int j = 0; j < order.numm; j++) {
                        Record record = order.records[j];
                        int orderNum = record.orderNum;
                        if (orderNum == a) {
                            if (!integers.contains(a)) {
                                integers.add(a);
                            }
                        }
                        a = orderNum;
                    }

                }
            } catch (Exception e) {
                break;
            }


            //折后总价
            totalprice = table.getTotalPrice(k);
            //总价
            sumPrice = table.getSumPrice(k);
            if (totalprice == -2)
                continue;
            else
                System.out.println("table " + k + ": " + sumPrice + " " + totalprice);
        }

    }

    
}

复制代码

 

 

 

 

代码分析:

 

此题涉及了一个新的概念,try catch,对于以前的if-else而言,代码臃肿,可读性差,不同与if-else的诸多缺点,trycatch是用于处理异常的语句,它们构成了一种异常处理机制。在一个try语句中,程序执行一段代码,如果发生了异常,则会被捕获,并转到相应的catch语句中进行处理。

例如,有这样一段代码,程序执行了一个方法pide,如果该方法发生了一场,则会被捕获并输出一条错误信息:

try{

Int result=pide(10,0);

System.out.println(result);

}catch(Expetion e){

System.out.println(Error);}

如果pide方法发生了异常,则会被捕获,反之,程序会执行pide方法并输出结果。总之,trycatch语句用于处理程序运行时可能发声的异常,以保证程序的稳定性和正确性。

对于日期格式的判断,我采用的是最基础的if-else语句,我写了好几条if-else语句,显得代码过于冗杂,但却实在无能为力,之前写的判断日期的方法bug太多,只能用这种方法,抛开代码复杂度不谈,这种判断方法还有一个缺点,判断不了数据类型是否正确,导致输入的年份是“aaaa”也判定为正确。此次作业困扰我最久的问题是重复桌号。对于重复桌号,需要根据桌号信息中的时间去判断重复桌号是否在同一时间段内,并将在同一时间段的桌号的点菜信息合并。我写了好几种判断方法,但是编译器输出一直都是“非零返回”,无论怎么去修改,代码永远有bug,而测试点的后几个基本都是对重复桌号的判断,这导致我一直拿不到最后几个测试点的分。

2.第五次作业

7-1.菜单计价程序-5

 

复制代码
本次课题相比菜单计价系列-3新增要求如下:

 

1、菜单输入时增加特色菜,特色菜的输入格式:菜品名+英文空格+口味类型+英文空格+基础价格+"T"

例如:麻婆豆腐 川菜 9 T

菜价的计算方法:

周一至周五 7折, 周末全价。

特色菜的口味类型:川菜、晋菜、浙菜

川菜增加辣度值:辣度0-5级;对应辣度水平为:不辣、微辣、稍辣、辣、很辣、爆辣;

晋菜增加酸度值,酸度0-4级;对应酸度水平为:不酸、微酸、稍酸、酸、很酸;

浙菜增加甜度值,甜度0-3级;对应酸度水平为:不甜、微甜、稍甜、甜;    

例如:麻婆豆腐 川菜 9 T

输入订单记录时如果是特色菜,添加口味度(辣/酸/甜度)值,格式为:序号+英文空格+菜名+英文空格+口味度值+英文空格+份额+英文空格+份数

例如:1 麻婆豆腐 4 1 9

单条信息在处理时,如果口味度超过正常范围,输出"spicy/acidity/sweetness num out of range : "+口味度值,spicy/acidity/sweetness(辣度/酸度/甜度)根据菜品类型择一输出,例如:

acidity num out of range : 5

输出一桌的信息时,按辣、酸、甜度的顺序依次输出本桌菜各种口味的口味度水平,如果没有某个类型的菜,对应的口味(辣/酸/甜)度不输出,只输出已点的菜的口味度。口味度水平由口味度平均值确定,口味度平均值只综合对应口味菜系的菜计算,不做所有菜的平均。比如,某桌菜点了3份川菜,辣度分别是1、3、5;还有4份晋菜,酸度分别是,1、1、2、2,辣度平均值为3、酸度平均值四舍五入为2,甜度没有,不输出。

一桌信息的输出格式:table+英文空格+桌号+:+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价+英文空格+"川菜"+数量+辣度+英文空格+"晋菜"+数量+酸度+英文空格+"浙菜"+数量+甜度。

如果整桌菜没有特色菜,则只输出table的基本信息,格式如下:

table+英文空格+桌号+:+英文空格+当前桌的原始总价+英文空格+当前桌的计算折扣后总价+英文空格

例如:table 1: 60 36 川菜 2 爆辣 浙菜 1 微甜

计算口味度时要累计本桌各类菜系所有记录的口味度总和(每条记录的口味度乘以菜的份数),再除以对应菜系菜的总份数,最后四舍五入。

注:本题要考虑代点菜的情况,当前桌点的菜要加上被其他桌代点的菜综合计算口味度平均值。

 

 

2、考虑客户订多桌菜的情况,输入时桌号时,增加用户的信息:

格式:table+英文空格+桌号+英文空格+":"+英文空格+客户姓名+英文空格+手机号+日期(格式:YYYY/MM/DD)+英文空格+ 时间(24小时制格式: HH/MM/SS)

例如:table 1 : tom 13670008181 2023/5/1 21/30/00

约束条件:客户姓名不超过10个字符,手机号11位,前三位必须是180、181、189、133、135、136其中之一。

输出结果时,先按要求输出每一桌的信息,最后按字母顺序依次输出每位客户需要支付的金额。不考虑各桌时间段的问题,同一个客户的所有table金额都要累加。

输出用户支付金额格式:

用户姓名+英文空格+手机号+英文空格+支付金额
复制代码

 

 

 

代码实现:

类的设计与第三次作业一致,不同的是对于输入信息改变而修改了部分代码,例如:菜单中的特色菜新增加了口味类型,那么菜单部分信息的存入也发生了变化,在Dish类中新增加了一个String类型的口味类型。订单信息中也发生了改变,在份额前新增了口味度的选择,因此,Record类中也新增加了一个String类型的口味类型和一个int类型的口味值。而对于桌号一行的信息改变(新增了客户名和客户手机号),Order类中新增加了两个String类型的值,分别代表客户姓名和客户的手机号。另外,此次作业还需要判断客户姓名是否不超过10个字符,此处采用的仍是熟悉的length()获取长度,以及判断客户手机号是否为十一位,手机号前三位是否为“180”、“181”、“189”、“133”、“135”、“136”其中之一。此处我定义了一个方法,将手机号传入方法中,再用substring获取前三位,equals判断是否为特定数字。最后,还需根据客户名字的字母顺序依次输出每位客户需要支付的金额,实现这个方法所用的是循环嵌套,在里面用compareTo来实现客户名的字母排序。

 

复制代码
    
public class Main {
public static void main(String[] args) { Scanner input = new Scanner(System.in); Menu menu = new Menu(); Table table = new Table(); int tableNum = 0; String s = input.nextLine(); String[] str = s.split(" "); Boolean menuTag = false; while (!(str[0].equalsIgnoreCase("end"))) { if (check(str[0])) { int flag=0; menuTag = false; if (str[0].equalsIgnoreCase("table")) { menuTag = true; if(str[3].length()>10) { System.out.println("wrong format"); flag=1; } else if(str[4].length()!=11) { System.out.println("wrong format"); flag=1; } else if(!judge(str[4])) { System.out.println("wrong format"); flag=1; } else if(opentime(str[5],str[6])==0) { System.out.println("table " + str[1] + " out of opening hours"); flag=1; } else { tableNum = Integer.parseInt(str[1]); System.out.println("table " + tableNum + ": "); table.addTable(tableNum, str[3], str[4],str[5],str[6]); } if(flag==1) { while(!(str[0].equalsIgnoreCase("end"))) { s = input.nextLine(); str = s.split(" "); if(str[0].equalsIgnoreCase("table")) break; } continue; } } } else if (Character.isDigit(str[0].charAt(0))) { if(str.length<5) { if (str[1].equalsIgnoreCase("delete")) { table.order[tableNum].delARecordByOrderNum(Integer.parseInt(str[0])); table.order[tableNum].delRecord(Integer.parseInt(str[0]), true); } else table.order[tableNum].addRecord(menu, Integer.parseInt(str[0]), str[1], 0,Integer.parseInt(str[2]), Integer.parseInt(str[3]), 1, 0, false); } else if(str.length==5) { if (Character.isDigit(str[1].charAt(0))) {table.order[tableNum].addRecord(menu, Integer.parseInt(str[1]), str[2], 0,Integer.parseInt(str[3]), Integer.parseInt(str[4]), 2, Integer.parseInt(str[0]), false); table.order[Integer.parseInt(str[0])].addRecord(menu, Integer.parseInt(str[1]), str[2], 0,Integer.parseInt(str[3]), Integer.parseInt(str[4]), 3, Integer.parseInt(str[0]), true); } else table.order[tableNum].addRecord(menu, Integer.parseInt(str[0]), str[1], Integer.parseInt(str[2]),Integer.parseInt(str[3]), Integer.parseInt(str[4]), 1, 0, false); } else if(str.length==6) { table.order[tableNum].addRecord(menu, Integer.parseInt(str[1]), str[2], Integer.parseInt(str[3]), Integer.parseInt(str[4]),Integer.parseInt(str[5]), 2, Integer.parseInt(str[0]), false); table.order[Integer.parseInt(str[0])].addRecord(menu, Integer.parseInt(str[1]), str[2], Integer.parseInt(str[3]), Integer.parseInt(str[4]),Integer.parseInt(str[5]), 3, Integer.parseInt(str[0]), true); } } else { if (menuTag) { System.out.println("invalid dish"); } else { int unit_price = 0; try { if (str.length==2) { unit_price = Integer.parseInt(str[1]); menu.addDish(str[0], unit_price, false,"wu"); } else if(str.length==4){ if (str[3].equals("T")) { unit_price = Integer.parseInt(str[2]); menu.addDish(str[0], unit_price, true,str[1]); } } else System.out.println("wrong format"); } catch (Exception e) { System.out.println("wrong format"); } } } s = input.nextLine(); str = s.split(" "); } int sumPrice[]=new int[20]; int totalprice[]=new int[20]; String kename[]=new String[20]; String kenum[]=new String[20]; int c=0; for (int i = 1; i <= tableNum; i++) { Order order = table.order[i]; try { int a = 0; ArrayList<Integer> integers = new ArrayList<>(); if (order != null) { for (int j = 0; j < order.numm; j++) { Record record = order.records[j]; int orderNum = record.orderNum; if (orderNum == a) { if (!integers.contains(a)) { integers.add(a); } } a = orderNum; } } } catch (Exception e) { break; } //折后总价 totalprice[c] = table.getTotalPrice(i); //总价 sumPrice[c] = table.getSumPrice(i); kename[c]=order.kehu; kenum[c]=order.kehunum; for(int j=0;j<c;j++) { if(kename[c].equals(kename[j])&&(kenum[c].equals(kenum[j]))) { totalprice[j]=totalprice[j]+totalprice[c]; sumPrice[j]=sumPrice[j]+sumPrice[c]; c--; break; } } c++; } for(int i=0;i<c-1;i++) { for(int j=i+1;j<c;j++) { if(kename[i].compareTo(kename[j])>0) { String temp=kename[i]; kename[i]=kename[j]; kename[j]=temp; int t=totalprice[i]; totalprice[i]=totalprice[j]; totalprice[j]=t; } } } for(int i=0;i<c;i++) { System.out.println(kename[i]+" "+kenum[i]+" "+totalprice[i]); } } }
复制代码

 

 

 

代码分析:

 

“substring(int beginIndex,int endIndex)”此方法中的beginIndex表示截取的起始索引,截取的字符串中包括起始索引对应的字符,endIndex表示结束索引,截取的字符串中不包括结束索引对应的字符,如果不指定endIndex,则表示截取到目标字符串末尾。该方法用于提取位置beginIndex和位置endIndex位置之间的字符串部分。这里需要特别注意的是,对于开始位置beginIndexJava是基于字符串的首字符索引为0处理的,但对于结束位置endIndexJava是基于字符串的首字符索引为1来处理的。

代码中的comoareTo()方法:compareTo()通常用于两种方式的比较:一是字符串与对象进行比较,二是按字典顺序比较两个字符串,这里使用的是第二种方法,基于字符串中各个字符的Unicode值。将此String对象表示的字符序列与参数字符串所表示的字符序列进行比较。如果按字典顺序比String对象在参数字符串之前,则比较结果为一个负整数。如果该对象位于参数字符串之前,则比较结果为一个正整数。如果这两个字符串相等,则比较结果为0compareTo()只有在方法equals(Object)返回true时才返回0(这是字典排序的定义)。

此次作业中,在订单处理时我的处理方式是通过判断订单分割后得到的字符数组长度来决定是否是代点菜,特色菜订单,特色菜代点菜订单等,然后根据不同的长度传入方法中对应的订单信息类型不同来进行订单记录的,但是感觉有更好的方法,虽然我想不出来。另外,本次作业的输出中有对口味度的平均值输出,因此Record中的String“口味类型就是为了购物求口味度平均值加上去的。

 

3.第三次作业

1.7.1 测验1-圆类设计

 

创建一个圆形类(Circle),私有属性为圆的半径,从控制台输入圆的半径,输出圆的面积

输入格式:
输入圆的半径,取值范围为(0,+∞),输入数据非法,则程序输出Wrong Format,注意:只考虑从控制台输入数值的情况

输出格式:
输出圆的面积(保留两位小数,可以使用String.format(“%.2f”,输出数值)控制精度)

 

 

 

代码实现:

创建最基本的主类和圆类即可。

代码分析:

此题难度不大,属于基础题型,不做分析。

2.7.2 测验2-类结构设计

 

复制代码
设计一个矩形类,其属性由矩形左上角坐标点(x1,y1)及右下角坐标点(x2,y2)组成,其中,坐标点属性包括该坐标点的X轴及Y轴的坐标值(实型数),求得该矩形的面积。类设计如下图:


image.png

输入格式:
分别输入两个坐标点的坐标值x1,y1,x2,y2。

输出格式:
输出该矩形的面积值(保留两位小数)。

输入样例:
复制代码

 

 

 

代码实现:

首先是主类,然后定义了一个矩形类和点类。矩形类中主要是坐标的获取,长、宽的获取以及面积的获取等方法,点类中主要就是点横纵坐标的setget

代码分析:

此题基本上属于看图说话,没有什么难度,但需要注意的一点是小数的保留位数,此方法已于第一题中给出,即String format(“%.2f.输出数值)

3.7.3 测验3-继承与多态

 

复制代码
将测验1与测验2的类设计进行合并设计,抽象出Shape父类(抽象类),Circle及Rectangle作为子类,类图如下所示:


image.png

试编程完成如上类图设计,主方法源码如下(可直接拷贝使用):

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        
        int choice = input.nextInt();
        
        switch(choice) {
        case 1://Circle
            double radiums = input.nextDouble();
            Shape circle = new Circle(radiums);
            printArea(circle);
            break;
        case 2://Rectangle
            double x1 = input.nextDouble();
            double y1 = input.nextDouble();
            double x2 = input.nextDouble();
            double y2 = input.nextDouble();
            
            Point leftTopPoint = new Point(x1,y1);
            Point lowerRightPoint = new Point(x2,y2);
            
            Rectangle rectangle = new Rectangle(leftTopPoint,lowerRightPoint);
            
            printArea(rectangle);
            break;
        }
        
    }
其中,printArea(Shape shape)方法为定义在Main类中的静态方法,体现程序设计的多态性。

输入格式:
输入类型选择(1或2,不考虑无效输入)
对应图形的参数(圆或矩形)

输出格式:
图形的面积(保留两位小数)
复制代码

 

 

 

代码实现:

12题的基础上增加了一个父类Shape,只需要在Circle类与Rectangle类名后加“extends Shape”即可。

代码分析:

本次题目中给出了主方法源代码,其中有这样一个方法printArea(),这个方法并没有定义,因此需要在主类中增加一个方法printArea()

4.7.4 测验4-抽象类与接口

 

复制代码
在测验3的题目基础上,重构类设计,实现列表内图形的排序功能(按照图形的面积进行排序)。
提示:题目中Shape类要实现Comparable接口。

其中,Main类源码如下(可直接拷贝使用):

public class Main {
    public static void main(String\[\] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        ArrayList<Shape> list = new ArrayList<>();    

        int choice = input.nextInt();

        while(choice != 0) {
            switch(choice) {
            case 1://Circle
                double radiums = input.nextDouble();
                Shape circle = new Circle(radiums);
                list.add(circle);
                break;
            case 2://Rectangle
                double x1 = input.nextDouble();
                double y1 = input.nextDouble();
                double x2 = input.nextDouble();
                double y2 = input.nextDouble();            
                Point leftTopPoint = new Point(x1,y1);
                Point lowerRightPoint = new Point(x2,y2);
                Rectangle rectangle = new Rectangle(leftTopPoint,lowerRightPoint);
                list.add(rectangle);
                break;
            }
            choice = input.nextInt();
        }    

        list.sort(Comparator.naturalOrder());//正向排序

        for(int i = 0; i < list.size(); i++) {
            System.out.print(String.format("%.2f", list.get(i).getArea()) + " ");
        }    
    }    
}

输入格式:
输入图形类型(1:圆形;2:矩形;0:结束输入)

输入图形所需参数

输出格式:
按升序排序输出列表中各图形的面积(保留两位小数),各图形面积之间用空格分隔。
复制代码

 

 

 

代码实现:

3题的基础上新增了一个接口Comparable

代码分析:

题目中用到了list.sort()排序,sort()方法根据指定的顺序对动态数组中的元素进行排序,它不返回任何值,只是更改动态数组列表中元素的顺序。

 

三、踩坑心得

1.对于String类中的方法中获取字符串的长度s.length()和获取字符数组长度s.length总是会搞混(它们实在是太像了)。

2.(这是我个人的问题)在菜单5中对口味值的累加,每个口味度的代码除了名字不一样,其它都一样,以至于我复制粘贴时忘记改名字了,导致输出的结果对不上,我还在这里困惑了好久。

四、主要困难及改进意见

对我而言最大的问题就是一段代码中if-else语句使用太多了,导致代码的可读性太差,过于冗杂,但是又想不到其它简便的方法,每次想出一个新方法要不就报错,要不就输出错误,感觉没有if-else来的快,所以导致我的代码中if-else太多了。

五、总结

此次blog主要针对前两次大作业做总结,期中考试感觉没什么总结的。前两次大作业的难度大幅度上涨,代码量也翻了一倍,虽然写代码的过程十分煎熬和痛苦,但是通过这两次大作业我还是学到了许多东西,例如:对try catch的熟练使用,对compareTo方法对字符串排序的掌握。学习Java语言时,必须有一颗能沉静下来的心,在课上学到的东西总是有限的,更多的知识还需要我们自己去探索追寻。总之,继续努力吧,通过一次次的失败积攒经验,拒绝躺平。

posted @   corcinle  阅读(46)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示