Java第一阶段总结
前言
此篇博客主要针对PTA三次作业做一个总结,也是对自己学习了一个多月的Java做一个小结,学习了Java语言的一些基本用法,初步认识了面向过程和面向对象,了解是一个怎样的过渡过程以及两者的不同之处。
一、作业过程总结
1.总结三次作业之间的知识迭代关系:
第一次作业:Main类中只用了一个主方法去写题目所需要的功能,初步使用输入方法和循环方法;第二次作业:在Main类中除了主方法还写了很多种其他方法,然后在主方法里面调用其他方法去实现题目所需要的功能;第三次作业:不止Main一种类,分别写了很多种类,类里面分别有它们独自的属性和方法,然后在Main类中调用其他的类,利用其他类去调用其中的属性和方法,从而实现题目所需要的功能。
2.如何通过作业逐步从面向对象过程过渡到面向对象:
第一次作业和第二次作业主要考虑的是怎么用代码实现题目要求的事件本身,使用的也是Java语言的一些基本用法,在一个Main类中写完所有的方法;而第三次作业通过题目,考虑到了同一个目标有2个以上的方法,所以就想到了使用面向对象思想,然后使用了很多种对象类去封装它们独有的方法,让Main类去调用,与之前有所不同。
3.作业过程中遇到的问题及解决方法:
问题1:对PTA的Java语言测试环境不熟悉,出现编译错误及多种错误,查询资料,将类名命名为Main类,将包名去掉即可
问题2:等腰直角三角形判断方法错误,精度溢出问题,询问同学得知利用判定条件(a * a + b * b - c * c <= 0.001)即可
问题3:PTA提示判定输入值无效段代码有误,在eclipse中通过打断点debug找到输出值有误
问题4:一元二次方程开方用法错误,百度到Java语言是用Math.sqrt();
问题5:运行异常NullPointerException空指针,debug之后找到报空的字段并给它赋初始值即可
问题6:第二题求下n天最大值范围有误,debug发现day的增长速率过快,将其中一个day++去掉即可(左图为错误,右图为正确)
4.每次作业花费的时间比例: 2:5:3
5,对编程过程的严谨性的认识及教训:
第三次作业的第二道题中因为逻辑的不严谨,计算下n天的时候,当天数累加到每个月天数上限时sum会多加1,造成sum累加过快,最后得到的结果不正确。这体现出在较为复杂的代码中,比较小的参数值的问题可能会造成很大的影响,导致结果完全不同;以及一些细节问题也会造成最终程序错误,比如少一个括号,使用中文字符,还有判定条件是否全面,数据精度是否会造成溢出,使用方法是否符合题意要求,第三次作业用Java语言提供的日期的方法导致结果不正确;所以此后的编程要多注意这些方面的问题,弄出一个严谨性较强的程序。
二、OO设计心得
1.面向过程与面向对象的比较:
面向过程我们首先会去考虑题目的输入和输出以及整个事件的流程,面向过程重点在于事件本身,这样导致整个程序的代码复用性不高,比较适用简单的程序(以下为作业中的面向过程代码);
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import java.util.ArrayList; 2 import java.util.Scanner; 3 4 public class Main { 5 public static void main(String[] args) { 6 float a; 7 float c; 8 float d; 9 Scanner b = new Scanner(System.in); 10 ArrayList<Float> list = new ArrayList<>(); 11 do { 12 a = b.nextFloat(); 13 list.add(a); 14 } while (list.size() == 1); 15 c = list.get(0); 16 d = list.get(1); 17 if ((-5 <= c && c <= 5) && (-2.5 <= d && d <= 2.5)) { 18 System.out.print("In the rectangle"); 19 } else { 20 System.out.print("Not in the rectangle"); 21 } 22 } 23 }
面向对象我们首先会考虑题目中包含哪些类,类与类之间的关系,以及类本身的特征属性和所包含的方法,面向对象重点在于对象本身。若是同等多代码量的程序,面向对象运行程序的速度远快于面向过程,若代码量较少的话,面向过程远快于面向对象;面向对象条理比面向过程更清晰,代码更鲜明,可读性更高(以下为作业中面向对象代码)。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import java.text.ParseException; 2 import java.text.SimpleDateFormat; 3 import java.util.Calendar; 4 import java.util.Date; 5 import java.util.Scanner; 6 import java.util.Scanner; 7 8 public class Main { 9 public static void main(String[] args) throws Exception { 10 Scanner input = new Scanner(System.in); 11 int year = 0; 12 int month = 0; 13 int day = 0; 14 15 int choice = input.nextInt(); 16 17 if (choice == 1) { // test getNextNDays method 18 int m = 0; 19 year = Integer.parseInt(input.next()); 20 month = Integer.parseInt(input.next()); 21 day = Integer.parseInt(input.next()); 22 23 DateUtil date = new DateUtil(year, month, day); 24 25 if (!date.checkInputValidity()) { 26 System.out.println("Wrong Format"); 27 System.exit(0); 28 } 29 30 m = input.nextInt(); 31 32 if (m < 0) { 33 System.out.println("Wrong Format"); 34 System.exit(0); 35 } 36 37 System.out.print(date.getYear() + "-" + date.getMonth() + "-" 38 + date.getDay() + " next " + m + " days is:"); 39 System.out.println(date.getNextNDays(m).showDate()); 40 } else if (choice == 2) { // test getPreviousNDays method 41 int n = 0; 42 year = Integer.parseInt(input.next()); 43 month = Integer.parseInt(input.next()); 44 day = Integer.parseInt(input.next()); 45 46 DateUtil date = new DateUtil(year, month, day); 47 48 if (!date.checkInputValidity()) { 49 System.out.println("Wrong Format"); 50 System.exit(0); 51 } 52 53 n = input.nextInt(); 54 55 if (n < 0) { 56 System.out.println("Wrong Format"); 57 System.exit(0); 58 } 59 60 System.out.print(date.getYear() + "-" + date.getMonth() + "-" 61 + date.getDay() + " previous " + n + " days is:"); 62 System.out.println(date.getPreviousNDays(n).showDate()); 63 } else if (choice == 3) { // test getDaysofDates method 64 year = Integer.parseInt(input.next()); 65 month = Integer.parseInt(input.next()); 66 day = Integer.parseInt(input.next()); 67 68 int anotherYear = Integer.parseInt(input.next()); 69 int anotherMonth = Integer.parseInt(input.next()); 70 int anotherDay = Integer.parseInt(input.next()); 71 72 DateUtil fromDate = new DateUtil(year, month, day); 73 DateUtil toDate = new DateUtil(anotherYear, anotherMonth, 74 anotherDay); 75 76 if (fromDate.checkInputValidity() && toDate.checkInputValidity()) { 77 System.out.println("The days between " + fromDate.showDate() 78 + " and " + toDate.showDate() + " are:" 79 + fromDate.getDaysofDates(toDate)); 80 } else { 81 System.out.println("Wrong Format"); 82 System.exit(0); 83 } 84 } else { 85 System.out.println("Wrong Format"); 86 System.exit(0); 87 } 88 } 89 } 90 91 class DateUtil { 92 public int year; 93 public int month; 94 public int day; 95 96 public DateUtil(int year, int month, int day) { 97 super(); 98 this.year = year; 99 this.month = month; 100 this.day = day; 101 } 102 103 // 检测输入的年、月、日是否合法 104 public boolean checkInputValidity() { 105 boolean b = true; 106 if (year < 1820 || year > 2020) { 107 b = false; 108 } else if (month < 1 || month > 12) { 109 b = false; 110 } else if (day < 1 || day > 31) { 111 b = false; 112 } else if (!isLeapYear(year) && month == 2 && day == 29) { 113 b = false; 114 } 115 return b; 116 } 117 118 // 判断year是否为闰年 119 public boolean isLeapYear(int year) { 120 boolean a = false; 121 if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { 122 a = true; 123 } 124 return a; 125 } 126 127 // 取得year-month-day的下n天日期 128 public DateUtil getNextNDays(int m) throws ParseException { 129 int sum = 0; 130 int ye = year; 131 int mo = month; 132 int da = day; 133 int run[]=new int[] {0,31,29,31,30,31,30,31,31,30,31,30,31}; 134 int ping[]=new int[] {0,31,28,31,30,31,30,31,31,30,31,30,31}; 135 while(sum!=m) { 136 if(isLeapYear(ye)) { 137 if(da<run[mo]) { 138 da++; 139 sum++; 140 }else if(mo<12) { 141 mo++; 142 da=1; 143 sum++; 144 }else{ 145 ye++; 146 mo=1; 147 da=1; 148 sum++; 149 } 150 }else { 151 if(da<ping[mo]) { 152 da++; 153 sum++; 154 }else if(mo<12) { 155 mo++; 156 da=1; 157 sum++; 158 }else{ 159 ye++; 160 mo=1; 161 da=1; 162 sum++; 163 } 164 } 165 166 } 167 return new DateUtil(ye, mo, da); 168 } 169 170 // 取得year-month-day的前n天日期 171 public DateUtil getPreviousNDays(long n) throws Exception { 172 int sum = 0; 173 int ye = year; 174 int mo = month; 175 int da = day; 176 int run[]=new int[] {31,31,29,31,30,31,30,31,31,30,31,30,31}; 177 int ping[]=new int[] {31,31,28,31,30,31,30,31,31,30,31,30,31}; 178 while(sum!=n) { 179 if(isLeapYear(ye)) { 180 if(da < 1) { 181 da=run[mo-1]; 182 mo--; 183 }else if(mo < 1) { 184 ye--; 185 mo=12; 186 da--; 187 sum++; 188 }else{ 189 da--; 190 sum++; 191 } 192 } 193 else { 194 if(da < 1) { 195 da=ping[mo-1]; 196 mo--; 197 }else if(mo < 1) { 198 ye--; 199 mo=12; 200 da--; 201 sum++; 202 }else{ 203 da--; 204 sum++; 205 } 206 } 207 208 } 209 return new DateUtil(ye, mo, da); 210 } 211 212 // 比较当前日期与date的大小(先后) 213 public boolean compareDates(DateUtil date) throws Exception { 214 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 215 String dateString = this.getYear() + "-" + this.getMonth() + "-" 216 + this.getDay(); 217 String time = date.getYear() + "-" + date.getMonth() + "-" 218 + date.getDay(); 219 Date bt = sdf.parse(dateString); 220 Date et = sdf.parse(time); 221 222 if (bt.before(et)) { 223 return true; 224 } else { 225 return false; 226 } 227 } 228 229 // 判断两个日期是否相等 230 public boolean equalTwoDates(DateUtil date) throws Exception { 231 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 232 String dateString = this.getYear() + "-" + this.getMonth() + "-" 233 + this.getDay(); 234 String time = date.getYear() + "-" + date.getMonth() + "-" 235 + date.getDay(); 236 Date bt = sdf.parse(dateString); 237 Date et = sdf.parse(time); 238 239 if (bt.equals(et)) { 240 return true; 241 } else { 242 return false; 243 } 244 } 245 246 // 求当前日期与date之间相差的天数 247 public int getDaysofDates(DateUtil date) throws ParseException { 248 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 249 String dateString = this.getYear() + "-" + this.getMonth() + "-" 250 + this.getDay(); 251 String time = date.getYear() + "-" + date.getMonth() + "-" 252 + date.getDay(); 253 Date bt = sdf.parse(dateString); 254 Date et = sdf.parse(time); 255 int days; 256 if (bt.before(et)) { 257 days = (int) ((et.getTime() - bt.getTime()) / (1000 * 3600 * 24)); 258 } else { 259 days = (int) ((bt.getTime() - et.getTime()) / (1000 * 3600 * 24)); 260 } 261 return days; 262 } 263 264 // 以“year-month-day”格式返回日期值 265 public String showDate() { 266 return year + "-" + month + "-" + day; 267 } 268 269 public int getYear() { 270 return year; 271 } 272 273 public void setYear(int year) { 274 this.year = year; 275 } 276 277 public int getMonth() { 278 return month; 279 } 280 281 public void setMonth(int month) { 282 this.month = month; 283 } 284 285 public int getDay() { 286 return day; 287 } 288 289 public void setDay(int day) { 290 this.day = day; 291 } 292 }
2.面向对象设计的基本原则理解:
每种编程都有它自己的原则,面向对象设计我目前了解到单一职责原则,主要是说一个方法只执行一件事情,每个对象都负责自己独自的功能,都有自己独自的属性,这与之前一股脑写完所有东西不同,整个程序看起来会很冗杂,单一职责原则会使得整个程序条理更清晰,可读性更高,程序设计也更加强壮。
3.OO编程思维的理解:
面向对象和之前学习的C语言以及刚开始接触的面向过程思想不一样,我认为是它们的升级版,当我们拿到题目时首先会去考虑有哪些对象,然后考虑对象具有哪些属性和方法,然后再考虑main方法的调用,考虑是否有输入输出值,整体思路很清晰,程序很明朗。
三、测试的理解与实践
1.测试对于编码质量的重要性:
测试的作用就是用来测试代码的运行是否流畅和测试代码的运行速度,减少了运行时间也是提高了代码滴质量,测试的时候可以帮我们找到代码问题,我们还可以提炼代码,或许会想到更好的方法去实现题目要求,从而在减少了代码量的同时提高了代码的质量,并且可以让我们知道不同方式实现时得运行时间的对比,所以测试对于编码质量而言很重要。
2.假如让你设计测试用例,你会如何做:
第一步是建立相关测试类,第二步是把我们所需要测试的方法写入测试类中,然后拟定数据,第三步运行测试类,如果测试方法没有问题,将这个方法写入主方法中,其中还要考虑输入是否合法,运行速度快慢,答案正确与否,并给出一些测试例子做参考,最后给出测试结果。
四、课程收获
学习Java四周,接触到的新鲜东西很多,从最开始的Java发展简史及简单的输入输出,再到老师开始讲解类,通过后面的作业实践及课堂学习了解到面向过程与面向对象的使用和区别,类本身包含属性及方法,有它独自的作用,如Scanner类是获取输入值的,还有get set的用法,一个用来获取值,一个用来赋予值;数据类型的转换方法,类型与类型均可进行转换;数组的使用,如何不出现报空现象;如何使用public、private等关键字;如何使用嵌套循环;如何构造方法,如何调用类,以及最近接触的怎么根据程序画出UML类图,怎么根据UML类图写出程序。最为特别的一点是以前学编程对变量名参数名从不在意,现在养成使用英文名的习惯,这样程序可读性大大加强。
五、对课程的建议
老师上课方式与之前都不同,属于边讲边实践,学生可以更快熟悉操作。提出的建议是上课可以多些互动,多一点讨论,激起同学想要学习的积极性;还有就是希望老师以后及时查看课堂作业,课上能进行一下讲解好的地方与不好的地方,也许这样学得更多,相当于在共同交流;最后还有一点是想要有课本,以及希望老师给个课间,大家都做适当休息,效果可能更佳。
六、之后一阶段的学习计划
前段时间的学习很懒散,经常上课跟不上趟,或者说这门课程对我来说很复杂,衔接太紧了,一节听不懂,节节听不懂,之后打算抓紧复习前面的,尽早补回知识盲点,预习后面的知识点,有人曾跟我说,当你走在老师教学内容前面的时候就不会觉得学的很吃力,准备试一试。还有更重要的是改变自己的习惯,多动手,不能只局限于眼睛看明白,也做好准备迎接大作业。