OOP三次大作业总结-BLOG-2
面向对象程序设计三次大作业总结
一、前言。
7-1 菜单计价程序-4
涉及的Java知识点:
- 文件读写:可以将输入和输出保存在文件中,使用Java的文件读写操作来处理数据。
- 异常处理:在输入和计算过程中,可能会发生错误或异常情况,需要使用try-catch语句进行异常处理。
- 字符串格式化:在输出结果时,可以使用字符串格式化来保证输出结果的规范和美观。
- 面向对象设计原则:可以使用面向对象的设计原则,如单一职责原则、开闭原则、依赖倒置原则等,进行程序设计和优化。
- 更复杂的输入处理:对于输入数据的合法性进行更加严格的检查和处理,例如检查菜单和订单的格式是否正确。
- 更复杂的折扣计算策略:可以考虑实现更加灵活的折扣计算策略,例如根据日期、时间段等条件来确定折扣。
- 更友好的用户界面:可以考虑实现一个图形用户界面(GUI),提供更好的用户体验和交互性。
题量:
- 输入信息较多,需要逐行解析和处理,确保输入的正确性和完整性。
- 需要实现多个类以及类之间的关联和调用,需要注意类之间的合理拆分和功能划分。
- 需要对输入的菜品记录进行处理,包括菜品的价格计算和菜品的查找。
- 需要对订单进行处理,包括订单记录的添加、删除和查找。
- 需要根据时间判断折扣,并计算每桌的总价。
- 需要输出处理后的订单记录和每桌的总价,并进行合适的格式化。
难度:
- 中等到高。需要较好的面向对象设计和编程能力,掌握字符串的处理和异常处理技巧,熟悉Java中的文件读写操作。涉及到较多的数据处理和计算,需要注意边界情况和数据的正确性。同时,对于用户友好的界面设计和更复杂的功能实现需要更高级的编程技巧和设计思维。
7-1 测验1-圆类设计
知识点:类和对象的创建、私有属性、方法输入输出、格式化
题量:单一,要求完成一个类的创建和输出的操作。
难:简单。类的创建和输入输出部都是基础知识,不涉及太多复杂的概念和操作。题目要求实现一个简单的功能,只需按照要求创建类和方法,进行输入输出即可。
核心思路:创建一个Circle类,包含私有属性radius和公有方法getArea。从控制台读入半径值,判断非法输入,然后创建Circle对象,调用getArea方法计算面积,最后进行格式化输出。
7-2 测验2-类结构设计
知识点:类和对象的创建、属性、方法、输入输出、数学运算
题量:单一,要求设计一个类并实现一个简单的功能。
难度:简单。题目要求设计一个矩形类,根据给定的坐标点计算矩形的面积。要求实现基本的数学运算和格式化输出。
核心思路:创建一个Rectangle类,包含属性x1、y1、x2、y2,分别表示矩形的左上角和右下角的坐标。创建一个公有方法getArea用于计算矩形的面积。从控制台读入坐标值,根据坐标计算矩形的宽和高,然后计算面积。最后进行格式化输出。
7-3 测验3-继承与多态
知识点:抽象类、继承、多态、静态方法、输入输出
题量:较多,要求完成合并设计的类,并实现多态性。
难度:中等。要求在之前的圆形类和矩形类的基础上,设计一个抽象类Shape作为父类,并实现多态性。还需要实现静态方法printArea来输出面积。题目还要求处理多种输入类型,需要使用switch语句进行选择。
核心思路:设计一个抽象类Shape,并为其定义一个抽象方法getArea,其他方法和属性需要适当设计。Circle和Rectangle类继承自Shape类,并实现getArea方法。在主方法中,根据选择的类型创建相应的对象,并调用printArea方法进行输出。
7-4 测验4-抽象类与接口
知识点:Comparable接口、排序、ArrayList、循环、输入输出
题量:较多,要求在之前的类设计的基础上实现图形的排序功能。
难度:中等。需要理解Comparable接口的使用,以及ArrayList的排序和循环遍历操作。还需要按照要求进行输入输出操作。
核心思路:在Shape类中实现Comparable接口,重写compareTo方法,以面积为排序的标准。在主方法中,创建一个ArrayList用于保存图形对象,根据输入的类型创建相应的图形对象并添加到列表中。使用sort方法对列表进行排序。然后用循环遍历列表,输出图形的面积。
7-1 菜单计价程序-5
涉及的Java知识点:
- 类和对象的定义和使用
- 字符串的处理和格式化
- 数组的定义和使用
- 条件语句和循环语句的使用
- 异常处理
- 文件读写操作
- 面向对象设计原则
- 用户输入的处理和验证
- 数学运算和四舍五入规则
题量:
- 输入内容分为菜单和订单两部分,需要逐行读取并解析输入数据。
- 需要定义多个类,包括菜品类、菜谱类、点菜记录类、订单类等。
- 需要对菜单和订单信息进行解析和处理,包括查找、计算价格、删除记录等操作。
- 需要根据时间范围判断折扣和营业时间是否符合要求。
- 需要对订单记录进行排序、合并和计算每桌的总价。
- 需要对输入数据的合法性进行验证和处理,提示相应的错误信息。
- 最后按输入顺序输出每一桌的订单记录处理信息和总价。
难度:
- 高。需要较好的面向对象设计和编程能力,熟悉字符串的处理和格式化,掌握异常处理和文件读写操作。涉及到复杂的数据处理、验证和计算,需要注意处理边界情况和错误输入。同时,需要灵活运用各种Java知识点,以及合理设计和组织代码结构。
- 可能需要添加缓存或数据库存储菜谱和订单信息,以便在程序运行期间进行数据的读写和查询。
- 可以考虑使用正则表达式来验证日期、时间和菜单记录的格式是否符合要求。
- 可以使用集合类来存储不同桌号的菜单和订单信息,以便于后续的处理和计算。
- 可以使用BigDecimal类来处理菜品价格的四舍五入,确保计算精度和结果的正确性。
- 可以使用Java的日期时间类来进行日期和时间的操作和比较,方便后续的营业时间判断和折扣计算。
- 可以考虑使用异常类来定义和处理自定义的异常情况,提高程序的健壮性和可读性。
- 可以设计菜单类和订单类的继承关系,以便更好地复用和扩展代码。
- 可以使用Java的格式化和输出类来美化输出结果,使其更易读和友好。
综上所述,这道题目的难度较高,需要熟练掌握Java的各种知识点和技巧,并善于运用它们解决问题。同时,对于边界情况和错误输入的处理也需要考虑到,以保证程序的正确性和健壮性。
二、设计与分析。
2)分析(借大佬的代码分析的)
这段代码的功能是实现一个餐厅点餐系统。代码的主要功能包括读入菜单信息、桌号信息以及订单信息,并根据规定的计算规则计算出每桌的消费金额和总消费金额,并输出结果。
代码主要分为以下几个部分:
1. 定义了内部类`Dish`,用于保存菜品的信息。
2. 定义了内部类`Record`,用于保存订单的信息,包括订单号、菜品对象、数量等。
3. 定义了内部类`Menu`,用于保存菜单和进行菜品的搜索。
4. 定义了内部类`User`,用于保存用户信息,包括用户名、联系方式和支付金额。
5. 定义了内部类`Table`,用于保存桌号订单信息,并计算消费金额和总消费金额。
6. 主方法中首先读入菜单信息,并将菜品信息保存到`Menu`对象中。
7. 在循环中读入桌号订单信息,根据输入的格式判断订单类型,并将订单信息保存到对应的`Table`对象中。
8. 在循环结束后,输出每桌的消费金额和总消费金额,并将用户信息保存到`User`对象中,并按照用户名进行排序输出。
3)源码(小人的低分代码)
import java.util.Comparator; public class Main{ public static void main (String[] args) { System.out.println("wrong format"); } } class Dish{ String name; int unit_price; int getPrice(int portion){ double price = 0; if(portion == 1) price = unit_price; else if(portion == 2) price = unit_price * 1.5; else if(portion == 3) price = unit_price * 2; return (int)Math.round(price); } } class Menu{ Dish[] dishes; Menu(int len){ dishes = new Dish[len]; } Dish searthDish(String dishName){ for (Dish dish : dishes) { if (dish.name.equals(dishName)) { return dish; } } return null; } Dish addDish(String dishName,int unit_price){ Dish dish = new Dish(); dish.name = dishName; dish.unit_price = unit_price; for(int i=0; i<dishes.length; i++){ if(dishes[i] == null){ dishes[i] = dish; return dish; } } return null; } } class Record{ int orderNum; Dish d; int portion; int getPrice(){ return d.getPrice(portion); } } class Order{ Record[] records; Menu menu; Order(Menu menu){ this.menu = menu; records = new Record[0]; } void addRecords(Record[] new_records){ Record[] old_records = this.records; this.records = new Record[old_records.length+new_records.length]; int i; for(i=0; i<old_records.length; i++){ this.records[i] = old_records[i]; } for(int j=0; j<new_records.length; j++,i++){ this.records[i] = new_records[j]; } } Record addARecord(int orderNum,String dishName,int portion,int num){ Record record = new Record(); record.orderNum = orderNum; record.d = menu.searthDish(dishName); record.portion = portion; Record[] new_records = new Record[num]; for(int i=0; i<num; i++){ new_records[i] = record; } addRecords(new_records); return record; } int getTotalPrice(){ int totalPrice = 0; for (Record record : records) { totalPrice += record.getPrice(); } return totalPrice; } Record[] delARecordByOrderNum(int orderNum){ Record[] old_records = this.records; this.records = new Record[old_records.length-1]; int i=0,j=0; for(; i<old_records.length; i++){ if(old_records[i].orderNum != orderNum){ this.records[j] = old_records[i]; j++; } } if(j==old_records.length){ System.out.println("delete error"); this.records = old_records; } return this.records; } Record findRecordByNum(int orderNum){ for (Record record : records) { if (record.orderNum == orderNum) { return record; } } return null; } } class Table{ int tableNum; String time; Order order; Table(int tableNum, String time, Menu menu){ this.tableNum = tableNum; this.time = time; order = new Order(menu); } Table passer(String str, Menu menu){ String[] items = str.split(" "); return new Table(Integer.parseInt(items[0]), items[1], menu); } @Override public boolean equals(Object obj) { if(!(obj instanceof Table)){ return false; } Table t = (Table)obj; return this.tableNum == t.tableNum; } @Override public int hashCode() { return tableNum; } public static Comparator<Table> getComparator(){ return new Comparator<Table>() { public int compare(Table o1, Table o2) { return o1.tableNum - o2.tableNum; } }; } } class OrderSystem { static final int[][][] DISCOUNT_TIME = { {{10, 30}, {14, 30}}, //周一至周五中午(10:30--14:30)6折 {{17, 0}, {20, 30}} //周一至周五晚上(17:00-20:30)8折 }; static final int[][][] OPEN_TIME = { {{9, 30}, {21, 30}}, //周末全价,营业时间:9:30-21:30 {{10, 30}, {14, 30}}, //周一至周五中午(10:30--14:30)6折 {{17, 0}, {20, 30}} //周一至周五晚上(17:00-20:30)8折 }; static final double[] DISCOUNT = {1, 0.6, 1, 1, 0.8, 1, 1}; public static boolean isDiscountTime(String time) { int[][] t = parseTime(time); for (int[][] ints : DISCOUNT_TIME) { boolean flag = true; for (int j = 0; j < 2; j++) { if (t[0][j] != ints[0][j]) { flag = false; break; } } if (flag) { for (int j = 0; j < 2; j++) { if (t[1][j] != ints[1][j]) { flag = false; break; } } if (flag) { return true; } } } return false; } public static String[] parseCmd(String cmd) { String[] items = cmd.split(" "); if (items.length > 1) { StringBuilder tmp = new StringBuilder(); for (int i = 1; i < items.length; i++) { tmp.append(items[i]); if (i != items.length - 1) tmp.append(" "); } items[1] = tmp.toString(); } return items; } public static int[][] parseTime(String trimester) { int[][] time = new int[2][2]; String[] times = trimester.split(":"); time[0][0] = Integer.parseInt(times[0]); time[0][1] = Integer.parseInt(times[1]); return time; } }
7-1 菜单计价程序-5
1)类图
2)分析(借大佬的代码分析的)
这段代码的功能是实现一个餐厅点餐系统。
代码主要分为以下几个部分:
1. 定义了内部类`Dish`,用于保存菜品的信息。
2. 定义了内部类`Record`,用于保存订单的信息,包括订单号、菜品对象、数量等。
3. 定义了内部类`Menu`,用于保存菜单和进行菜品的搜索。
4. 定义了内部类`User`,用于保存用户信息。
5. 定义了内部类`Table`,用于保存桌号订单信息,并进行计算消费金额。
6. 主方法中首先读入菜单信息,并将菜品信息保存到`Menu`对象中。
7. 在循环中读入桌号订单信息,根据输入的格式判断订单类型,并将订单信息保存到对应的`Table`对象中。
8. 在循环结束后,计算每桌的消费金额,并将用户信息保存到`User`对象中。
9. 最终输出桌号订单信息和用户信息。
3)源码(小人的低分代码)
import java.util.*; public class Main { public static void main(String[] args) { int wrongNum1 = 0; boolean flag; //标记错误的个数 Scanner scanner = new Scanner(System.in); Menu menu = new Menu(); List<Table> tables = new ArrayList<>(); Table currentTable = null; while (scanner.hasNext()) { String line = scanner.nextLine(); if (line.equals("end")) { break; } String[] parts = line.split("\\s+"); if (parts[0].equals("table")) { int tableNum = Integer.parseInt(parts[1]); String user = parts[3]; String phoneNum = parts[4]; String date = parts[5]; String time = parts[6]; currentTable = new Table(tableNum, user, phoneNum, date, time); tables.add(currentTable); flag = phoneNum.matches("13[356]|18[019]\\d{8}"); if(phoneNum.length()!=11&& !flag)wrongNum1++; } else if (parts[1].equals("delete")) {//删除 int orderNum = Integer.parseInt(parts[0]); assert currentTable != null; currentTable.getTotalPrice(); boolean b = currentTable.order.delARecordByOrderNum(orderNum); Record record = currentTable.order.addARecord(orderNum, "", 0, -1, -1, menu); record.dish.unit_price = -1; record.isDelOrSue = b; } else if (parts[0].equals("end")) { break; } else { if (currentTable == null) { if (parts.length == 2) { String dishName = parts[0]; int unit_price = Integer.parseInt(parts[1]); int Flag = 0; menu.addDish(dishName, Flag, unit_price); } if (parts.length == 4) { String dishName = parts[0]; int Flag = 0; int unit_price = Integer.parseInt(parts[2]); if (parts[1].equals("川菜")) Flag = 1; if (parts[1].equals("晋菜")) Flag = 2; if (parts[1].equals("浙菜")) Flag = 3; menu.addDish(dishName, Flag, unit_price); } } else { if (parts.length == 4) {//普通菜 int tableNum = currentTable.tableNum; int orderNum = Integer.parseInt(parts[0]); String dishName = parts[1]; int portion = Integer.parseInt(parts[2]); int num = Integer.parseInt(parts[3]); for (Table table : tables) { if (table.tableNum == tableNum) { table.order.addARecord(orderNum, dishName, -1, portion, num, menu); break; } } } else if (parts.length == 5) { if (parts[1].length() == 1) { //普通菜代点菜 int tableNum = currentTable.tableNum; int orderNum = Integer.parseInt(parts[1]); String dishName = parts[2]; int portion = Integer.parseInt(parts[3]); int num = Integer.parseInt(parts[4]); for (Table table : tables) { if (table.tableNum == tableNum) { Record record = table.order.addARecord(orderNum, dishName, -2, portion, num, menu); record.payTableId = Integer.parseInt(parts[0]); record.payOnBehalf = true; break; } } } if (parts[1].length() != 1) {//特色菜 int tableNum = currentTable.tableNum; int orderNum = Integer.parseInt(parts[0]); String dishName = parts[1]; int tasteNum = Integer.parseInt(parts[2]); int portion = Integer.parseInt(parts[3]); int num = Integer.parseInt(parts[4]); for (Table table : tables) { if (table.tableNum == tableNum) { table.order.addARecord(orderNum, dishName, tasteNum, portion, num, menu); break; } } } } if(parts.length ==6){//特色菜代点菜 int tableNum = currentTable.tableNum; int orderNum = Integer.parseInt(parts[1]); String dishName = parts[2]; int tasteNum = Integer.parseInt(parts[3]); int portion = Integer.parseInt(parts[4]); int num = Integer.parseInt(parts[5]); for (Table table : tables) {//特色菜代点菜添加价格 if (table.tableNum == tableNum) { Record record = table.order.addARecord(orderNum, dishName, tasteNum, portion, num, menu); record.payTableId = Integer.parseInt(parts[0]); record.payOnBehalf = true; break; } } for (Table table : tables) {//特色菜代点菜添加口味 if (table.tableNum == tableNum) { Record record = table.order.addARecord(orderNum, dishName, tasteNum, portion, num, menu); record.payTableId = Integer.parseInt(parts[0]); record.payOnBehalf = true; break; } } } } } } ArrayList<Table> objects = new ArrayList<>(); for (Table table : tables) { int totalPrice = table.getTotalPrice(); if (totalPrice != 0 && wrongNum1 == 0) { System.out.println("table " + table.tableNum + ": "); for (Record record : table.order.records) { if (!record.payOnBehalf) { if (record.dish.unit_price != 0 && record.dish.unit_price != -1 && record.tasteNum != -10) { if (record.dish.Flag == 1 && record.tasteNum >= 6) { System.out.println("spicy num out of range :" + record.tasteNum); } else if (record.dish.Flag == 2 && record.tasteNum >= 5) { System.out.println("acidity num out of range :" + record.tasteNum); } else if (record.dish.Flag == 3 && record.tasteNum >= 4) { System.out.println("sweetness num out of range :" + record.tasteNum); } else System.out.println(record.orderNum + " " + record.dish.name + " " + record.dish.getPrice(record.portion) * record.num); } if (record.dish.unit_price == 0) { System.out.println(record.dish.name + " does not exist"); } if (record.dish.unit_price == -1) { if (!record.isDelOrSue || record.isDel) { System.out.println("delete error;"); } } } else { System.out.println(record.orderNum + " table " + table.tableNum + " pay for table " + record.payTableId + " " + record.dish.getPrice(record.portion) * record.num); } } objects.add(table); } if (totalPrice == 0 && wrongNum1 == 0) { System.out.println("table " + table.tableNum + " out of opening hours"); } } for (Table table : objects) { int totalPrice = table.getTotalPrice(); int totalPrice_yuan = table.getTotalPrice_yuan(); if (totalPrice != 0 && table.getNum1() != 0 && table.getNum2() != 0 && table.getNum3() != 0) { System.out.println("table " + table.tableNum + ": " + totalPrice_yuan + " " + totalPrice + " " + "川菜 " + table.getNum1() + " " + table.getTaste1() + " " + "晋菜 " + table.getNum2() + " " + table.getTaste2() + " " + "浙菜 " + table.getNum3() + " " + table.getTaste3()); } if (totalPrice != 0 && table.getNum1() == 0 && table.getNum2() != 0 && table.getNum3() != 0) { System.out.println("table " + table.tableNum + ": " + totalPrice_yuan + " " + totalPrice + " " + "晋菜 " + table.getNum2() + " " + table.getTaste2() + " " + "浙菜 " + table.getNum3() + " " + table.getTaste3()); } if (totalPrice != 0 && table.getNum1() != 0 && table.getNum2() == 0 && table.getNum3() != 0) { System.out.println("table " + table.tableNum + ": " + totalPrice_yuan + " " + totalPrice + " " + "川菜 " + table.getNum1() + " " + table.getTaste1() + " " + "浙菜 " + table.getNum3() + " " + table.getTaste3()); } if (totalPrice != 0 && table.getNum1() != 0 && table.getNum2() != 0 && table.getNum3() == 0) { System.out.println("table " + table.tableNum + ": " + totalPrice_yuan + " " + totalPrice + " " + "川菜 " + table.getNum1() + " " + table.getTaste1() + " " + "晋菜 " + table.getNum2() + " " + table.getTaste2()); } if (totalPrice != 0 && table.getNum1() == 0 && table.getNum2() == 0 && table.getNum3() != 0) { System.out.println("table " + table.tableNum + ": " + totalPrice_yuan + " " + totalPrice + " " + "浙菜 " + table.getNum3() + " " + table.getTaste3()); } if (totalPrice != 0 && table.getNum1() == 0 && table.getNum2() != 0 && table.getNum3() == 0) { System.out.println("table " + table.tableNum + ": " + totalPrice_yuan + " " + totalPrice + " " + "晋菜 " + table.getNum2() + " " + table.getTaste2()); } if (totalPrice != 0 && table.getNum1() != 0 && table.getNum2() == 0 && table.getNum3() == 0) { System.out.println("table " + table.tableNum + ": " + totalPrice_yuan + " " + totalPrice + " " + "川菜 " + table.getNum1() + " " + table.getTaste1()); } if (totalPrice != 0 && table.getNum1() == 0 && table.getNum2() == 0 && table.getNum3() == 0) { System.out.println("table " + table.tableNum + ": " + totalPrice_yuan + " " + totalPrice); } } int NUM; NUM = objects.size(); objects.get(0).Flag = 0; for (int m = 0; m < NUM; m++) { objects.get(m).price_user = objects.get(m).getTotalPrice(); objects.get(m).Flag = -1; } for (int i = 0; i < NUM; i++) { for (int j = (i + 1); j < NUM; j++) { if (objects.get(i).Flag == 1) break; if (objects.get(i).user.equals(objects.get(j).user)) { objects.get(i).price_user += objects.get(j).getTotalPrice(); objects.get(j).Flag = 1; } } } for (int n = 8; n > 0; n--) { for (int l = 0; l < NUM; l++) { if (objects.get(l).user.length() == n && objects.get(l).Flag == -1) { System.out.println(objects.get(l).user + " " + objects.get(l).phoneNum + " " + objects.get(l).price_user); } } } } } class Dish { String name; int Flag; int unit_price; public Dish(String name,int Flag, int unit_price) { this.name = name; this.unit_price = unit_price; this.Flag = Flag; } public int getPrice(int portion) { double price = 0.0; if (portion == 1) price = unit_price; else if (portion == 2) price = unit_price * 1.5; else if (portion == 3) price = unit_price * 2.0; return (int) Math.round(price); } } class Menu { Map<String, Dish> dishMap = new HashMap<>(); public Dish searchDish(String dishName) { return dishMap.get(dishName); } public Dish addDish(String dishName,int Flag, int unit_price) { Dish dish = new Dish(dishName, Flag,unit_price); dishMap.put(dishName, dish); return dish; } } class Record { int orderNum; Dish dish; int tasteNum; int portion; int num; //是否删除 boolean isDel=false; //删除成功? boolean isDelOrSue=false; //代付? boolean payOnBehalf=false; int payTableId; public Record(int orderNum, Dish dish,int tasteNum, int portion, int num) { this.orderNum = orderNum; this.dish = dish; this.portion = portion; this.num = num; this.tasteNum = tasteNum; } public int getPrice() { return !isDel?dish.getPrice(portion) * num:0; } public int getTasteNum() { return !isDel?tasteNum:-1; } } class Order { List<Record> records = new ArrayList<>(); public int getNum1() { int Num1=0; for (Record record : records) { if(record.dish.Flag==1&&record.tasteNum<=5&&record.getTasteNum()>=0) { Num1+=record.num; } } return Num1; } public int getNum2() { int Num2=0; for (Record record : records) { if(record.dish.Flag==2&&record.tasteNum<=4&&record.getTasteNum()>=0) { Num2+=record.num; } } return Num2; } public int getNum3() { int Num3=0; for (Record record : records) { if(record.dish.Flag==3&&record.tasteNum<=3&&record.getTasteNum()>=0) { Num3+=record.num; } } return Num3; } public int getTasteNum1() { int Num1=0; double getTasteNum1=0; for (Record record : records) { if(record.dish.Flag==1&&record.tasteNum<=5&&record.getTasteNum()>=0) { Num1+=record.num; getTasteNum1 +=record.getTasteNum()*record.num; } } getTasteNum1= getTasteNum1 /Num1; return (int)Math.round(getTasteNum1); } public int getTasteNum2() { int Num2=0; double getTasteNum2=0; for (Record record : records) { if(record.dish.Flag==2&&record.tasteNum<=4&&record.getTasteNum()>=0) { Num2+=record.num; getTasteNum2 +=record.getTasteNum()*record.num; } } getTasteNum2= getTasteNum2 /Num2; return (int)Math.round(getTasteNum2); } public int getTasteNum3() { int Num3=0; double getTasteNum3=0; for (Record record : records) { if(record.dish.Flag==3&&record.tasteNum<=3&&record.getTasteNum()>=0) { Num3+=record.num; getTasteNum3 +=record.getTasteNum()*record.num; } } getTasteNum3= getTasteNum3 /Num3; return (int)Math.round(getTasteNum3); } public Record addARecord(int orderNum, String dishName,int tasteNum, int portion, int num, Menu menu) { Dish dish = menu.searchDish(dishName); if (dish == null || dish.unit_price == -1) { dish = menu.addDish(dishName, 0,0); } Record record = new Record(orderNum, dish,tasteNum, portion, num); records.add(record); return record; } public boolean delARecordByOrderNum(int orderNum) { for (Record record1 : records) { if (record1.orderNum==orderNum){ record1.isDel=true; record1.isDelOrSue=true; return true; } } return false; } } class Table { int Flag; int price_user; int tableNum; String user; String phoneNum; String date; String time; Order order = new Order(); public Table(int tableNum,String user,String phoneNum, String date, String time) { this.tableNum = tableNum; this.user = user; this.phoneNum = phoneNum; this.date = date; this.time = time; } public String getTaste1() { int TasteNum1 = order.getTasteNum1(); if(TasteNum1==0) { return "不辣"; } if(TasteNum1==1) { return "微辣"; } if(TasteNum1==2) { return "稍辣"; } if(TasteNum1==3) { return "辣"; } if(TasteNum1==4) { return "很辣"; } if(TasteNum1==5) { return "爆辣"; } return date; } public String getTaste2() { int TasteNum2 = order.getTasteNum2(); if(TasteNum2==0) { return "不酸"; } if(TasteNum2==1) { return "微酸"; } if(TasteNum2==2) { return "稍酸"; } if(TasteNum2==3) { return "酸"; } if(TasteNum2==4) { return "很酸"; } return date; } public String getTaste3() { int TasteNum3 = order.getTasteNum3(); if(TasteNum3==0) { return "不甜"; } if(TasteNum3==1) { return "微甜"; } if(TasteNum3==2) { return "稍甜"; } if(TasteNum3==3) { return "甜"; } return date; } public int getNum1() { return order.getNum1(); } public int getNum2() { return order.getNum2(); } public int getNum3() { return order.getNum3(); } //普通菜折扣 public double getDiscount1() { double discount1 = 1.0; String weekday = getWeekday(date); if (time.contains("/")){ time = time.replaceAll("/", ":"); // 将斜杠替换为冒号 String[] timeParts = time.split(":"); // 将时间拆分为小时、分钟和秒钟 if (timeParts[0].length() < 2) { timeParts[0] = "0" + timeParts[0]; // 如果小时部分缺少前导零,则添加前导零 } time= String.join(":", timeParts); // 将时间部分重新组合为一个字符串 } if (weekday.equals("Saturday") || weekday.equals("Sunday")) { if (!isOpeningTime(time)) { return 0; } } else if (weekday.equals("Monday") || weekday.equals("Tuesday") || weekday.equals("Wednesday") || weekday.equals("Thursday") || weekday.equals("Friday")) { if (isOpeningTime(time)) { if (time.compareTo("10:30:00") >= 0 && time.compareTo("14:30:00") <= 0) { discount1 = 0.6; } else if (time.compareTo("17:00:00") >= 0 && time.compareTo("20:30:00") <= 0) { discount1 = 0.8; } else { return 0; } } } return discount1; } //特色菜折扣 public double getdiscount2() { double discount2 = 1.0; String weekday = getWeekday(date); if (time.contains("/")){ time = time.replaceAll("/", ":"); // 将斜杠替换为冒号 String[] timeParts = time.split(":"); // 将时间拆分为小时、分钟和秒钟 if (timeParts[0].length() < 2) { timeParts[0] = "0" + timeParts[0]; // 如果小时部分缺少前导零,则添加前导零 } time= String.join(":", timeParts); // 将时间部分重新组合为一个字符串 } if (weekday.equals("Saturday") || weekday.equals("Sunday")) { if (!isOpeningTime(time)) { return 0; } } else if (weekday.equals("Monday") || weekday.equals("Tuesday") || weekday.equals("Wednesday") || weekday.equals("Thursday") || weekday.equals("Friday")) { if (isOpeningTime(time)) { if (time.compareTo("10:30:00") >= 0 && time.compareTo("14:30:00") <= 0) { discount2 = 0.7; } else if (time.compareTo("17:00:00") >= 0 && time.compareTo("20:30:00") <= 0) { discount2 = 0.7; } else { return 0; } } } return discount2; } public int getTotalPrice(){//折扣后的总价 int totalPrice; int totalPrice1 = 0; int totalPrice2 = 0; for(Record record : order.records){ if(record.dish.Flag==0){ totalPrice1 +=(int)Math.round(record.getPrice()*getDiscount1()); } if((record.dish.Flag==1&&record.tasteNum<=5)||(record.dish.Flag==2&&record.tasteNum<=4)||(record.dish.Flag==3&&record.tasteNum<=3)){ totalPrice2 +=(int)Math.round(record.getPrice()*getdiscount2()); } } totalPrice = totalPrice1 + totalPrice2; return totalPrice; } public int getTotalPrice_yuan(){//折扣前的总价 int totalPrice_yuan; int totalPrice1_yuan = 0; int totalPrice2_yuan = 0; for(Record record : order.records){ if(record.dish.Flag==0){ totalPrice1_yuan += Math.round(record.getPrice()); } if((record.dish.Flag==1&&record.tasteNum<=5)||(record.dish.Flag==2&&record.tasteNum<=4)||(record.dish.Flag==3&&record.tasteNum<=3)){ totalPrice2_yuan += Math.round(record.getPrice()); } } totalPrice_yuan = totalPrice1_yuan + totalPrice2_yuan; return totalPrice_yuan; } private String getWeekday(String date){ String[] parts = date.split("/"); int year = Integer.parseInt(parts[0]); int month = Integer.parseInt(parts[1]); int day = Integer.parseInt(parts[2]); Calendar calendar = Calendar.getInstance(); calendar.set(year, month - 1, day); int weekdayIndex = calendar.get(Calendar.DAY_OF_WEEK) - 1; String[] weekdays = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; return weekdays[weekdayIndex]; } private boolean isOpeningTime(String time) { return time.compareTo("09:30:00") >= 0 && time.compareTo("21:30:00") <= 0; } }
7-1 测验1-圆类设计
1)类图
2)分析
这段代码是一个简单的Java程序,用于计算矩形的面积。代码中定义了一个名为Main的类,在类中有四个私有变量x1、y1、x2和y2,分别表示矩形的两个对角点的坐标。构造函数用于初始化这些坐标值。 类中定义了一个名为getArea()的方法,用于计算矩形的面积。面积计算的方法是首先通过取两个横坐标之差和。
3)源码
import java.util.Scanner; class Circle { private double radius; public Circle(double radius) { this.radius = radius; } public double getArea() { return Math.PI * radius * radius; } } public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); double radius = scanner.nextDouble(); if (radius <= 0) { System.out.println("Wrong Format"); } else { Circle circle = new Circle(radius); String area = String.format("%.2f", circle.getArea()); System.out.println(area); } } }
7-2 测验2-类结构设计
1)类图
2)分析
这段代码是一个简单的Java程序,它计算并输出给定矩形的面积。 程序首先导入了`java.util.Scanner`类,以便从命令行读取输入。 然后定义了一个名为`Main`的类,该类具有四个私有变量`x1`、`y1`、`x2`和`y2`,这些变量表示矩形的两个对角点坐标。 类`Main`还定义了一个构造函数,用于初始化矩形的坐标。 接下来,`Main`类还拥有一个`getArea`方法,用于计算并返回矩形的面积。该方法使用Math类中的`abs`方法计算矩形的长度和宽度,并将它们相乘得到矩形的面积。 最后,`Main`类中的`main`方法是程序的入口点。它首先创建一个Scanner对象来读取控制台输入。然后,它依次读取四个浮点数,分别赋值给`x1`、`y1`、`x2`和`y2`。接下来,创建一个`Main`对象,传递这些输入参数来初始化矩形。然后,通过调用`getArea`方法计算矩形的面积,并将结果存储在`area`变量中。最后,使用`System.out.printf`方法将`area`变量的值输出到控制台,并保留两位小数。 所以,这段代码的作用是读取两组坐标值,表示一个矩形的对角线的两个点,然后计算并输出该矩形的面积。
3)源码
import java.util.Scanner; public class Main { private double x1; private double y1; private double x2; private double y2; public Main(double x1, double y1, double x2, double y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; } public double getArea() { double length = Math.abs(x2 - x1); double width = Math.abs(y2 - y1); return length * width; } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); double x1 = scanner.nextDouble(); double y1 = scanner.nextDouble(); double x2 = scanner.nextDouble(); double y2 = scanner.nextDouble(); Main rectangle = new Main(x1, y1, x2, y2); double area = rectangle.getArea(); System.out.printf("%.2f", area); } }
7-3 测验3-继承与多态
2)分析
这段代码是一个简单的Java程序,用于计算不同形状的图形的面积。 代码首先导入了`java.util.Scanner`类,以便从命令行读取输入。 然后定义了一个名为`Main`的类,其中包含一个`main`方法。在这个方法中,首先创建了一个Scanner对象来读取控制台输入。然后,读取一个整数`choice`,其表示用户选择的图形类型。 接下来,使用`switch`语句根据用户的选择执行不同的分支。如果用户选择了1,表示他们想计算圆形的面积。此时,程序会读取一个浮点数`radius`,表示圆的半径。然后,创建一个`Circle`对象,传递半径来初始化它,并调用`printArea`方法输出圆的面积。 如果用户选择了2,表示他们想计算矩形的面积。此时,程序会读取四个浮点数,分别为矩形的左上角点和右下角点的坐标。然后,创建一个`Point`对象表示矩形的左上角点和右下角点的坐标,再创建一个`Rectangle`对象,传递左上角点和右下角点来初始化它,并调用`printArea`方法输出矩形的面积。 在`printArea`方法中,接受一个`Shape`对象作为参数,并调用它的`getArea`方法来计算该图形的面积。最后,使用`System.out.printf`方法将面积输出到控制台,并保留两位小数。 代码中还定义了一个抽象类`Shape`,它具有一个抽象方法`getArea`,用于计算各种形状的图形的面积。`Circle`和`Rectangle`是`Shape`的子类,它们分别实现了`getArea`方法以计算圆形和矩形的面积。 此外,代码还定义了一个`Point`类,用于表示一个点的坐标。 所以,这段代码的作用是根据用户的选择计算圆形或矩形的面积,并输出结果。
3)源码
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int choice = input.nextInt(); switch(choice) { case 1://Circle double radius = input.nextDouble(); Shape circle = new Circle(radius); 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; } } public static void printArea(Shape shape) { double area = shape.getArea(); System.out.printf("%.2f", area); } } abstract class Shape { public abstract double getArea(); } class Circle extends Shape { private double radius; public Circle(double radius) { this.radius = radius; } public double getArea() { return Math.PI * radius * radius; } } class Rectangle extends Shape { private Point leftTopPoint; private Point lowerRightPoint; public Rectangle(Point leftTopPoint, Point lowerRightPoint) { this.leftTopPoint = leftTopPoint; this.lowerRightPoint = lowerRightPoint; } public double getArea() { double width = Math.abs(lowerRightPoint.getX() - leftTopPoint.getX()); double height = Math.abs(lowerRightPoint.getY() - leftTopPoint.getY()); return width * height; } } class Point { private double x; private double y; public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public double getY() { return y; } }
7-4 测验4-抽象类与接口
1)类图
2)分析
这段代码是一个Java程序,用于计算并按面积大小对圆形和矩形进行排序,并输出它们的面积。 代码首先导入了`java.util.ArrayList`、`java.util.Comparator`和`java.util.Scanner`类。 然后定义了一个名为`Main`的类,其中包含主要的`main`方法。在这个方法中,首先创建了一个Scanner对象来读取控制台输入。接下来,创建了一个ArrayList集合`list`,用于存储图形对象。 然后,读取一个整数`choice`,其表示用户选择的图形类型。 通过使用`while`循环,当用户输入的选择为0时,循环终止。进入循环体后,使用`switch`语句根据用户的选择执行不同的分支。 如果用户选择了1,表示他们想计算圆形的面积。此时,程序会读取一个浮点数`radius`,表示圆的半径。然后,创建一个`Circle`对象,传递半径来初始化它,并将它添加到`list`集合中。 如果用户选择了2,表示他们想计算矩形的面积。此时,程序会读取四个浮点数,分别为矩形的左上角点和右下角点的坐标。然后,创建一个`Point`对象表示矩形的左上角点和右下角点的坐标,再创建一个`Rectangle`对象,传递左上角点和右下角点来初始化它,并将它添加到`list`集合中。 在循环的末尾,再次读取`choice`的值,以便判断是否需要继续循环。 接下来,通过调用`list`集合的`sort`方法,使用`Comparator.naturalOrder()`来对图形进行正向排序,即按照图形的面积大小进行排序。 最后,通过使用`for`循环遍历`list`集合,获取每个图形的面积,并使用`System.out.print`方法将其格式化输出,并以空格分隔。 代码中还定义了一个抽象类`Shape`,它继承了`Comparable`接口,该接口用于实现对象之间的比较。`Shape`类具有一个抽象方法`getArea`,用于计算各种形状的图形的面积。`Circle`和`Rectangle`是`Shape`的子类,它们分别实现了`getArea`方法以计算圆形和矩形的面积。`Shape`类还实现了`compareTo`方法,用于根据图形的面积进行比较。 除此之外,代码中还定义了一个`Point`类,用于表示一个点的坐标。 因此,这段代码的作用是根据用户的选择计算圆形或矩形的面积,并将它们按照面积大小排序输出。
3)源码
import java.util.ArrayList; import java.util.Comparator; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); ArrayList<Shape> list = new ArrayList<>(); int choice = input.nextInt(); while(choice != 0) { switch(choice) { case 1://Circle double radius = input.nextDouble(); Shape circle = new Circle(radius); 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()) + " "); } } } class Point { private double x; private double y; public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public double getY() { return y; } } class Circle extends Shape { private double radius; public Circle(double radius) { this.radius = radius; } public double getArea() { return Math.PI * radius * radius; } } abstract class Shape implements Comparable<Shape> { public abstract double getArea(); public int compareTo(Shape other) { double area1 = this.getArea(); double area2 = other.getArea(); if (area1 < area2) { return -1; } else if (area1 > area2) { return 1; } else { return 0; } } } class Rectangle extends Shape { private Point leftTopPoint; private Point lowerRightPoint; public Rectangle(Point leftTopPoint, Point lowerRightPoint) { this.leftTopPoint = leftTopPoint; this.lowerRightPoint = lowerRightPoint; } public double getArea() { double width = Math.abs(lowerRightPoint.getX() - leftTopPoint.getX()); double height = Math.abs(lowerRightPoint.getY() - leftTopPoint.getY()); return width * height; } }
三、主要困难及改进建议
主要困难:
1. 代码结构复杂:代码中嵌套了多个内部类,并且代码逻辑比较复杂,使得代码难以理解和维护。
2. 验证输入格式的逻辑冗长:代码中对输入格式进行了多个匹配和判断,导致代码冗长且繁琐。
3. 代码重复性高:在多个地方出现了重复的代码片段,例如菜品的添加和搜索、订单的处理等。
改进建议:
1. 优化代码结构:可以考虑将内部类提取为独立的类,避免代码的嵌套和复杂性。
2. 减少验证输入格式的逻辑:可以使用正则表达式或其他方式,简化对输入格式的验证,提高代码的可读性和简洁性。
3. 提取公共代码片段:将重复的代码片段提取为独立的方法,提高代码的重用性和可维护性。
4. 增加注释和文档:在代码中增加注释和文档,对代码逻辑进行详细的解释和说明,方便他人理解和维护代码。
总体来说,代码的功能实现是正确的,但存在一些可以优化和改进的地方,以提高代码的可读性、可维护性和效率性。
四、总结
通过今天的问题,我学到了如何设计和实现一个简单的点餐系统,并进行菜单、订单和用户信息的处理和计算。我了解了面向对象的设计原则和技巧,例如使用类和对象进行封装和组织代码、使用继承和多态实现不同类型的对象、使用接口和泛型增加代码的灵活性等。
需要进一步学习和研究的地方包括:
1. 面向对象的设计原则和模式:进一步学习和理解面向对象的设计原则和模式,例如单一职责原则、开放封闭原则、依赖倒置原则、工厂模式、策略模式等,以提高代码的灵活性和可扩展性。
2. 输入验证和异常处理:进一步学习和掌握如何有效验证用户输入的格式和内容,并进行适当的异常处理,以提高系统的健壮性和可靠性。
3. 代码优化和重构:进一步学习如何优化代码结构、简化和提取公共代码片段、减少代码重复性,以提高代码的可读性、可维护性和性能。
4. 数据结构和算法:进一步学习和研究数据结构和算法的知识,以提高对问题的处理效率和性能。
通过不断学习和研究这些方面的知识,我可以逐步提升自己的编程能力和设计思维,设计和实现更高质量、更灵活和可维护的软件系统。