从面向过程到面向对象

从面向过程到面向对象

——我的Java第一次作业周期总结

〇、前言

  这篇博客是我对Java课程三次课后作业的总结,三次作业都是在PTA平台上完成的。正如我是一个精益求精的好学生,不将每个测试点后都打上红勾勾,晚上睡觉都不会安稳 o( =•ω•= )m   那么接下来我就来说说我在这三次作业里都学到了什么吧。

从面向过程到面向对象_第1张图片[Java三次作业标题]

从面向过程到面向对象_第2张图片[提交后让人无比舒适的红色]

 

一、作业过程总结

  ①知识的迭代。在上学期,我们使用C语言做了不少编程题,而这三次作业也是从类似的编程题写起,先编写实现特定功能的'方法',然后就要将'方法'封装成'类'。从开始的面向过程逐渐转变成现在的面向对象,完成知识的迭代更新。

  ②面向过程与面向对象。三次作业主要围绕日期问题进行程序设计,总体难度渐难。第一次作业的一些小题目让先你熟悉Java的语法,第二次作业就开始设计关于日期的'方法',比如从某年某月某日算起的n天之后是哪年哪月哪日,n天之前又是哪年哪月哪日,这就和C语言的函数一样,传进一些参数,返回一个数值,而第三次作业就让你用面向对象特有的'类'来进行程序设计。这三次作业就是让我们逐渐从“给一个命令做一个动作”的面向过程程序设计过渡到“用类创造对象”的面向对象程序设计。

  ③遇到问题与解决问题。在三次作业中,我遇到的问题大多是某个测试点过不去。

  第一次作业第四题,输入三条边的实型数据,输出三角形的类型。数据的合法性是一个考点,if-else的使用是一个考点,但这道题的坑挖在数据上。由于无法在键盘上输入根号,所以数据用的是保留小数的实型数,这时判断是否相等就要看它与结果的差值是否可以忽略,例如6.00000061与6.0就可以看作相等。于是我用if(Math.abs(b*b+c*c-a*a)<=1e-6)才过了那个巨坑的测试点。(问别人才知道的)

从面向过程到面向对象_第3张图片

[第一次作业第四题题目]

  在第三次作业中多次出现计算n天之前或之后的日期,若按照题目的思路,一天一天地加或一天一天地减就会有测试点超时的问题。比如今天是2020年3月27日,如果要计算八亿天即800,000,000天之后是多少年多少月多少日,那超时也不奇怪。

从面向过程到面向对象_第4张图片

