OOP学习的第二次博客作业

发布时间 2023-04-27 15:30:08作者: 邓文迪

(1)前言:总结前三次PTA作业

1.当面对第一次作业的时候,第一次的长篇大论便让我退缩,然后下接下来的题目。第二题是判断是否有重复数据的题目,以及第三题去除重复数据的题目,考察的大多都是for循环进行排序以及使用Arrays.sort()方法,以及学习到了如何是查询重复数据时候让自己的代码效率达到最高。为以后编写代码让自己的代码更加整洁且效率高打下了基础。在第四题中学习到了Arrays.sort(words, new Comparator<String>()的简单使用,可以自行定义compare方法对所需要排序的字符进行排序。在第五题第六题中,主要熟悉了无参构造方法以及含参构造方法,以及小数点有效数字的保留。第七题面对众多不熟悉的方法之后,通过查询Java API文档,了解Scanner类中nextLine()等方法、String类中split()等方法、Integer类中parseInt()等方法的用法,了解LocalDate类中of()、isAfter()、isBefore()、until()等方法的使用规则,了解ChronoUnit类中DAYS、WEEKS、MONTHS等单位的用法。通过此次作业中了解到了各种类中的方法以及温习了类与构造方法的构建。

2.当面对第二次作业的时候,看到前四道题的才16分的时候便开始表示疑惑,之后才懂得老师的用心,前四题大致都是一个知识点,让我们了解正则表达式的具体使用。Str.matches("^[1-9]\\d{4,14}$");.matches("^[1-9]\\d{4,14}$");等等写法,正则表达式其中的学问很多,需要我细细咀嚼,在第二题中还再次重温了Arrays.sort(chars);在第四题中还温习了number.compareTo以及direction.equals和id.substring的用法以及详情。第五题第六题在之前写过的题目上再增加了一些环节。在编写类的时候要注重各个类之间的关系以及参数的调用。这两题代码相对之前缩写过的代码而言,非常的长,这时我们就需要画类图来理解类中的具体方法以及各个类之间的关系,然后根据类图去编写代码。在这个过程中顿阿联了自己的逻辑思维能力以及应对长代码时的耐心。

 这类题型为正则表达式的典例:

import java.util.Scanner;

public class Main{
    public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    String qqNumber = input.nextLine();
    boolean isValid = qqNumber.matches("^[1-9]\\d{4,14}$");
        //利用正则表达式判断输入的qq号是否有效
    if (isValid) {
        System.out.print("你输入的QQ号验证成功");
    } else {
        System.out.print("你输入的QQ号验证失败");
    }
    }
}

 

(2)设计与分析:

 

面对此题时构思好编写各个类的顺序,以及各个类之间的关系(参数的传递)然后把大体的方法框架编写完毕之后,我首先编写主类里面的程序步骤,让主题程序先编写完成后,再去编写方法内的具体内容,getter、setter类方法很快的构建好了,boolean checkInputValidity(), boolean compareDates(DateUtil date), boolean compareDates(DateUtil date),String showDate()等方法的构建相对后三个方法而言还是较为容易,重要的时给year、month、day类发送信息获得信息来比较大小或者查询日期的合理性。public DateUtil getNextNDays(int n),DateUtil getPreviousNDays(int n),getDaysofDates(DateUtil date),这三个方法的编写就几乎要涉及到本类以及其他类的各个方法,编写量较大,在编写草图理清自己思路之后再编写程序最为合适。

 

 

在本次代码中相较于之前增设了Year、Month、day类的定义,

//Year类
class Year{
    int value;
    //默认构造方法
    public Year(){
    }
    //带参构造方法
    public Year(int value){
        this.value = value;
    }
    //getter
    public int getValue(){
        return value;
    }
    //setter
    public void setValue(int value){
        this.value = value;
    }
    //判断year是否为闰年
    public  boolean isLeapYear(){
        if((value % 4 == 0&&value % 100 != 0) || value % 400 == 0)
            return true;
        else
            return false;
    }
    //效验数据合法性
    public boolean validate(){
        if(this.value <= 2050&&this.value >= 1900)
            return true;
        else
            return false;
    }
    //年份加一
    public void yearIncrement(){
        this.value = this.value+1;
    }
    //年份减一
    public void yearReduction(){
        this.value=this.value-1;
    }
}

 

 

而7-6相对于7-5而言就是三个日期类与datatuil之间的关系,以及三个日期类之间的关系不同,聚合的关系不同,定义的方法不同。在7-5中有种层层递进的关系,而在7-6中dateutil类似于统帅三军的感觉。

 

