1.前言
在这三次的题目集中,主要涉及到了面向对象的相关知识点,包括类、对象、构造函数、封装、继承和多态等。我们学习了很多有关面向对象编程和软件设计的知识。这三次的题目集中,题目量和难度都有一定的增加。难度最大的题目集3中,我们需要设计一个完整的菜单计价系统,这一份题目集对于我们来说是最有难度的,需要掌握更多的知识点,包括结构体和链表等,这是我们在本学期中收获最大的一次作业了。
2.设计与分析
设计部分,我们需要重点分析题目集2中7-1、7-2以及题目集3中7-1三道菜单计价系列的题目。在这三道题目中,我们需要设计一个menu类以及与之相关的dish、order和customer类。在设计过程中,我们需要考虑到各个类之间的关系,并且要注意代码的扩展性和复用性。
在源码分析过程中,我们使用了SourceMonitor来统计代码的各项指标。可以发现,题目集3中的代码量和复杂度都较大,需要更加细致的设计和实现。同时,我们也使用了PowerDesigner来进行相应的类图设计和分析。通过类图,我们可以更加清晰地看到类与类之间的关系。在菜单计价系统中,我们可以看到dish类与menu类的聚合关系,order类与menu类的继承关系,customer类与menu类的关联关系等等。
在分析中,我们还需要关注算法的设计和实现。在菜单计价系统中涉及到了很多不同的算法,比如点餐算法、扣除库存算法、计算总价算法等等。我们需要仔细思考和实现这些算法,同时也需要对算法的复杂度进行分析和优化。
作业7-1
class Dish {
String name; //菜品名称
int basePrice; //菜品基础价格
public Dish(String name, int basePrice) {
this.name = name;
this.basePrice = basePrice;
}
public String getName() {
return name;
}
public int getBasePrice() {
return basePrice;
}
public double getPrice(int portion) {
double price = basePrice;
switch (portion) {
case 2:
price *= 1.5;
break;
case 3:
price *= 2;
break;
default:
price *= 1;
break;
}
return Math.round(price * 100) / 100.0; //四舍五入
}
}
class Menu {
private Dish[] dishes; //菜品列表
public Menu(Dish[] dishes) {
this.dishes = dishes;
}
public Dish searchDish(String name) {
//通过菜品名称查找菜品信息
for (Dish dish : dishes) {
if (dish.getName().equals(name)) {
return dish;
}
}
return null;
}
}
class Record {
private Dish dish; //菜品信息
private int quantity; //菜品数量
private int portion; //份额
public Record(Dish dish, int quantity, int portion) {
this.dish = dish;
this.quantity = quantity;
this.portion = portion;
}
public double getTotalPrice() {
double price = dish.getPrice(portion) * quantity;
return Math.round(price * 100) / 100.0; //四舍五入
}
}
class Order {
private Record[] records; //菜品记录列表
public Order() {
records = new Record[0];
}
public double getTotalPrice() {
double totalPrice = 0;
for (Record record : records) {
totalPrice += record.getTotalPrice();
}
return Math.round(totalPrice * 100) / 100.0; //四舍五入
}
public void addRecord(Dish dish, int quantity, int portion) {
Record record = new Record(dish, quantity, portion);
Record[] newRecords = new Record[records.length + 1];
System.arraycopy(records, 0, newRecords, 0, records.length);
newRecords[records.length] = record;
records = newRecords;
}
}
这份代码主要涉及到了面向对象的相关知识点,包括类、对象、构造函数、封装、继承和多态等。以下是对代码中具体的知识点的总结:
1. 类和对象:在这份代码中,我们定义了Dish、Menu、Record和Order这四个类。类是一个模板,用于描述具有相同属性和行为的一组对象,而对象则是类的一个实例,具有自己的属性和方法。
2. 构造函数:在Dish、Menu和Record这三个类中,我们都定义了构造函数。构造函数是一种特殊的方法,用于初始化一个对象。当我们创建一个对象时,会自动调用该对象对应的类的构造函数进行初始化。
3. 封装:在这份代码中,我们使用了private关键字将类的某些成员变量进行了封装,限制了外部对这些变量的直接访问。这种封装有助于保护对象的状态不被外部错误修改,并提高了代码的安全性和可维护性。
4. 继承和多态:这份代码中没有直接体现继承和多态的概念,不过面向对象的程序设计中,继承和多态是非常重要的概念。继承可以提高代码的复用性和可维护性,而多态则可以提高代码的灵活性和可扩展性。
5. 方法和参数:在这份代码中,我们定义了多个方法,包括构造函数、getPrice()和getTotalPrice()等。方法是对象可以执行的一系列操作,用于完成特定的功能。在这些方法的参数中,我们可以看到除了基本类型的int之外,还有一个Dish类型的参数,这是因为我们需要在Record类中保存菜品的详细信息。
总体来说,这份代码涉及的知识点并不复杂,但是对于初学者来说也需要花费比较长的时间和精力去理解和掌握。在理解这份代码的基础上,我们可以进一步对其进行拓展和改进,以适应不同的需求和场景。
作业7-2
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
class Dish {
private String name;
private int basePrice;
public Dish(String name, int basePrice) {
this.name = name;
this.basePrice = basePrice;
}
public String getName() {
return name;
}
public int getBasePrice() {
return basePrice;
}
public int getPrice(int portion) {
double price;
if (portion == 1) {
price = basePrice;
} else if (portion == 2) {
price = basePrice * 1.5;
} else if (portion == 3) {
price = basePrice * 2;
} else {
throw new IllegalArgumentException("Invalid portion: " + portion);
}
return (int) Math.round(price);
}
}
class Menu {
private Map<String, Dish> dishMap = new HashMap<>();
public Dish searchDish(String name) {
return dishMap.get(name);
}
public void addDish(String name, int basePrice) {
dishMap.put(name, new Dish(name, basePrice));
}
}
class Record {
private int orderNum;
private Dish dish;
private int portion;
private int num;
public Record(int orderNum, Dish dish, int portion, int num) {
this.orderNum = orderNum;
this.dish = dish;
this.portion = portion;
this.num = num;
}
public int getOrderNum() {
return orderNum;
}
public Dish getDish() {
return dish;
}
public int getPortion() {
return portion;
}
public int getNum() {
return num;
}
public int getPrice() {
return dish.getPrice(portion) * num;
}
}
class Order {
private Map<Integer, Record> recordMap = new HashMap<>();
public int getTotalPrice() {
int totalPrice = 0;
for (Record record : recordMap.values()) {
totalPrice += record.getPrice();
}
return totalPrice;
}
public Record addRecord(int orderNum, Dish dish, int portion, int num) {
Record record = new Record(orderNum, dish, portion, num);
recordMap.put(orderNum, record);
return record;
}
public void delRecordByOrderNum(int orderNum) {
recordMap.remove(orderNum);
}
public Record findByOrderNum(int orderNum) {
return recordMap.get(orderNum);
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Menu menu = new Menu();
Order order = new Order();
// 读入菜单
String line;
while (true) {
line = scanner.nextLine().trim();
if (line.equals("end")) {
break;
}
String[] fields = line.split(" ");
String name = fields[0];
int basePrice = Integer.parseInt(fields[1]);
menu.addDish(name, basePrice);
}
// 读入订单
int orderNum = 1;
while (true) {
line = scanner.nextLine().trim();
if (line.equals("end")) {
break;
}
String[] fields = line.split(" ");
if (fields.length == 2 && fields[1].equals("delete")) {
int delOrderNum = Integer.parseInt(fields[0]);
order.delRecordByOrderNum(delOrderNum);
} else if (fields.length == 4) {
String name = fields[1];
int portion = Integer.parseInt(fields[2]);
int num = Integer.parseInt(fields[3]);
Dish dish = menu.searchDish(name);
if (dish != null) {
order.addRecord(orderNum, dish, portion, num);
orderNum++;
}
}
}
// 输出总价格
System.out.println(order.getTotalPrice());
}
}
- 类和对象
在 Java 中,通过 class
关键字定义类,并通过 new
来创建对象。在本程序中,我们定义了几个类:Dish
、Menu
、Record
、Order
。其中,Dish
类表示菜品,包含菜名、基础价格和计价方法;Menu
类表示菜单,用于管理所有菜品;Record
类表示订单中的一道菜品记录,包含序号、菜品、份额、数量和计价方法;Order
类表示整个订单,包含若干条 Record
记录,以及计算订单总价的方法。
- 数组
数组是一种基本数据结构,在 Java 中,通过 []
定义一个数组变量,然后使用 new
创建一个具体的数组对象。在本程序中,我们定义了一些数组变量,用于保存菜单、记录和菜品等对象的信息。
- 集合
集合是一种高级数据结构,与数组相比,它在添加、删除和更新元素方面具有更好的灵活性,可以自动调整大小,且不需要事先指定容量。Java 中提供了各种集合类,常见的有 List
、Set
、Map
等。在本程序中,我们使用了 Map
集合,来存储菜单和订单中的信息。
- 异常处理
在 Java 中,异常是一种特殊的对象,用于表示程序中的错误或异常情况。在本程序中,我们使用了 IllegalArgumentException
异常来处理传入错误的份额参数的情况。
5.字符串操作
在本程序中,我们使用了许多字符串操作函数,如 String.trim()
、String.split()
、String.equals()
等。
作业3
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Judge judge=new Judge();
Menu menu=new Menu();
ArrayList<Discount> discounts=new ArrayList<>();
ArrayList<Table> tables=new ArrayList<>();
int tableNumber=0;
ArrayList<Order> orders=new ArrayList<>();
while (in.hasNext()){
String str=new String(in.nextLine());
if(str.equals("end")){//判断结束
break;
}
String[] strSplit=str.split(" ");
if(judge.isMenu(strSplit.length,strSplit[1])){//入菜单
menu.addDish(strSplit[0],Integer.parseInt(strSplit[1]));
}
if(judge.isTable(strSplit)){//输入桌子序号,时间
Discount discount=new Discount();
Order order=new Order();
order.setTableNumber(Integer.parseInt(strSplit[1]));
discount.setTime(strSplit[2],strSplit[3]);
discounts.add(discount);
orders.add(order);
tableNumber++;
}
if(judge.isRecord(strSplit)){//输入订单
int orderNum=Integer.parseInt(strSplit[0]);
String dishName=strSplit[1];
int portion=Integer.parseInt(strSplit[2]);
int num=Integer.parseInt(strSplit[3]);
orders.get(tableNumber-1).addARecord(orderNum,dishName,portion,num);
orders.get(tableNumber-1).findRecordByNum(orderNum-1).setDish(menu);
}
if(judge.isDelete(strSplit.length,strSplit[1])){ //table.setDeleteNumber(Integer.parseInt(strSplit[0]));
orders.get(tableNumber-1).setDeleteNumber(Integer.parseInt(strSplit[0]));
}
}
//输出
for(int i=0;i<orders.size();i++){
System.out.println("table "+orders.get(i).getTableNumber()+": ");
for(int j=0;j<orders.get(i).getRecordNumber();j++){
System.out.println(j+1+" "+orders.get(i).findRecordByNum(j).getDish().getName()+" "+orders.get(i).findRecordByNum(j).getPrice());
}
Table table=new Table(); if(orders.get(i).hasDelete(orders.get(i).getDeleteNumber())){
orders.get(tableNumber-1).delARecordByOrderNum(orders.get(i).getDeleteNumber());
}
table.setTototalPrice((int)(orders.get(i).getTotalPrice()*judge.judgeTimeDiscount(discounts.get(i))+0.5));
tables.add(table);
}
for(int i=0;i<tables.size();i++){
System.out.println("table"+" "+(i+1)+":"+" "+tables.get(i).getTototalPrice());
}
}
}
class Discount{
int year;
int month;
int day;
int hour;
int minute;
int second;
Discount(){}
void setTime(String timeDay,String timeHour){
String[] timeDaySplit = timeDay.split("/");
String[] timeHourSplit =timeHour.split("/");
this.year=Integer.parseInt(timeDaySplit[0]);
this.month=Integer.parseInt(timeDaySplit[1]);
this.day=Integer.parseInt(timeDaySplit[2]);
this.hour=Integer.parseInt(timeHourSplit[0]);
this.minute=Integer.parseInt(timeHourSplit[1]);
this.second=Integer.parseInt(timeHourSplit[2]);
}
public int getDay() {
return day;
}
public int getHour() {
return hour;
}
public int getMinute() {
return minute;
}
public int getMonth() {
return month;
}
public int getSecond() {
return second;
}
public int getYear() {
return year;
}
}
class Judge{
Judge(){}
boolean isMenu(int length,String string){
if(length==2&&!string.equals("delete")){
return true;
}
else{
return false;
}
}
boolean isRecord(String[] strSplit){
if(strSplit.length==4&&!strSplit[0].equals("table")){
return true;
}
else{
return false;
}
}
boolean isTable(String[] strSplit){
if(strSplit[0].equals("table")){
return true;
}
else{
return false;
}
}
boolean isDelete(int length,String string){
if(length==2&&string.equals("delete")){
return true;
}
else{
return false;
}
}
double judgeTimeDiscount(Discount discount){
if(discount.getHour()>=17&&discount.getHour()<20||(discount.getHour()==20&&discount.getMinute()<20)){
return 0.8;
}
else if((discount.getHour()==10&&discount.getMinute()>=30)||discount.getHour()>11&&discount.getHour()<14||(discount.getHour()==14&&discount.getMinute()<30)){
return 0.6;
}
return 1;
}
}
class Dish{
String name;//菜品名称
int unit_price; //单价
Dish(){}
Dish(String name,int unit_price){
this.name=name;
this.unit_price=unit_price;
}
void setName(String name){
this.name=name;
}
void setUnit_price(int unit_price){
this.unit_price=unit_price;
}
String getName(){
return this.name;
}
int getUnit_price(){
return this.unit_price;
}
int getPrice(int portion){//计算菜品价格
if(portion==1){
return (int)unit_price;
}
else if(portion==2){
return (int)(unit_price*1.5+0.5);
}
else if(portion==3){
return (int)unit_price*2;
}
return 1;
}
}
class Menu{
ArrayList<Dish> dishs=new ArrayList<>();//菜品数组,保存所有菜品信息
Dish searthDish(String dishName){//根据菜名在菜谱中查找菜品信息,返回Dish对象。
for(int i=0;i<dishs.size();i++){
if(dishs.get(i).getName().equals(dishName)){
return dishs.get(i);
}
}
return dishs.get(1);
}
void addDish(String dishName,int unit_price){//添加一道菜品信息
Dish dish=new Dish(dishName,unit_price);
dishs.add(dish);
}
}
class Record{
int orderNum;//序号
Dish d=new Dish();//菜品
int portion;//份额(1/2/3代表小/中/大份)
int numberOfDish;
String dishName;
Record(int orderNum,String dishName,int portion,int num){
this.orderNum=orderNum;
this.dishName=dishName;
this.portion=portion;
this.numberOfDish=num;
}
void setDish(Menu menu){//存入订单中
this.d=menu.searthDish(this.dishName);
}
int getOrderNum(){
return this.orderNum;
}
Dish getDish(){
return this.d;
}
int getPortion(){
return this.portion;
}
int getNumberDish(){
return this.numberOfDish;
}
void setOrderNum(int orderNum){
this.orderNum=orderNum;
}
void setDish(Dish dish){
this.d=dish;
}
void setPortion(int portion){
this.portion=portion;
}
void setNumberDish(int numberOfDish){
this.numberOfDish=numberOfDish;
}
int getPrice(){//计价,计算本条记录的价格
return (int)numberOfDish*d.getPrice(portion);
}
}
class Order{
//Record\[\] records;
int tableNumber;
int deleteNumber=0;
ArrayList<Record> records=new ArrayList<>();//保存订单上每一道的记录
int getTotalPrice(){//计算订单的总价
int totalPrice=0;
for(int i=0;i<records.size();i++){
totalPrice+=records.get(i).getPrice();
}
return totalPrice;
}
void setTableNumber(int tableNumber){
this.tableNumber=tableNumber;
}
int getTableNumber(){
return tableNumber;
}
void addARecord(int orderNum,String dishName,int portion,int num){//添加一条菜品信息到订单中。
Record record=new Record(orderNum,dishName,portion,num);
records.add(record);
}
void delARecordByOrderNum(int orderNum){//根据序号删除一条记录
records.remove(orderNum-1);
}
Record findRecordByNum(int orderNum){//根据序号查找一条记录
return records.get(orderNum);
}
int getRecordNumber(){
return records.size();
}
void setDeleteNumber(int deleteNumber){
this.deleteNumber=deleteNumber;
}
public int getDeleteNumber() {
return deleteNumber;
}
boolean hasDelete(int deleteNumber){
if(deleteNumber==0){
return false;
}
if(deleteNumber>0&&deleteNumber<records.size()){
return true;
}
else{
return false;
}
}
}
class Table{
int tototalPrice;
void setTototalPrice(int tototalPrice){
this.tototalPrice=tototalPrice;
}
int getTototalPrice(){
return this.tototalPrice;
}
}
- 类及类的属性和方法的定义
- 集合类Map、List等的使用方法
- 字符串的基本操作
- 输入输出的处理方式
- 基本的逻辑控制语句 if、switch、while等
同时,这道题还涉及到了对于时间和日期的处理方式和对于Java中小数的转换和四舍五入的处理方式。
踩坑心得
在提交过程中,遇到了很多问题。在作业三中需要我们对Java语言的基础知识和相关API有比较深入的掌握,同时也需要有一定的逻辑思维能力和综合性能力。
另外一个常见的问题就是代码的可维护性和扩展性。我们需要充分利用面向对象编程中的封装、继承和多态等概念,设计出易于扩展和维护的代码。
主要困难以及改进建议
在解题过程中,我们遇到了一些困难。比如,在菜单计价系统中,我们需要考虑数据库的设计和实现,这是我们之前没有接触过的内容。同时,在算法的设计和优化过程中,我们也遇到了一些困难。对于这些困难,我们需要更加努力地学习和提高自己的编程能力。
总结
在这三次的题目集中,我们学习了很多有关面向对象编程和软件设计的知识。通过实践,我们更加熟练地掌握了Java编程语言以及相关的工具和技术,同时也更加深入地理解了软件设计和开发的过程。也更深层次地理解上学期学的C语言(面对过程)和目前学习的Java语言(面对对象)的区别与相同之处。
标签:总结,题目,String,int,portion,Dish,return,public From: https://www.cnblogs.com/gp666666/p/17429029.html