[用累减的方法计算n天之前的日期]

  以求n天之后的日期为例,我采取的办法是先将日期设置为当年的1月1日,再用逐年加的办法加到n<=365,最后将剩下的天数加完。参考代码如下(太长了,不需要仔细看,仅供参考)

  1 /*n天之后的日期,累加法超时过不了测试点*/
  2 public DateUtil getNextNDays(long n) {
  3     long year = this.day.getMonth().getYear().getValue();
  4     long month = this.day.getMonth().getValue();
  5     long day = this.day.getValue();
  6     long yearT, monthT, dayT;
  7     if(n==0) {
  8         int yearTemp = (int)year;
  9         int monthTemp = (int)month;
 10         int dayTemp = (int)day;
 11         DateUtil date = new DateUtil(yearTemp,monthTemp,dayTemp);
 12         return date;
 13     }
 14     //将日期设置为year/1/1
 15     long leapNum = 28;
 16     if(this.day.getMonth().getYear().isLeapYear()) {
 17         leapNum = 29;
 18     }
 19     if(month == 1) {
 20         n += (day-1);
 21     } else if(month == 2) {
 22         n += 31+(day-1);
 23     } else if(month == 3) {
 24         n += 31+leapNum+(day-1);
 25     } else if(month == 4) {
 26         n += 31+leapNum+31+(day-1);
 27     } else if(month == 5) {
 28         n += 31+leapNum+31+30+(day-1);
 29     } else if(month == 6) {
 30         n += 31+leapNum+31+30+31+(day-1);
 31     } else if(month == 7) {
 32         n += 31+leapNum+31+30+31+30+(day-1);
 33     } else if(month == 8) {
 34         n += 31+leapNum+31+30+31+30+31+(day-1);
 35     } else if(month == 9) {
 36         n += 31+leapNum+31+30+31+30+31+31+(day-1);
 37     } else if(month == 10) {
 38         n += 31+leapNum+31+30+31+30+31+31+30+(day-1);
 39     } else if(month == 11) {
 40         n += 31+leapNum+31+30+31+30+31+31+30+31+(day-1);
 41     } else if(month == 12) {
 42         n += 31+leapNum+31+30+31+30+31+31+30+31+30+(day-1);
 43     }
 44     monthT =1; dayT = 1;
 45     //往后推年数
 46     for(yearT = year; n >= 366; yearT++) {
 47         if(isLeapYear(yearT)) {
 48             n -= 366;
 49         } else {
 50             n -= 365;
 51         }
 52     }
 53     //往后推日期
 54     if(!isLeapYear(yearT) && n==365) {
 55         yearT++;
 56     } else {
 57         long leapNumT = 28;
 58         if(isLeapYear(yearT)) {
 59             leapNumT = 29;
 60         }
 61         if(n>=31+leapNumT+31+30+31+30+31+31+30+31+30) {
 62             monthT = 12;
 63             dayT = n-(31+leapNumT+31+30+31+30+31+31+30+31+30)+1;
 64         } else if(n>=31+leapNumT+31+30+31+30+31+31+30+31) {
 65             monthT = 11;
 66             dayT = n-(31+leapNumT+31+30+31+30+31+31+30+31)+1;
 67         } else if(n>=31+leapNumT+31+30+31+30+31+31+30) {
 68             monthT = 10;
 69             dayT = n-(31+leapNumT+31+30+31+30+31+31+30)+1;
 70         } else if(n>=31+leapNumT+31+30+31+30+31+31) {
 71             monthT = 9;
 72             dayT = n-(31+leapNumT+31+30+31+30+31+31)+1;
 73         } else if(n>=31+leapNumT+31+30+31+30+31) {
 74             monthT = 8;
 75             dayT = n-(31+leapNumT+31+30+31+30+31)+1;
 76         } else if(n>=31+leapNumT+31+30+31+30) {
 77             monthT = 7;
 78             dayT = n-(31+leapNumT+31+30+31+30)+1;
 79         } else if(n>=31+leapNumT+31+30+31) {
 80             monthT = 6;
 81             dayT = n-(31+leapNumT+31+30+31)+1;
 82         } else if(n>=31+leapNumT+31+30) {
 83             monthT = 5;
 84             dayT = n-(31+leapNumT+31+30)+1;
 85         } else if(n>=31+leapNumT+31) {
 86             monthT = 4;
 87             dayT = n-(31+leapNumT+31)+1;
 88         } else if(n>=31+leapNumT) {
 89             monthT = 3;
 90             dayT = n-(31+leapNumT)+1;
 91         } else if(n>=31) {
 92             monthT = 2;
 93             dayT = n-31+1;
 94         } else if(n>=1) {
 95             monthT = 11;
 96             dayT = n-1+1;
 97         }
 98     }
 99     
100     int yearTemp = (int)yearT;
101     int monthTemp = (int)monthT;
102     int dayTemp = (int)dayT;
103     DateUtil date = new DateUtil(yearTemp, monthTemp, dayTemp);
104     return date;
105 }
点击查看代码

  补充一下,使用long类型而不是int类型也是为了过某些刁蛮的测试点,如果将n=2147483647(int类型的上限),即2,147,483,647天之后作为测试,那n在我的代码中会超过int的上限而得出错误的结果,所以我在其计算完成后将long强制转换成int作为返回值,才过了那个“整型数最大值”测试。一天一天加,直到加到第n天,代码虽然简单且简洁,但用巨大的数据运行起来就像只乌龟;用我的方法来计算日期,代码虽然冗长,速度则像火箭一样。这就是算法的魅力呀。  ( =•ω•= )

  ④作业花费时间比例。三次作业花费的时间当然是越来越长的,特别是在某些巨坑的测试点上。如果第一次作业算1个单位的话,第二次作业就是4个单位,而第三次作业至少是10个单位。

  ⑤编程的严谨性。编程要考虑到各种情况,认为不会有人用2147483647这种大数字进行测试这种想法是错误的。就像明明提示限制只能输入数字,我偏要输入字母,如果这时程序崩溃了或得不到想要的结果,那这样的程序写出来也不会得到认可。

 