//Day类
class Day{
    int value;
    Month month;
    int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    //默认构造方法
    public Day(){
    }
    //带参构造方法
    public Day(int yearValue,int monthValue,int dayValue){
        this.month = new Month(yearValue,monthValue);
        this.value = dayValue;
    }
    //getter
    public int getValue(){
        return value;
    }
    public Month getMonth(){
        return month;
    }
    //setter
    public void setValue(int value){
        this.value = value;
    }
    public void setMonth(Month value){
        this.month = value;
    }
    //日期复位(1)
    public void resetMin(){
        this.value = 1;
    }
    //日期设为该月最大值
    public void resetMax(){
        this.value=a[month.getValue()];
    }
    //效验数据合法性
    public boolean validate(){
        if(this.getMonth().getYear().isLeapYear())
            a[2]=29;
        if(this.value >= 1&&this.value <= a[month.getValue()])
            return true;
        else
            return false;
    }
    //日期加一
    public void dayIncrement() {
        this.value = this.value+1;
    }
    //日期减一
    public void dayReduction() {
        this.value = this.value-1;
    }
}

这两道题相较于之前的题,在日期信息的获取中也需要改变形式,必须通过在三个日期类中层层递进获得信息。

类似如此:

    public DateUtil getPreviousNDays(int n){
        for (int i=0;i<n;i++) {
                if(this.getDay().getMonth().getYear().isLeapYear())
                    a[2]=29;
                else
                    a[2]=28;
                if(this.getDay().getValue()==1) {
                    if(this.getDay().getMonth().getValue()==1) {
                        this.getDay().getMonth().getYear().setValue(this.getDay().getMonth().getYear().getValue()-1);
                        //this.year--;
                        this.getDay().getMonth().setValue(12);
                        //this.month=12;
                        this.getDay().setValue(31);
//                        this.day=31;
                    }
                    else {
                        this.getDay().getMonth().setValue(this.getDay().getMonth().getValue()-1);
//                        this.month--;
//                        this.day=a[this.month];
                        this.getDay().setValue(a[this.getDay().getMonth().getValue()]);
                    }
                }
                else
                    this.getDay().setValue(this.getDay().getValue()-1);;
            }
        return new DateUtil(this.getDay().getMonth().getYear().getValue(),this.getDay().getMonth().getValue(),this.getDay().getValue());
    }

 

 

面对第四次作业的7-1以及第六次作业的7-1,都是关于菜单计价系统,由于我们没有之前编写菜单计价系统1.0和2.0,所欲相对于我而言,没有很强的编程能力,面对菜单计价系统3-4这种题目,看到的时候便望而却步了。面对菜单三,我初次遇见时便被他吓到,他给出了dish、menu、record、order类的大致框架,我在稿纸上写出来各个类中的各个方法,画出全部代码的大致框架后便开始入手.

 

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Menu mu = new Menu();
        Table[] tablemes = new Table[10];
        int j = 0;//菜单数
        int l = 0;//订单数
        int k = 0;//代点菜数
        Dish tt;
        //int sum = 0;
        int cntTable = 0;//桌号
        int count;
        String[] temp;
        int a1,a2,a3,a4,a5;

        while (true) {
            String st = sc.nextLine();
            temp = st.split(" ");
            if(st.equals("end"))
                break;
            count = temp.length;
            if (count == 2) {//一个空格
                //String[] temp1 = st.split(" ");
                if (temp[1].equals("delete")) {//第二个为delete
                    a1 = Integer.parseInt(temp[0]);
                    int c = tablemes[cntTable].odt.delARecordByOrderNum(a1);
                    tablemes[cntTable].sum-=c;
                } else {//菜单添加
                    a2 = Integer.parseInt(temp[1]);
                    mu.dishs[j] = mu.addDish(temp[0], a2);
                    j++;
                }
                //continue;
            }
            else if (count == 4) {//三个空格
                //String[] temp2 = st.split(" ");
                if (temp[0].equals("table")) {//桌号
                    cntTable++;//跳过0;
                    l = 0;
                    tablemes[cntTable] = new Table();
                    //tablemes[cntTable].tableDtime = st;
                    tablemes[cntTable].AheadProcess(st);

                    System.out.println("table " + cntTable + ": ");
                } else {//增加订单的情况;
                    a3 =Integer.parseInt(temp[0]);
                    a4 = Integer.parseInt(temp[2]);
                    a5=Integer.parseInt(temp[3]);
                    tablemes[cntTable].odt.addARecord(a3, temp[1],a4 , a5);
                    tt = mu.searthDish(temp[1]);
                    if (tt != null) {
                        tablemes[cntTable].odt.records[l].d = tt;
                        int a = tablemes[cntTable].odt.records[l].getPrice();
                        System.out.println(tablemes[cntTable].odt.records[l].orderNum + " " + tt.name + " " +a );
                        tablemes[cntTable].sum +=a;
                    }
                    l++;
                }
                //continue;
            }

            else if (count == 5) {//代点菜
                //String[] temp3 = st.split(" ");
                a1 = Integer.parseInt(temp[1]);
                a2 = Integer.parseInt(temp[3]);
                a3 = Integer.parseInt(temp[4]);
                tablemes[cntTable].odt.addARecord( a1, temp[2], a2, a3);
                tt = mu.searthDish(temp[2]);
                if (tt != null) {
                    tablemes[cntTable].odt.records[l].d.unit_price = tt.unit_price;
                    int b = tablemes[cntTable].odt.records[l].getPrice();
                    System.out.println(temp[1] + " table " + tablemes[cntTable].tableNum + " pay for table " + temp[0] + " " + b);
                    tablemes[cntTable].sum += b;
                }
                l++;
            }
            //st = sc.nextLine();

        }
        for (int i = 1; i < cntTable + 1; i++) {
            tablemes[i].Gettottalprice();
        }
    }
}

