blog-2、

发布时间 2023-11-19 23:41:33作者: 陈鹏祥

前三次作业总结blog

前言:

第4-6次作业题量不大,主要是四次菜单问题的迭代,难度比较大,第四次作业是菜单二和三,难度比较大主要是要分析到各种不同的情况,以满足题目要求,第五次作业和第六次作业都是在菜单三的基础上升级,其中第五次作业的菜单四相比于菜单三多了很多异常处理,会用到,try-catch语句。而菜单五相比于菜单四我觉得难度更小,它在菜单三的基础上增加了很多功能只要分析到位就可以很好解决。

设计与分析:

下面对个别具有代表性题目进行分析:

7-4 菜单计价程序-2

相关类图:IMG_256

IMG_256

相关类代码:

import java.util.Scanner;

public class Main {

public static void main(String[] args) {

// Dish[] dish = new Dish[10086];

// Record[] record = new Record[10086];

String[] d = new String[10086];//存放原始输入信息

//String[] e = new String[10086];//存放菜品记录

//String[] f = new String[10086];//存放点菜记录

//String[] g = new String[10086];//存放删除信息

Menu menu = new Menu();

Order order = new Order();

int i = 0,r=0,o=0;

Scanner input = new Scanner(System.in);

//将输入信息存入字符串数组

while (true) {

d[i] = input.nextLine();

if (d[i].equals("end")) {

break;

}

i++;

}

for(int j=0;j<i;j++)

{

String[] str = d[j].split(" ");

char lastchar=str[str.length-1].charAt(0);

if(str.length==2&&Character.isDigit(lastchar))

{

String name = str[0];

int unit_price = Integer.parseInt(str[1]);

menu.dishs[o]=new Dish();

menu.dishs[o]=menu.addDish(name, unit_price);

//System.out.println(menu.dishs[o].name+menu.dishs[o].unit_price);

o++;

}

else if(str.length==4)

{

int orderNum = Integer.parseInt(str[0]);

String dishname = str[1];

int portion = Integer.parseInt(str[2]);

int num = Integer.parseInt(str[3]);

// System.out.println(orderNum+" "+dishname+" "+portion+" "+num+"\n");

order.addARecord(orderNum, dishname, portion, num, menu);

r++;

}

else if(str.length==2&&Character.isLetter(lastchar))

{

int deletenumber = Integer.parseInt(str[0]);

// System.out.println(deletenumber+"\n");

order.delARecordByOrderNum(deletenumber,menu);//根据序号删除

}

}

/*

for (int m = 0; order.records[m]!=null; m++) {

Dish fdish=new Dish();

if(order.records[m].d==null)

{order.records[m].d=new Dish();}

fdish = menu.searthDish(order.records[m].d.name);

if (fdish == null) {

System.out.println(order.records[m].d.name + "does not exist");

} else {

System.out.println(order.records[m].orderNum+order.records[m].d.name+order.records[m].getPrice());

}

}*/

for (int y=0;y<r;y++)

{

// System.out.println(order.records[y].orderNum+" "+order.records[y].number+"\n");

}

System.out.print(order.getTotalPrice());

}

}

class Dish {

String name;//菜品名称

int unit_price; //单价

int getPrice(int portion,int unit_price)//计算菜品价格的方法,输入参数是点菜的份额(输入数据只能是1/2/3,代表小/中/大份)

{

int price = (int) Math.round((1 + (portion - 1) * 0.5) * unit_price);

return price;

}

}