二、Java设计心得

  ①面向过程与面向对象。在我们大一上学期已经学习了程序设计基础的课程,也完成了用C语言编写的小项目,C语言是一门典型的面向过程语言,所以我对面向过程也有一定了解;而Java是一门典型的面向对象语言,经过这三次作业的练习,我对面向过程与面向对象也有所感受。如果把编程想象成搭积木,代码越长积木搭得越高,对于面向过程而言,你每搭一块都必须足够谨慎,因为你不知道你搭错这一块会对后面的积木造成什么影响,当程序运行失败,原因也不是那么容易看出来时,你必须从头开始找起,想办法纠正它;而面向对象则像是你提前准备了装积木的盒子,你将积木搭好放在盒子中,然后把盒子一个个搭好,这样,寻找问题也方便得多。我在C语言课设时就感觉到面向过程程序设计的繁杂,我的“简易画图软件”的全部代码加起来超过1300行,设计程序时,即使完成编译后运行起来的代码也总是能出不少问题,这时我想找出错误就必须从程序开始的代码一行行往下找。而在做这三次作业时我就感受到面向对象程序设计的优势,我只要将'类'设计好,主程序想要完成什么功能,交给'类'就行了,而当哪里出错时,找到相应的'类'进行纠正就可以了。

从面向过程到面向对象_第5张图片

[C语言课设作品]

  ②面向对象设计的基本原则。将万物看成对象,赋予对象该有的属性和功能就是面向对象程序设计的基本原则。就像我要设计一辆车,这辆车的属性有车身重量、大小、颜色,这辆车要能开动、加速、减速、刹车,当我想需要完成什么操作可以直接调用。

  ③Java编程思维。最重要的就是把'类'设计好,我们需要什么功能应该先想到该创建什么样的'类',而不是将功能写成方法,直接让main方法进行调用,那样就回到面向过程的老路了。使用Java进行编程就是因为它是一门纯面向对象语言,我们渴了就new一个'人'出来给我们端茶倒水。

 

三、测试的理解与实践

  ①测试对于编码质量的重要性。代码的质量很大程度受测试影响,就拿这次做的三次作业来说,如果没有测试用例要求在规定时间内要得出正确结果,我大可不必想出更快速的计算方法,直接用简单的累加法来求出日期,既省事又简洁。如果没有测试用例,我也不会想到几位小数点后近似相等的问题。站在用户的角度,如果因为好奇,输入了一个20亿(2,000,000,000)的数字,想看看20亿天之后是哪年哪月哪日,结果程序因为数据溢出告诉你一个显然错误的答案,这对用户是十分不友好的。

  ②测试用例的良苦用心。测试用例绝不单单用的是普遍的数据,好的测试用例是那种当自己觉得万无一失准备提交的时候,偏偏就有那么几个过不去的测试点,心中不禁惊呼:绝了!如果测试用例没有揪出某些致命BUG的话,导致用户在使用的时候程序崩溃,会极大地拉低用户对程序的好感度,毕竟谁也不会喜欢一个会崩溃的软件。所以如果让我来设计测试用例,我会着重在普通数据的测试上,极端数据也不能少,例如你要我输入正整数,我偏要测试字符串、负数、零、整型最大值、整型最小值、实型数据,看你的程序能否给出相应的提示信息。

从面向过程到面向对象_第6张图片

[测试用例]

 

四、课程收获

  ①面向对象理解加深。感受到为什么现在基于面向对象的计算机语言这么流行,因为它更符合正常人的思维方式,编写代码也更有效率。

  ②代码健壮性理解加深。学习C语言时,老师就强调代码的健壮性:不仅要处理正常的数据,也要处理异常的数据。其中,“if-else if-else”语句尤其用得多,“将其它所有不正常的数据全部丢进else里就行了”,每次处理异常数据时都会这样想,这样,程序就不会因处理不了异常数据而崩溃了。

  ③提高书写博客的能力。这是我第一次写博客,以前都是有问题查百度,翻阅其他人写的博客、帖子,而现在通过这门课程,我也知道自己也可以组织语言,书写自己的博客,传授所学会的或体会到的知识,自己也在整理知识中获益,非常开心。

五、对课程的建议

  干货多一点。我在观看其他教师网络讲课时,当老师们用自己理解到的知识风趣幽默地讲解出来时,我就会感觉到学习的乐趣。就像华中师范大学的戴建业教授,用极其生活化且极具趣味的语言讲述李白、杜甫、高适的交情,“找仙人,采仙草,炼仙丹”一度成为沙雕网友的笑梗。又像中国政法大学的罗翔教授,每节课都会用离奇且逗人发笑的案例使法律术语变得深刻。网红教师李永乐老师,用浅显易懂的语言讲解深奥的数理知识深得网友青睐。有趣的干货能使知识更好地得到传播。

从面向过程到面向对象_第7张图片[戴建业教授]

从面向过程到面向对象_第8张图片

[找仙人 采仙草 炼仙丹]

六、下一阶段的学习计划

  自主学习。Eclipse有不少基本的操作还不熟悉,比如断点调试、各个界面的功能、项目的构建……接下来就要不断探索eclipse里的功能了。

你可能感兴趣的:(从面向过程到面向对象)