面向对象学习阶段性课程总结
作者:互联网
一、前言:
新学期开始了面向对象程序设计的学习,截止到现在,我们已经完成了三次相关作业。其中,第一次作业的难度及题量都是最少的,也没有太多知识点,主要是让我们熟悉面向对象程序设计的基本输入输出以及简单的判断。第二次作业题量也不多,主要让我们对类与方法有一个初步的认识。第三次作业明显较前两次要难,虽然题量不多,但是由于有了正则表达式这一知识点的加入,导致我花费了较多的时间还是没有完成这一次题目集的第三题。
二、设计与分析
题目集1:7-8
本题要求输入三角形的三边长来判断该三角形为何种三角形,我的作业代码如下:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); double a =input.nextDouble(); double b =input.nextDouble(); double c =input.nextDouble(); if(a<1||a>200||b<1||b>200||c<1||c>200) { System.out.print("Wrong Format"); } else if((a+b>c)&&(a+c>b)&&(b+c>a)&&(Math.abs(a-c)<b)&&(Math.abs(a-b)<c)&&(Math.abs(c-b)<a)) { if(a==b&&b==c) { System.out.print("Equilateral triangle"); } else if((a==b||a==c||b==c)&&(Math.abs(a*a-b*b-c*c)<0.1||Math.abs(b*b-a*a-c*c)<0.1||Math.abs(c*c-b*b-a*a)<0.1)) { System.out.print("Isosceles right-angled triangle"); } else if((a==b||a==c||b==c)) { System.out.print("Isosceles triangle"); } else if((a*a==b*b+c*c||b*b==a*a+c*c||c*c==b*b+a*a)) { System.out.print("Right-angled triangle"); } else { System.out.print("General triangle"); } } else { System.out.print("Not a triangle"); } } }View Code
本题难度并不大,但在运行过程中还是遇到一点小问题,经调试以后发现是因为在判断等腰直角三角形时,因为直角边和斜边满足根2倍数关系,根2是无限小数,所以老师在给用例的时候无法给出一个准确值,因此不能用平方和的方法判断。应该用直角边的根2倍与斜边的差值绝对值是否足够小来处理问题。
具体实现:
该题较为简单,我在一个主方法中使用if嵌套if的形式完成了判断。最外围的if语句勇于判断输入是否违法,如果违法则输出WF,否则对三条边进行相关判断,如果符合条件,则输出相应的判断。
题目集2:7-4
题目要求:输入年月日的值(均为整型数),输出该日期的下一天。 其中:年份的合法取值范围为[1820,2020] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法。
我的作业代码如下:
1 import java.util.Scanner; 2 3 public class Main{ 4 5 public static void main(String[] args) { 6 // TODO Auto-generated method stub 7 Scanner input = new Scanner(System.in); 8 int a = input.nextInt(); 9 int b = input.nextInt(); 10 int c = input.nextInt(); 11 nextDate(a,b,c); 12 } 13 14 public static boolean isLeapYear(int year) { 15 return (year%400==0||(year%4==0&&year%100!=0)); 16 } 17 18 public static boolean checkInputValidity(int year,int month,int day) { 19 return (year>=1820&&year<=2020&&month>=1&&month<=12&&day>=1&&day<=31&&isMonth(year, month, day)); 20 } 21 22 public static void nextDate(int year,int month,int day) { 23 if(checkInputValidity(year, month, day)) { 24 if(month == 1||month == 3||month == 5||month == 7||month == 8||month == 10||month == 12) { 25 if((day+1)>31) { 26 month +=1; 27 day = 1; 28 if(month > 12) { 29 year +=1; 30 month = 1; 31 } 32 }else { 33 day +=1; 34 } 35 }else if(month ==2) { 36 if(isLeapYear(year)) { 37 if((day+1)>29) 38 month+=1; 39 day = 1; 40 }else { 41 if(day+1>28) { 42 month+=1; 43 day = 1; 44 } 45 } 46 }else { 47 if((day+1)>30) { 48 month +=1; 49 day = 1; 50 }else { 51 day +=1; 52 } 53 } 54 System.out.println("Next date is:"+year+"-"+month+"-"+day); 55 }else { 56 System.out.println("Wrong Format"); 57 } 58 } 59 60 public static boolean isMonth(int year,int month,int day) { 61 boolean p = false; 62 if(month == 1||month == 3||month == 5||month == 7||month == 8||month == 10||month == 12) { 63 if(day<=31) { 64 p=true;} 65 else { 66 p=false; 67 } 68 }else if(month == 2) { 69 if(isLeapYear(year)) { 70 if(day <= 29) { 71 p = true; 72 }else { 73 p = false; 74 } 75 }else { 76 if(day <=28) { 77 p = true; 78 }else { 79 p = false; 80 } 81 } 82 }else { 83 if(day <= 30) { 84 p = true; 85 }else { 86 p = false; 87 } 88 } 89 return p; 90 } 91 }View Code
该题的难度主要在于当月份及年份需要加一时该如何处理以及不同的方法间的相互调用。由于一开始没有搞清方法的含义,导致不知道该如何调用,之后也是通过看书以及在网上找资料顺利完成该题,没有其他太过复杂的问题,pta上的每个测试点都顺利通过。
具体实现:
首先我写了一个主方法,它的结构最为简单,只有几行调用语句。之后在Main类中我写了一个isLeapYear方法,将用户从键盘输入的年份作为参数传入,用该年份取400的余数,若余数为0则为闰年;或者判断该年份是否为4的倍数的同时又不是100的倍数,如符合要求则为闰年。isLeapYear返回一个boolean值。再用相同方式写一个boolean类型的方法判断输入是否违法。而最主要的方法nextDate中先调用了上述方法,读入年月日,再进行日期加1的操做;且使用判断语句if()完成年月日进1的操做(即输入日期为该月最后一天,则月份需加1;若该月为12月,则年份加1,月份变为1),且输出下一天的日期。而在主方法中我只调用了nextDate(含参)方法。
关于方法调用:
一开始我写代码时想法很简单,直接在一个Main方法里完成题目的所有要求,但那样写出来的代码可读性极差,甚至在我自己调试时都读不懂某一段代码的含义。于是我将问题分解,每一个问题对应一个方法,具体实现如下:
public static void main(String[] args);//主方法
public static boolean isLeapYear(int year) ;//判断year是否为闰年,返回boolean类型
public static boolean checkInputValidity(int year,int month,int day);//判断输入日期是否合法,返回布尔值
public static void nextDate(int year,int month,int day) ; //求输入日期的下一天
这样写出来的代码可读性较强,调试的时候也较为简单
题目集2:7-5
题目要求:输入年月日的值(均为整型数),同时输入一个取值范围在[-10,10] 之间的整型数n,输出该日期的前n天(当n > 0时)、该日期的后n天(当n<0时)。
其中年份取值范围为 [1820,2020] ,月份取值范围为[1,12] ,日期取值范围为[1,31] 。
注意:不允许使用Java中任何与日期有关的类或方法。
我的作业代码如下:
import java.util.Scanner; public class Main{ public static void main(String[] args) { // TODO Auto-generated method stub Scanner input = new Scanner(System.in); int a = input.nextInt(); int b = input.nextInt(); int c = input.nextInt(); int n = input.nextInt(); nextDate(a,b,c,n); } public static boolean isLeapYear(int year) { return (year%400==0||(year%4==0&&year%100!=0)); } public static boolean checkInputValidity(int year,int month,int day) { return (year>=1820&&year<=2020&&month>=1&&month<=12&&day>=1&&day<=31&&isMonth(year, month, day)); } public static void nextDate(int year,int month,int day,int n) { if(checkInputValidity(year, month, day)) { if(n==0) { System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); }else if(n>0&&n<=10){ if((day-n)<=0) { if(month == 1) { day = 31+day-n; month = 12; year -=1; } else if(month == 3) { month = 2; if(isLeapYear(year)) { day = 29+day-n; }else { day = 28+day-n; } }else if(month == 2||month == 4||month == 6||month == 8||month == 9||month == 11){ month -= 1; day = 31+day-n; }else { month -=1; day = 30+day-n; } }else { day -=n; } System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); }else if(n>=-10&&n<0){ if(month == 1||month == 3||month == 5||month == 7||month == 8||month == 10||month == 12) { if((day-n)>31) { month +=1; day = day-n-31; if(month > 12) { year +=1; month = 1; } }else { day -=n; } }else if(month ==2) { if(isLeapYear(year)) { if((day-n)>29) month+=1; day = day-n-29; }else { if(day-n>28) { month+=1; day = day-n-28; } } }else { if((day-n)>30) { month +=1; day = day-n-30; }else { day -= n; } } System.out.println(n+" days ago is:"+year+"-"+month+"-"+day); } }else { System.out.print("Wrong Format"); } } public static boolean isMonth(int year,int month,int day) { boolean p = false; if(month == 1||month == 3||month == 5||month == 7||month == 8||month == 10||month == 12) { if(day<=31) { p=true;} else { p=false; } }else if(month == 2) { if(isLeapYear(year)) { if(day <= 29) { p = true; }else { p = false; } }else { if(day <=28) { p = true; }else { p = false; } } }else { if(day <= 30) { p = true; }else { p = false; } } return p; } }View Code
该题主要在边界测试上遇到一些问题,有了前几题的铺垫,本题写的很快,但在测试边界时由于我自己的理解问题,导致我进行了很久的无用调试。主要是当我输入2020年12月31日时,我认为应该输出WF,结果编译器正常输出2021年1月1日;之后通过反复理解题目,我才将自己的代码提交到pta,结果通过测试。
具体实现:
该题我依旧沿用了题目7-4的部分方法(判断闰年,判断输入非法),而对nextDate方法进行改进,使得它的功能变为判断n天后的日期。具体操做为将原来nextDate方法中的加一改为减去用户从键盘输入的n天,并判断该日期是否超出了该月份的界限(若n天前为上一个月或者下一个月,则月份需要减去1或者加上1,若操做后的月份为2月还要判断该年是否为闰年,这里需要用到isLeapYear方法),之后输出n天后对应的日期。
这里依旧需要进行方法间的相互调用,通过这两个题目,使得我对调用方法这个操作变得较为熟悉,也为之后的学习打下了一些基础.
题目集3:7-2
题目要求:定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。 注意:不允许使用Java中和日期相关的类和方法,否则按0分处理。
我的作业代码如下:
import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner input = new Scanner(System.in); int a = input.nextInt(); int b = input.nextInt(); int c = input.nextInt(); Date date = new Date(); date.setYear(a); date.setMonth(b); date.setDay(c); date.nextDate(); } } class Date { private int year = 0; private int month = 0; private int day = 0; public Date(int year, int month, int day) { super(); this.year = year; this.month = month; this.day = day; } public Date() { super(); // TODO Auto-generated constructor stub } public boolean isLeapYear() { return (this.year%400==0||(this.year%4==0&&this.year%100!=0)); } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } public int getDay() { return day; } public void setDay(int day) { this.day = day; } public boolean checkInputValidity() { return (this.year>=1900&&this.year<=2000&&this.month>=1&&this.month<=12&&this.day>=1&&this.day<=31&&isMonth()); } public void nextDate() { if(checkInputValidity()) { if(this.month == 1||this.month == 3||this.month == 5||this.month == 7||this.month == 8||this.month == 10||this.month == 12) { if((this.day+1)>31) { this.month +=1; this.day = 1; if(this.month > 12) { this.year +=1; this. month = 1; } }else { this.day +=1; } }else if(this.month ==2) { if(isLeapYear()) { if((this.day+1)>29) this.month+=1; this.day = 1; }else { if(this.day+1>28) { this.month+=1; this.day = 1; } } }else { if((this.day+1)>30) { this.month +=1; this.day = 1; }else { this.day +=1; } } System.out.println("Next day is:"+this.year+"-"+this.month+"-"+this.day); }else { System.out.println("Date Format is Wrong"); } } public boolean isMonth() { boolean p = false; if(this.month == 1||this.month == 3||this.month == 5||this.month == 7||this.month == 8||this.month == 10||this.month == 12) { if(this.day<=31) { p=true;} else { p=false; } }else if(this.month == 2) { if(isLeapYear()) { if(this.day <= 29) { p = true; }else { p = false; } }else { if(this.day <=28) { p = true; }else { p = false; } } }else { if(this.day <= 30) { p = true; }else { p = false; } } return p; } }View Code
类图:
本题是题目集2:7-4的进阶版,由于一开始我不清楚类的含义,所以我直接将之前的代码粘贴到pta上且通过了测试点。后来在课堂上老师再次强调了需要用类来解决问题,于是我通过阅读相关资料完成了类的封装性并解决了问题。在这个题目中我写了两个类:Main与Date,在Main类中创建一个Date类型,并通过Date中的set方法传入参数,之后调用了Date中的NextDate方法输出了下一天。而在NextDATe方法中包含了判断闰年的方法isLeapYear()以及判断输入是否违法的checkInputValidity()。(上述方法均为我自己在编译器中编写)
具体实现:
由于本题是前两题的进阶版,所以基本思路不变,,我依旧使用的是前两次的方法;但是由于需要实现类的封装性,我对代码进行了如下修改:
- 在一个工程中定义了两个类:Main和Date,其中Date类中存放所有的方法
- 将Date类中的nextDate方法由含参改为无参,不直接向该方法传参数而是使用set方法中的this.参数
- 在Main类中定义一个Date类型,再调用相关的set和nextDate方法
之后通过接收用户从键盘输入的相关数据进行操做,具体为通过Date中的set方法将参数传递给this.参数,而后进行下一步操做(即判断下一天的日期)。
关于题目集3:7-3
题目要求:编写程序,实现对简单多项式的导函数进行求解。
具体实现:
将一元多项式按项拆开,对每一项进行操做。拆分一元多项式需要使用正则表达式。
由于能力有限,该题并没有完整的解决,主要问题在于无法正确使用正则表达式拆分一元多项式,导致后续操作无法继续进行。也因为没有解决该题,我感受到了面向对象程序设计这门课程的难度,心里的压力陡然增加。总结一下我自己的问题:
1、无法静下心来学习,自主学习能力差,容易受到外界环境影响,知识不进脑子
2、对自己没有信心。在开始看到题目要求时心里疯狂暗示自己无法完成题目要求,导致心理压力大
总之,题目集三凸显了我的很多问题,带给我的压力更是前所未有,心情很沮丧。
三、踩坑心得
- 首先是第一次作业,由于该次作业属于入门级作业,实际操作过程中并没有太多问题,只有在问题7-8中判断三角形类型时遇见了一些问题,主要还是因为没有采用计算机思维而是按照惯性思维来解决问题,使得实际解决问题时无法满足要求。
- 第二次作业中,由于一开始我将所有方法放在主方法里,导致整个程序冗长复杂且可读性极差,之后我采用将方法分开写再相互调用的操做,使得整个程序较为简洁规范。拿一个我在修改过程中遇到的实际问题来说:我在其中的两个方法中都需要判断输入年份是否为闰年,若按照我开始的想法,则需要在每个方法里复制判断闰年的代码,这使得代码量增加,一个简单的程序最后有一百多行;之后我将这个判断写成一个方法,再在其他方法中调用该方法,其他类似的方法我也如此操作,使得代码量减少了是一方面,最主要是加强了程序的可读性
- 第三次作业中一开始没有理解set方法的含义,导致修改后的代码多处报错;因为我在使用this.参数时并没有对其进行传参,导致运行无结果。之后在Main类中使用set(名称)(参数)的方法解决了该问题,具体实现如下:
public static void main(String[] args) { Scanner input = new Scanner(System.in); int a = input.nextInt(); int b = input.nextInt(); int c = input.nextInt(); Date date = new Date(); date.setYear(a); date.setMonth(b); date.setDay(c); date.nextDate(); }
View Code
四、改进建议
- 在此前的程序中使用了大量if语句,使程序圈复杂度增加,某些程序圈复杂度甚至达到几十,在之后的程序书写中可以考虑多使用while或者其他判断语句
- 有些功能不需要自己写相应方法,在Java中都有相应的方法可以直接调用;比如冒泡排序,在Java中可以直接调用Arrays.sort()方法,这一块需要自己多阅读相关资料
- 现阶段还是没有学会分析问题,经常一段程序里面去解决几个问题,导致程序耦合性高。在之后的程序书写中要学会分解问题,一个问题对应一个方法,且对应一段程序
五、总结
在这几次作业中我主要学习了Java的基本语法以及面向对象程序设计相较于c语言的不同之处(当然只是一部分),对于Java中特有的一些方法我还需要深入学习,进行进一步研究;老师在课堂上采用的是串讲的教学模式,这需要我们提前进行自学,而我有时候会感觉跟不上老师的进度,这就说明我的自学内容是不够的,我需要更多的对课本以及相关资料进行学习。
标签:阶段性,int,public,month,面向对象,课程,year,方法,day 来源: https://www.cnblogs.com/YXH-170652/p/14617170.html