class Menu {

Dish[] dishs = new Dish[100] ;//菜品数组,保存所有菜品信息

int i = 0;

/* public Menu() {

}

*/

Dish searthDish(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。

{

for (int x=0;x<i;x++)

{

if( dishs[x]!=null)

{

if ( dishName.equals(dishs[x].name)) { // 判断 dish 是否为 null

return dishs[x];

}

}

}

return null;

}

int searthDish1(String dishName)//根据菜名在菜谱中查找菜品信息,返回Dish对象。

{

for (int x=0;x<i;x++)

{

if( dishs[x]!=null) {

if (dishName.equals(dishs[x].name)) { // 判断 dish 是否为 null

return x;

}

}

}

return -1;

}

Dish addDish(String dishName, int unit_price)//添加一道菜品信息

{

int x=-2;

x=searthDish1(dishName);

if(x==-1){

dishs[i].name = dishName;

dishs[i].unit_price = unit_price;

i++;}

else

{ dishs[x].name = dishName;

dishs[x].unit_price = unit_price;

}

return dishs[i-1];

}

}

class Record {

int orderNum;//序号\

Dish d=new Dish();//菜品\

int portion;//份额(1/2/3代表小/中/大份)\

int number;//份数;

int getPrice()//计价,计算本条记录的价格\

{

int price = number * d.getPrice(portion,d.unit_price);

return price;

}

}

class Order {

Record[] records=new Record[100];//保存订单上每一道的记录

int i = -1;

public Order() {

}

int getTotalPrice()//计算订单的总价

{

int price = 0;

for (int j=0;records[j]!=null;j++) {

price += records[j].getPrice();

}

return price;

}

Record addARecord(int orderNum, String dishName, int portion, int num, Menu menu)//添加一条菜品信息到订单中。

{

i++;

records[i] = new Record();// 创建 Record 对象

records[i].d=new Dish();

records[i].orderNum = orderNum;

records[i].portion = portion;

records[i].number = num;

if(menu.searthDish(dishName)==null)

{

System.out.print(dishName+" does not exist\n");

}

else

{

records[i].d= menu.searthDish(dishName);

System.out.print(orderNum+" "+dishName+" "+records[i].getPrice()+"\n");

}

return records[i];

}

void delARecordByOrderNum(int orderNum,Menu menu)//根据序号删除一条记录

{

int j;

for ( j = 0;records[j]!=null; j++) {

if (records[j].orderNum == orderNum)

{

if(records[j].d.name==null)

{

// System.out.print("delete error;\n");

}

else

{

/*

for (int k = j; records[k + 1] != null; k++) {

records[k] = records[k + 1];

records[k]

records[records.length - 1] = null;

}

*/

records[j].number=0;

}

}

}

if(j<orderNum){

System.out.print("delete error;\n");

}

}

Record findRecordByNum(int orderNum)//根据序号查找一条记录

{

for (int j = 0; j < records.length; j++) {

if (records[j].number == orderNum) {

return records[j];

}

}

records[10086].number = 10086;

return records[10086];

}

}

分析:从类图和时间空间复杂度分析可以看出它包含了四个类:Dish(菜品)、Menu(菜单)、Record(记录)和Order(订单)。

Dish类:

属性:name(菜品名称)、unit_price(单价)

方法:getPrice(),根据菜品的份额和单价计算价格

Menu类:

属性:dishs(菜品数组)

方法:searthDish(),根据菜名在菜谱中查找菜品信息;searthDish1(),根据菜名在菜谱中查找菜品信息并返回索引;addDish(),添加一道菜品信息到菜单中

Record类:

属性:orderNum(序号)、d(菜品对象)、portion(份额)、number(份数)

方法:getPrice(),计算本条记录的价格

Order类:

属性:records(记录数组)

方法:getTotalPrice(),计算订单的总价;addARecord(),向订单中添加一条菜品记录;delARecordByOrderNum(),根据序号删除一条记录;findRecordByNum(),根据序号查找一条记录

7-1 菜单计价程序-3

相关类图:IMG_256

IMG_256

分析:通过类图可以看出此代码包括

Dish类:

该类表示菜品,包括菜品名称和单价,以及计算菜品价格的方法。但是在 getPrice 方法中只允许输入 1/2/3,代表小/中/大份,这种硬编码的方式不够灵活,可以考虑使用枚举类型来表示份额。

Menu类:

用于管理所有菜品信息,包括添加菜品和根据菜名查找菜品信息等功能。但是在添加菜品时,使用了数组来保存菜品信息,没有考虑到扩容的问题,如果菜品数量超过1000个会出现数组越界的问题。

Record类:

表示订单中的一条记录,包括菜品、序号、份额、份数等信息,可以计算本条记录的价格。但是属性命名不够清晰,不易理解每个属性的含义,推荐改进属性命名。

Order类:

表示一个订单,包括保存订单上每一道菜品的记录、计算订单的总价、添加菜品信息到订单中、根据序号删除一条记录等功能。在添加记录和计算订单总价的过程中,代码逻辑比较混乱,建议进行简化和优化。

Main类:

包含主程序入口,实现了具体的点餐逻辑和桌号管理。但是代码结构比较混乱,逻辑相对复杂,可以考虑将部分功能抽离成单独的方法或类来提高可读性和维护性。

table类:

表示一张餐桌,包括桌号、点菜时间、计算总价、判断时间是否在营业时间内等功能。在计算总价和判断营业时间的逻辑中,存在硬编码的问题,应该将这些逻辑提取成单独的方法或常量以提高可维护性。

菜单计价程序-4

相关类图:IMG_256IMG_256IMG_256

IMG_256

分析:菜品类(Food)

属性:

name:菜品名称

price:菜品价格

菜谱类(Menu)

属性:

foods:菜谱中包含的菜品列表

方法:

addFood(Food food):将菜品添加到菜谱中

removeFood(Food food):从菜谱中移除指定的菜品

点菜记录类(OrderRecord)

属性:

food:被点的菜品

quantity:点菜的数量

订单类(Order)

属性:

orderRecords:订单中包含的点菜记录列表

方法:

addOrderRecord(OrderRecord record):将点菜记录添加到订单中

removeOrderRecord(OrderRecord record):从订单中移除指定的点菜记录

calculateTotalPrice():计算订单的总价格

属性:

tableNumber:桌号

orders:桌子上的订单列表

方法:

addOrder(Order order):将订单添加到桌子上

removeOrder(Order order):从桌子上移除指定的订单

错误判断类(ErrorChecking)

方法:

checkValidInput(String input):检查用户输入是否有效

这些类主要通过属性和方法的组合来实现餐厅点餐系统的功能。其中,菜品类表示一个具体的菜品,菜谱类管理菜谱信息,点菜记录类记录点菜信息,订单类表示一个具体的订单,桌子类表示一个具体的桌子,错误判断类用于检查用户输入的有效性。

通过这些类和方法的组合使用,可以实现点菜、加桌、删菜等功能。

7-1 菜单计价程序-5

相关类图IMG_256

IMG_256

首先,我们看到了 Dish 类。这个类用于表示菜品,包括菜品名称、口味、单价等属性,以及计算菜品价格的方法。这个类的设计相对清晰,但是可能需要注意的是口味和等级的表示方式,可能需要进一步的说明或者使用枚举类型来表示。

接下来是 Menu 类,它用于管理菜单,包括菜品数组,保存所有菜品信息,并提供了添加菜品、查找菜品等方法。这个类的设计也比较合理,但在实际应用中可能需要考虑更高效的菜品查找方式。

然后是 Record 类,用于表示订单中的每一道菜品的记录,包括菜品、序号、口味、等级、份额等属性,并提供了计价的方法。这个类的设计也比较清晰,但可能需要注意口味和等级的表示方式,以及计价方法的实现逻辑。

接着是 Order 类,用于保存订单上每一道的记录,并提供了添加记录、删除记录、计算总价等方法。这个类的设计也比较合理,但可能需要注意记录的管理方式,以及计算总价的逻辑。

然后是 Table 类,表示餐桌,包括桌号、顾客信息、时间等属性,并提供了判断时间是否正确的方法。这个类的设计也比较清晰,但可能需要考虑更全面的餐桌状态管理。

最后是 Customer 类,表示顾客信息,包括姓名、电话、支付金额等属性。这个类的设计也比较简单清晰。

7-1 测验1-圆类设计

相关类代码import java.util.Scanner;

class Circle {

private double r;

private double s;

public double getR() {

return r;

}

public void setR(double r) {

this.r = r;

}

public double getS() {

return Math.PI*r*r;

}

public void setS(double s) {

this.s = s;

}

}

public class Main {

public static void main(String[] args) {

Circle c=new Circle();

Scanner sc = new Scanner(System.in);

double a=sc.nextDouble();

if(a<=0){

System.out.println("Wrong Format");

}

else {

c.setR(a);

double ss= c.getS();

System.out.println(String.format("%.2f",ss));

}

}

}

分析:此题比较简单:是对类的基本应用,只要设了类,对类进行运用就没有问题。

7-3 测验3-继承与多态

IMG_256

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 radiums = input.nextDouble();

if (radiums <= 0) {

System.out.println("Wrong Format");

return;

}

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;

}

}

