blog作业一

发布时间 2023-05-24 21:47:20作者: 人世宇、歆蒂

前言:

在今年刚开始的时候,我们学习了JAVA面向对象程序设计,首先,我先了解了JAVA是一门怎样的编程语言。了解了它具有可移植性、安全性、高效性、简单性等特点,被广泛应用于企业级Web应用开发、移动应用开发、游戏开发、嵌入式系统开发等领域。首先先了解了它应该有的具体的特点。可移植性:Java程序可以在不同的操作系统和硬件平台上运行,而不需要重新编写代码。安全性:Java有一个安全模型,可以保证程序不会对系统造成损害。简单性,JAVA语言简单易懂,易于学习和使用。然后我们进行了学习与练习,主要练习了一个迭代的题目,点菜系列。主要还是学习了JAVA的基本的语法跟面向对象的特别于其他编程语言的特点。首先是用JAVA的基本语法写了一些简单的习题用来回顾和复习JAVA原因跟其他面向过程的编程语言共同之处,然后从JAVA语言的特点开始,学习了JAVA面向对象编程的特点封装、继承、多态、类、接口以及抽象类的学习。然后就是训练题目的点菜习题,难度较大,不易操作,需要用一定的时间才能够完成作业。下面主要分析三道点菜题目。

设计与分析:

第一道点菜题目的类图:

 

 

 

 

 

 

答题思路:首先进行写类图,通过类图的里面写的属性与方法,逐步加入进去,然后在主函数里面对象实例化来写一些东西来。

代码分析:

 

 

 

 

 

以上的类是把每一道菜的属性跟方法写出来,把菜肴的价格从主函数里面调用得到写出来。

class Menu{

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

    public void add(Dish dish)

    {

        int In = 0;

        if(dishs!=null)

            In = dishs.length;

       

            Dish[] tmp = new Dish[In+1];

            if(In>0)

            {

                System.arraycopy(dishs,0,tmp,0,In);

               

            }

            tmp[In] = dish;

            dishs = tmp;

       

    }

 

    Dish searthDish(String dishName){

        if(dishs==null)

            return null;

        for(int i=0;i<dishs.length;i++)

        {

            if(dishs[i].name.equals(dishName))

                return dishs[i];

        }

        return null;

    }

}

以上的是菜单类,用来记录菜系跟搜寻结束“end”,

主函数代码:

 

用一些String的方法跟实现成果的代码上来实现这个题的编写。学到了用一些String的方法实现一些功能的实现。

第二到题目的类图:

 

 

 

 

 

 

代码分析:

 

 

 

以上是菜肴类,可以在主函数里面中把其每道菜的价格给写出来。

 

 

public static void main(String[] args)

   {

        int flag=0;//判断是否开始订单

        int i=0,num=0;

      Scanner input = new Scanner(System.in);

      String s;

        Menu menu=new Menu();

        Order order=new Order();

        s=input.nextLine();

        while(!s.equals("end"))

        {

            String[] b=s.split(" ");//分割

            if(b[0].equals("1"))

                flag=1;

            if(flag==0)

            {

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

                if(menu.searthDish(b[0],i)==null)

                {

                    menu.dishs[i]=menu.addDish(b[0],Integer.parseInt(b[1]));

                    i++;

                }

                else

                    menu.searthDish(b[0],i).unit_price=Integer.parseInt(b[1]);

            }

            else

            {

                if(menu.searthDish(b[1],i)!=null)

                {

                num=Integer.parseInt(b[0]);

                order.records[num]=new Record();

                order.records[num]=order.addARecord(num,menu.searthDish(b[1],i),Integer.parseInt(b[2]),Integer.parseInt(b[3]));

                    System.out.println(order.records[num].orderNum+" "+order.records[num].d.name+" "+order.records[Integer.parseInt(b[0])].getPrice());

                }

                else if(b[1].equals("delete"))

                {

                    if(Integer.parseInt(b[0])<=num&&Integer.parseInt(b[0])>=1&&order.records[Integer.parseInt(b[0])].flag==0)

                        order.delete(Integer.parseInt(b[0]));

                    else

                        System.out.println("delete error;");

                }

                else

                {

                    num=Integer.parseInt(b[0]);

                    order.records[num]=new Record();

                    Dish dish=new Dish();

                    dish.name=dish.name+b[1];

                    dish.unit_price=0;

                    order.records[num]=order.addARecord(num,dish,Integer.parseInt(b[2]),Integer.parseInt(b[3]));

                    System.out.println(b[1]+" does not exist");

                }

            }

            s=input.nextLine();

        }

        System.out.println(order.getTotalPrice(num));

   }

}