在这个代码中完成对功能的选择,将其他各个类统筹在这里实现。

 

 画出这个类图之后按照这个框架构造就可以更高效率的完成全部代码的编译。

面对菜单4的编写,十分的具有难度,在经过一顿思考之后,编写之后,最终以失败告终,不过我相信以后我一定会努力的去完成更难的题目,去攻克更艰险的难关。

(3)踩坑心得:

 

面对题目有看似很容易解决但是不知如何下笔的时候,可以大胆的查阅相关的资料,说不定就有意外的收获,java还是相对智能呢个,java文档中有很多类中方法的使用可以帮助我们省却很多过程,直接达到我们所需要的功能。但我们获得一个新知识之后,要多次进行使用,多次查看,才能掌握其中的知识,才能让它成为我们的武器,以后更快更便捷的完成任务编写完代码。在运用比较型代码时,要注意前缀和后缀,是哪个大是返回正值。编写复杂函数如第五次作业的public DateUtil getNextNDays(int n),DateUtil getPreviousNDays(int n),getDaysofDates(DateUtil date),时候,要注意给其它类发送信息时的信息,必须发送和接受是同一类型,以及进行属性的更改的时候,得看定义的属性是否是可更改的属性以及能否直接对属性进行更改。例如这里定义的DAY、month、year的属性,都是day、month、year类的,不可直接进行简单的相加减,而在此处我们调用了setter等方法进行属性的修改,以及运用getter等方法进行属性的获取。

    public String showDate(){
        return this.getDay().getMonth().getYear().getValue() + "-" + this.getDay().getMonth().getValue() + "-" + this.getDay().getValue();
    }

 

 

 

 对日期的获取的时候,我们一开始容易直接使用this.year,this.month,this.day,获取,这样是错误的,在编译之后才发现问题所在。

(4)改进建议:

面对第二次作业的第五六题dayincrement、yearincrement、monthincrement以及rasemax以及rasemin等等我认为莫名其妙的函数,在本次程序中按照要求编写之后但并没有使用,在这里我认为直接加减我认为更加的方便,如果对类中发送信息引用这些方法我认为反而会让程序变得更加繁琐,不易于读者的理解。以及像菜单三菜单四这种大工程的题目,希望老师逐步递进的给我们布置作业,一上来就要编写如此陌生、庞大的系统,会打消同学们的积极性,以及难度相对于同学们来说非常的大,希望不管是作业还是老师上课的教学,都是逐层递进,更加容易让同学们接受,并且更加好的去编写并学习其中的知识点。

 

(5)总结:

对于这三次的作业,学习到了如果运用Array.sort直接对需要排序的字符串乃至数组进行直接排序,无需我们进行繁琐的for循环。直接开始接触到了Scanner类中nextLine()等方法、String类中split()等方法、Integer类中parseInt()等方法的用法,了解LocalDate类中of()、isAfter()、isBefore()、until()等方法的使用规则,了解ChronoUnit类中DAYS、WEEKS、MONTHS等单位的用法。通过此次作业中了解到了各种类中的方法以及温习了类与构造方法的构建。让我领略到了java文档库中有许多实用的方法供我们使用,我们以后无需进行复杂的编码去实现部分功能的实现,我们可以直接调用库中的方法进行运算。通过第二次的作业我也学习到了正则表达式的基础使用,但是里面的知识我们之前从来没有接触过,表达方式也是从未见过,字符也是过于新鲜。现在只是接触,要想掌握还需再课后完成任务之后花更多的时间去理解与记忆。在一次次的学习中我们具有了更强的逻辑思维能力,懂得在运行大规模程序的过程中要如何一步步的进行操作。正如现在我懂得了在遇到复杂程序的时候,第一步是要进行大致框架的构建,在老师的引导下,以及我自己多次编写程序的过程中,对powerdesigner的使用更加的精湛,并且懂得了在编写完代码后直接一键生成类图以及在构建完类图后powerdesigner可以帮助我们构建出代码的大体框架。画出正确的类图可以帮助我们更快的编写出代码的大体框架的同时,具有良好的思维逻辑。

 

对课堂教学以及课后训练的建议:老师的课程可以更加详细,引用更多的实例去让我们理解所讲述的内容,过于空洞让同学们难以接受以及疲于学习知识理论。以及现在老师讲述的内容貌似于近几次作业的编写相关性不大,让我们易于忘记上课讲述的内容,希望老师可以在平时作业中点拨一下知识点,让我们及时的复习上课所讲述的内容。对于课后作业而言,我认为任务量过大,需要我们进行极大的时间来去一步步了解并且难以自主的完成。必须在网上查阅大量的资料去进行学习,并且在编写的过程中极易出错,我们需一步一步的试错。所以我认为学习课后任务的压力过大,任务过多,难度也是有的,并且相对于平时上课的内容相关性不强,希望以后能有所改进。