public static void printArea(Shape shape) {

System.out.printf("%.2f", shape.getArea());

}

}

abstract class Shape {

public abstract double getArea();

}

class Circle extends Shape {

private double r;

public Circle(double r) {

this.r = r;

}

public double getR() {

return r;

}

public void setR(double r) {

this.r = r;

}

@Override

public double getArea() {

return Math.PI * r * r;

}

}

class Rectangle extends Shape {

private Point leftTopPoint;

private Point lowerRightPoint;

public Rectangle(Point leftTopPoint, Point lowerRightPoint) {

this.leftTopPoint = leftTopPoint;

this.lowerRightPoint = lowerRightPoint;

}

@Override

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-抽象类与接口

import java.util.Scanner;

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 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();

}

//Collections.sort(list);

list.sort(Comparator.naturalOrder()); // 使用默认的升序排序

for (int i = 0; i < list.size(); i++) {

System.out.print(String.format("%.2f", list.get(i).getArea()) + " ");

}

}

}

abstract class Shape implements Comparable<Shape> {

public abstract double getArea();

@Override

public int compareTo(Shape o) {

return Double.compare(this.getArea(), o.getArea());

}

}

class Circle extends Shape {

private double radiums;

public Circle(double radiums) {

this.radiums = radiums;

}

@Override

public double getArea() {

return Math.PI * radiums * radiums;

}

}