主要的代码用到了这些菜单、订单、菜品、记录等类。其中,菜单类包含菜品数组和查找菜品信息的方法,订单类包含记录数组和计算总价、添加记录、删除记录等方法,菜品类包含菜品名称、单价和计算价格的方法,记录类包含序号、菜品、份额、数量和计价的方法。在主函数中,通过输入不同的指令(1表示开始点餐,其他表示菜品信息或订单信息),根据不同的情况调用不同的方法,来实现点餐、查看订单、修改订单等功能。

class Menu

{

   Dish[] dishs=new Dish[15];

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

   {

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

           {

          if(dishName.equals(dishs[i].name))

               return dishs[i];

           }

       return null;

   }

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

   {

       Dish d=new Dish();

       d.name=dishName.substring(0);

       d.unit_price=unit_price;

       return d;

   }

}

菜单类主要跟第一道题的一样都是一道一道、菜补到菜单里面。

class Record

{

    int orderNum;//序号\

    Dish d;//菜品\

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

    int flag=0;//是否被删除

    int num;

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

    {

        return (int)Math.round(d.getPrice(portion)*num);

    }

}

以上是一个订单类其中包含了订单号 orderNum、菜品信息 d、份额 portion、删除标志 flag、数量 num 和计价方法 getPrice()。其中,菜品信息 d 是一个 Dish 类型的变量,表示这条记录所点的菜品。份额 portion 是一个整数,代表小/中/大份。计价方法 getPrice() 通过调用菜品信息 d 的 getPrice() 方法计算出本条记录的价格,并乘以数量 num。最后使用 Math.round() 方法将结果四舍五入为整数。

 第三道点菜题目类图:

 

代码分析:

 

public class Main {

    public static void main(String[] args) {

       Scanner in = new Scanner(System.in);

       Menu menu=new Menu();

       Dish d;

       String a ;//接受内容

       a = in.next();

    //创建菜单

       while(!a.equals("end")) {

          if(a.charAt(0)!='t'){

                int price;

                price=in.nextInt();

                d=new Dish(a,price);

                menu.add(d);

            }

            else

                break;

            a=in.next();

       }

   //订单,此时的a="table"

       ArrayList<Order> orders = new ArrayList<Order>();

       while(!a.equals("end")) {

          int table=in.nextInt();      //接收第几桌

       //接受订单信息

          Order order = new Order(menu,table);

          orders.add(order);

          a=in.next(); //接收日期

          String b = in.next(); //接收时间

          order.account(a,b);

          System.out.println("table "+table+": ");

          while(true){

             a=in.next();

             if(a.equals("end")||a.equals("table"))

                 break;

             String m=in.nextLine();

             String[] p = m.split(" ");

             if(p.length==4) {

                 //给本桌点餐

                 int orderNum = Integer.parseInt(a);

                 String dishName = p[1];

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

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

                //查找是否有此菜名

                d = menu.searthDish(dishName);//接受菜品

                if(d==null)//未找到,说明没有该菜品

                     System.out.println(dishName+" does not exist");

                else {//找到了,添加订单

                     Record r = order.addARecord(orderNum, dishName, portion, num);

                     System.out.println(orderNum+" "+dishName+" "+r.getPrice());

                }

             }

             if(p.length==5) {

                 //为别桌点菜

                 int orderNum = Integer.parseInt(p[1]);

                 String dishName = p[2];

                 int portion = Integer.parseInt(p[3]);

                int num = Integer.parseInt(p[4]);

                //查找是否有此菜名

                d = menu.searthDish(dishName);//接受菜品

                if(d==null)//未找到,说明没有该菜品

                     System.out.println(dishName+" does not exist");

                else {//找到了,添加订单

                     Record r = order.addARecord(orderNum, dishName, portion, num);

                     System.out.println(orderNum+" table "+table

                           +" pay for table "+a+" "+r.getPrice());

                }

             }

             if(p.length==2) {//删除

                 int orderNum = Integer.parseInt(a);

                 String dishName = p[1];

                 if(dishName.equals("delete"))

                    order.delARecordByOrderNum(orderNum);//删除订单信息

             }

          }

       }

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

          if(orders.get(i).acc==0)

             System.out.println("table "+orders.get(i).table+" out of opening hours");

          else

             System.out.println("table "+orders.get(i).table+

                   ": "+orders.get(i).getTotalPrice());

       }

        in.close();

    }

}

在菜单部分,首先创建了一个空的菜单对象,然后通过循环来不断接收用户输入的菜品名称和价格,将其封装成Dish对象并添加到菜单中,直到输入“end”为止。

在订单部分,首先创建了一个空的订单列表,然后通过循环来不断接收用户输入的桌号和订单信息,将其封装成Order对象并添加到订单列表中,直到输入“end”为止。每个订单对象包含一个菜单对象,以便查询菜品信息和计算订单总价。

在订单信息输入部分,首先接收日期和时间,然后通过循环来不断接收用户输入的菜品信息,将其封装成Record对象并添加到订单中,直到输入“end”或“table”为止。其中,菜品信息可能是为本桌点餐或为别桌点餐,通过判断输入字符串的长度来区分。如果是为别桌点餐,还需要输出付款信息。

整个代码逻辑比较清晰。

 

class Order {

   ArrayList<Record> records = new ArrayList<Record>();// 保存订单上每一道的记录

   Menu menu;

   int table;

   float acc;

   void account(String a,String b) {//a接收日期,b接收时间

      //计算星期几w

      String[] s = a.split("/");

      if(s[1].length()==1)

          s[1]="0"+s[1];

      if(s[2].length()==1)

          s[2]="0"+s[2];

      a = s[0]+"-"+s[1]+"-"+s[2];

  SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

      Calendar cal=Calendar.getInstance();

      Date date=null;

      try {

          date = format.parse(a);

      } catch (ParseException e) {

          // TODO Auto-generated catch block

          e.printStackTrace();

      }

      cal.setTime(date);

      int w=cal.get(Calendar.DAY_OF_WEEK)-1;

      if(w<=0)

          w=7;

      //处理时间

      String[] time = b.split("/");

      int h=Integer.parseInt(time[0]);

      int m=Integer.parseInt(time[1]);

     

      if(w>=1&&w<=5) {

      if(h>=17&&(h<20||(h==20&&m<30)))

          acc=0.8f;

      else if((h>10||(h==10&&m>=30))&&(h<14||(h==14&&m<30)))

          acc=0.6f;

      }

      else if((h>9||(h==9&&m>=30))&&(h<21||(h==21&&m<30)))

          acc=1;

   }

   int getTotalPrice(){

   // 计算订单的总价

      int total=0;

      if(records==null)

          return 0;

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

          total+=records.get(i).getPrice();

      return Math.round(acc*total);

   }

   public Order(Menu menu,int table){

      this.menu = menu;

      this.table = table;

   }

   //根据菜名点菜

   Record addARecord(int orderNum,String dishName,int portion,int num) {

      //不用判断菜品是否存在,main里会判断,在这里一定会存在

      Record r = new Record(orderNum,menu.searthDish(dishName),portion,num);

      records.add(r);

      return r;

   }

   void delARecordByOrderNum(int orderNum){

      //根据序号删除一条记录

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

          if(records.get(i).orderNum==orderNum) {

             records.remove(i);

             return ;//删除成功

          }

      }

      System.out.println("delete error;");//删除失败

   }

}

以上跟上一个点菜不一样的地方就是加了桌号,然后上面的去加了这种,还能进行删除。

 

全部的类图以上的是。

 

 

踩坑心得:

  1. 首先看到点菜这个题目时,没有过多的考虑,写的类很少,好多主要的东西都写在了主函数里面去,但是等到后面的出现更多的点菜系列的题目时,发现需要那些类才能更加的连贯,所有我之后直接去把类增多了,然后主函数里面的更多的时引用类来实现一些东西。

 

 

之前的类:

 

 

之后的类:

 

  1. 在写菜单里面的搜索菜的方法时没有做到简洁性,所有后面重新搞直接用代码的size来找长度,来进行得到菜。

 

 

3.一开始写的时候对代码的注释没有很好的体现,导致之后自己都有些东西看不懂了,所有之后还对自己的代码进行了分成意思以及注释了一下,使代码更加的连贯性跟整洁。缺少对类的说明和注释,不易于理解和维护。

计算星期几的方法可以使用Java 8的新特性 LocalDate,使代码更简洁和可读性更高。时间处理可以使用Java 8的新特性 LocalTime,使代码更简洁和可读更高。计算总价的方法可以使用Java 8的新特性 Stream,使代码更简洁和可读性更高。addARecord方法中的参数应该使用Dish对象而不是菜名字符串,这样可以避免重复查找菜品。delARecordByOrderNum方法应该返回一个布尔值表示是否删除成功,而不是使用System.out.println输出信息。

 

 

 