class Rectangle extends Shape {

private Point leftTopPoint;

private Point lowerRightPoint;

public Rectangle(Point leftTopPoint, Point lowerRightPoint) {

this.leftTopPoint = leftTopPoint;

this.lowerRightPoint = lowerRightPoint;

}

@Override

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;

}

}

分析:此题是在第三题的基础的改进,主要加了接口部分知识,属于是老师上课讲的内容,没有难度

踩坑心得:

  1. 分清类和对象的区别,在调用对象前一定要初始化对象,否则就会出现对象为空的异常。比如这样

IMG_256

  1. 而且一定要保证数据存入对象

主要困难以及改进建议:

  1. 区分不清静态和动态的区别,不知道什么时候用什么类型的。最后通过查找资料明白了静态的内容,基于类而存在,非静态的内容基于对象而存在。也就是说静态内容是一类事物(即基于该类的所有对象)的共有特征,而非静态内容每个对象的独有特征。静态内容一旦修改,所有对象都会被影响,修改非静态内容,只会影响当前对象。
  2. 对于如何构造父类以及运用还不够熟练。
  3. 其次对于异常处理,try-catch语句的应用还需要多多练习。

总结:

  1. 经过这几次的pta以及期中考试,我对于Java有了更清晰的认知,已经不再是那么陌生,对于一个编程性问题我能很快想到如何运用Java思想来解决。
  2. 其次在这几次作业和考试中我也学习,掌握了多态的运用,以及异常处理问题。对于Java语言学习的深度更深了。
  3. 经过这几次的菜单问题,我对于一个问题的思考也更加全面,为以后得Java编程奠定了基础。