主要困难以及改进建议:

  1. 抽象思维能力:JAVA编程题通常需要程序员具备较高的抽象思维能力,够将实际问题抽象为代码实现。这对于初学者来说是一项挑战。

 

  1. 算法和数据结构:JAVA编程题涉及到算法和数据结构的应用,如排序、查找、树、图等,需要程序员具备扎实的算法和数据结构基础。

 

   Scanner in = new Scanner(System.in);

       Menu menu=new Menu();

       Dish d;

       String a ;//接受内容

       a = in.next();

    //创建菜单

       while(!a.equals("end")) {

          if(a.charAt(0)!='t'){

                int price;

                price=in.nextInt();

                d=new Dish(a,price);

                menu.add(d);

            }

            else

                break;

            a=in.next();

       }

   //订单,此时的a="table"

       ArrayList<Order> orders = new ArrayList<Order>();

       while(!a.equals("end")) {

          int table=in.nextInt();      //接收第几桌

       //接受订单信息

          Order order = new Order(menu,table);

          orders.add(order);

          a=in.next(); //接收日期

          String b = in.next(); //接收时间

          order.account(a,b);

          System.out.println("table "+table+": ");

          while(true){

             a=in.next();

             if(a.equals("end")||a.equals("table"))

                 break;

             String m=in.nextLine();

             String[] p = m.split(" ");

             if(p.length==4) {

                 //给本桌点餐

                 int orderNum = Integer.parseInt(a);

                 String dishName = p[1];

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

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

                //查找是否有此菜名

                d = menu.searthDish(dishName);//接受菜品

                if(d==null)//未找到,说明没有该菜品

                     System.out.println(dishName+" does not exist");

                else {//找到了,添加订单

                     Record r = order.addARecord(orderNum, dishName, portion, num);

                     System.out.println(orderNum+" "+dishName+" "+r.getPrice());

                }

             }

             if(p.length==5) {

                 //为别桌点菜

                 int orderNum = Integer.parseInt(p[1]);

                 String dishName = p[2];

                 int portion = Integer.parseInt(p[3]);

                int num = Integer.parseInt(p[4]);

                //查找是否有此菜名

                d = menu.searthDish(dishName);//接受菜品

                if(d==null)//未找到,说明没有该菜品

                     System.out.println(dishName+" does not exist");

                else {//找到了,添加订单

                     Record r = order.addARecord(orderNum, dishName, portion, num);

                     System.out.println(orderNum+" table "+table

                           +" pay for table "+a+" "+r.getPrice());

                }

             }

             if(p.length==2) {//删除

                 int orderNum = Integer.parseInt(a);

                 String dishName = p[1];

                 if(dishName.equals("delete"))

                    order.delARecordByOrderNum(orderNum);//删除订单信息

             }

          }

       }

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

          if(orders.get(i).acc==0)

             System.out.println("table "+orders.get(i).table+" out of opening hours");

          else

             System.out.println("table "+orders.get(i).table+

                   ": "+orders.get(i).getTotalPrice());

       }

        in.close();

    }

}

这些东西还是缺少一些灵活的策略。

前端传递参数时使用encodeURIComponent方法进行重新编码,后端因为spring默认会进行一次解码操作,所以可以直接获取。

改进

代码的难度可以适量的降低一点点,更多来一点较为考验JAVA实际的特点的题目。

这个要先从多重继承概念说起

c++首先引入的多重继承带来了诸如菱形继承一类的问题,而后为了解决这个问题又不得不引入了虚继承这种概念。然而在实际的应用中人们发现继承更多的只被用在两种场合:扩充/改善基类,以及实现多态。对于前者,单继承足以;而对于后者,则真正需要的其实是纯抽象类,即只包含纯虚函数的基类。而对于这一种基类,由于其目的和普通的实例类已经有所不同,因此在java中将其改称为interface,即接口加以明确区分。

因此,java或者c#所谓的不支持多重继承,只是不支持对实例类的多重继承——因为这种继承所带来的一点点代码上的缩减远比不上其引入的麻烦,但是对于用于实现多态的多重继承,即implement interface依然是很好的支持了的。

面向对象的语言叫方法

面向过程的语言叫函数在java中没有函数这么一说,只有方法一说。实际上方法就是函数,函数就是方法,只是在不同的语言不同的称呼而已。

总结:

  1. 首先,我们学到了数组的定义和使用:点菜时需要记录菜品和数量,可以使用数组来存储这些信息。
  2. 循环结构的应用:在点菜时需要重复执行一定的操作,比如输入菜品和数量,可以使用循环结构来简化代码。
  3. 方法的定义和调用:可以将点菜的过程封装成一个方法,方便重复调用。
  4. 字符串的操作:在点菜时需要处理字符串,比如输入的菜品名称,可以使用字符串的方法来获取长度、比较、截取等操作。
  5. 异常处理:在输入菜品数量时,可能会出现非法输入,比如输入的不是数字,需要进行异常处理。
  6. 然后学到了类、继承、多态与抽象接口等。
  7. 在进行习题结构的考虑上需要自己再去调整与实践,用更多的编程题目去提高自己的能力。
  8. 老师讲课很好,无需更改。