OOP第一次作业总结
一、前言
大一上学习完C语言程序设计课程后,第一次接触Java语言和面向对象,对Java语言的语法还尚不熟悉,前两次训练集主要训练了Java的语法,从第三次训练集开始训练类的设计和使用,前两周还在适应期,代码不规范,可读性很差,后面随着训练,自认为可读性应该强了不少。
训练集01总共12道题,说实话对于才刚开始学习Java语法的我来说,题量比较大,一开始也总编译错误,对Java语法完全不熟悉,在简单的题上浪费了许多时间,但其实训练集01的题难度不算很大,除了那道GPS数据处理的题,训练的知识点其实都是选择、循环、数组、字符串等较基础的Java语法。因为刚从C/C++转入Java,正在适应期,对IDE工具的使用也不够老练,在PTA上编译了许多次,总因为语法错误编译错误。现在回头再看一遍题目,难度其实并不高。
训练集02总共9道题,题量一般,主要训练逻辑思维,大部分是计算题,此时已经过训练集01的训练,难度较低,当然除了最后一道题。最后一道题“求下一天”有点难度,这道题也是我花费时间最多的一天,题目给了方法名和需求,需要自己写方法,而因为有闰年平年大月小月,有很多细节需要照顾到。
训练集03虽然只有4道题,但是难度较高,涉及到了类的设计,这次训练集花费的时间最多。接下来会对其重点分析。
二、设计与分析
1.创建圆形类
编写一个圆形类Circle,一个私有实型属性半径,要求写出带参数构造方法、无参构造方法、属性的getter、setter方法以及求面积、输出数据等方法,具体格式见输入、输出样例。
以下为我的代码:
1 import java.util.*; 2 public class Main{ 3 public static void main(String[] args){ 4 Circle c=new Circle(); 5 Scanner in=new Scanner(System.in); 6 double r1 = in.nextDouble(); 7 c.setRadius(r1); 8 c.prin(); 9 } 10 } 11 12 class Circle{ 13 private double radius; 14 public void setRadius(double r){ 15 radius=r; 16 17 } 18 public double getRadius(){ 19 return radius; 20 21 } 22 public double getArea(){ 23 return Math.PI*radius*radius; 24 } 25 public void prin(){ 26 if(radius<0){ 27 System.out.print("Wrong Format"); 28 } 29 else{ 30 System.out.printf("The circle's radius is:%.2f\n",getRadius()); 31 System.out.printf("The circle's area is:%.2f\n",getArea()); 32 } 33 34 } 35 }
类图如下:

第一道题非常简单,只是为学习类的设计开了个头。但是我还是没写好,应该再在Circle类里面加上
public Circle{ } public Circle(double radius){ radius=this.radius; }
并且加上this关键字会更加规范。
2.创建账户类Account
设计一个名称为Account的类,具体包括:
- id:账号,私有属性,整型,默认值为0;
- balance:余额,私有属性,实型,默认值为0;
- annualInterestRate:当前利率,私有属性,实型,默认值为0,假设所有帐户均有相同的利率;
- dateCreated:账户开户时间,私有属性,LocalDate类型,默认为2020年7月31日;
- 一个能创建默认账户的无参构造方法;
- 一个能创建带特定id和初始余额的账户的构造方法;
- id、balance、annualInterstRate的getter及setter方法;
- dateCreated的getter方法;
- 一个名为getMonthlyInterestRate()的方法返回月利率(月利率计算公式:余额*(年利率/1200));
- 一个名为withDraw的方法从账户提取特定数额,当提取数额大于余额或为负数系统返回
WithDraw Amount Wrong提示; - 一个名为deposit的方法向账户存储特定数额,当存储数额大于20000元或为负数系统返回
Deposit Amount Wrong提示。
编写一个测试程序:
- 创建一个账户,其账户id、余额及利率分别有键盘输入,账户开户时间取系统当前时间;
- 输入取钱金额,系统进行取钱操作,如果取钱金额有误,则输出提示信息后系统继续运行;
- 输入存钱金额,系统进行存钱操作,如果存钱金额有误,则输出提示信息后系统继续运行;
系统输出,以如下格式分别输出该账户余额、月利息以及开户日期(输出实型数均保留两位小数)
以下为我的代码:
1 import java.util.Scanner; 2 import java.time.LocalDate; 3 4 public class Main{ 5 static class Account{ 6 private int id; 7 private double balance; 8 private double annuallnterestRate; 9 private LocalDate dateCreated=LocalDate.of(2020,7,31); 10 public Account(){ 11 12 } 13 public Account(int id,double balance){ 14 this.id=id; 15 this.balance=balance; 16 } 17 public int getId(){ 18 return this.id; 19 } 20 public double getAnnuallnterestRate(){ 21 return this.annuallnterestRate; 22 } 23 public void setAnnuallnterestRate(double annuallnterestRate){ 24 this.annuallnterestRate=annuallnterestRate; 25 } 26 public LocalDate getDateCreated(){ 27 return this.dateCreated; 28 } 29 public double getMonthlyInterestRate(){ 30 return this.balance*(this.annuallnterestRate/1200); 31 } 32 public void withDraw(double amount){ 33 if(amount>balance||amount<0){ 34 System.out.println("WithDraw Amount Wrong"); 35 } 36 else 37 this.balance-=amount; 38 } 39 public void deposit(double amount){ 40 if(amount>20000||amount<0){ 41 System.out.println("Deposit Amount Wrong"); 42 } 43 else 44 this.balance+=amount; 45 } 46 public double getBalance(){ 47 return this.balance; 48 } 49 } 50 public static void main(String[] args){ 51 Scanner in=new Scanner(System.in); 52 int id=in.nextInt(); 53 double balance=in.nextDouble(); 54 Account acc=new Account(id,balance); 55 56 double annuallnterestRate=in.nextDouble(); 57 acc.getAnnuallnterestRate(); 58 acc.setAnnuallnterestRate(annuallnterestRate); 59 60 LocalDate date =LocalDate.now(); 61 62 double tiAmount=in.nextDouble(); 63 acc.withDraw(tiAmount); 64 double cunAmount=in.nextDouble(); 65 acc.deposit(cunAmount); 66 67 System.out.printf("The Account'balance:%.2f\n",acc.getBalance()); 68 acc.getAnnuallnterestRate(); 69 LocalDate dateCreated=acc.getDateCreated(); 70 System.out.printf("The Monthly interest:%.2f\n",acc.getMonthlyInterestRate()); 71 System.out.printf("The Account'dateCreated:%d-%02d-%d",dateCreated.getYear(),dateCreated.getMonthValue(),dateCreated.getDayOfMonth()); 72 } 73 }
这道题已经给了很清楚的方法,这道题照着需求写就可以了。首先定义属性,其中存储了账户id、余额、年利率和开户日期等信息,并提供了存款、取款、计算月利率等功能。在主函数中,通过Scanner获取用户输入的账户信息,包括id、余额、年利率,以及取款和存款金额。最终输出账户余额、月利率、开户日期等信息。使用面向对象的编程思想,将账户信息封装在Account类中,并通过方法来提供各种操作。我还使用了局部类(LocalDate)以完成 账户开户时间取系统当前时间 的功能实现。
类图如下:

3.定义日期类
定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。
要求类图如下:

以下为我的代码:
import java.util.Scanner; public class Main{ static class Date{ private int year; public int getYear(){ return this.year; } public void setYear(int year){ if(year>=1900&&year<=2000){ this.year=year; }
} private int month; public int getMonth(){ return this.month; } public void setMonth(int month){ if(month>=1&&month<=12){ this.month=month; } } private int day; public int getDay(){ return this.day; } public void setDay(int day){ if(day>=1&&day<=31){ this.day=day; } } public Date(){ } public Date(int year,int month,int day){ this.year=year; this.month=month; this.day=day; } private int[] mon_maxnum=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; public boolean isLeapYear(int year){ if(year%4==0&&year%100!=0||year%400==0){ return true; } else{ return false; } } public boolean checkInputValidity(){ if(this.year<1900||this.year>2000||this.month<1||this.month>12||this.day<1||this.day>31) return false; else if(this.month==2){ if(this.year%4==0&&this.year%100!=0||this.year%400==0){ if(this.day>29) return false; else return true; } else{ if(this.day>28) return false; else return true; } } else if(this.day>mon_maxnum[this.month]) return false; else return true; } public void getNextDate(){ if(this.year%4==0&&this.year%100!=0||this.year%400==0){ mon_maxnum[2]=29; if(this.month==12&&this.day==31){ if(this.year==2000) System.out.print("Date Format is Wrong"); else if(this.year!=2000) System.out.print("Next day is:"+(this.year+1)+"-1-1"); } else if(this.month!=12 && this.day==mon_maxnum[this.month]){ System.out.print("Next day is:"+this.year+"-"+(this.month+1)+"-1"); } else{ System.out.print("Next day is:"+this.year+"-"+this.month+"-"+(this.day+1)); } } else{ if(this.month==12&&this.day==31){ if(this.year==2000) System.out.print("Date Format is Wrong"); else if(this.year!=2000) System.out.print("Next day is:"+(this.year+1)+"-1-1"); } else if(this.month!=12 && this.day==mon_maxnum[this.month]){ System.out.print("Next day is:"+this.year+"-"+(this.month+1)+"-1"); } else{ System.out.print("Next day is:"+this.year+"-"+this.month+"-"+(this.day+1)); } } } } public static void main(String[] args){ Scanner in=new Scanner(System.in); Date d=new Date(); int year=in.nextInt(); int month=in.nextInt(); int day=in.nextInt(); d.getYear(); d.setYear(year); d.getMonth(); d.setMonth(month); d.getDay(); d.setDay(day); if(d.checkInputValidity()){ d.getNextDate(); } else{ System.out.print("Date Format is Wrong"); } } }
Date类包含了私有的年、月、日成员变量(year, month, day),以及对应的get和set方法。其中,set方法采用了参数检查机制,如果输入的年份、月份或日份不在合法范围内,就不会进行传参。Date类还包含了一个无参构造函数和一个有参构造函数,分别可以创建空的或指定日期的日期对象。另外,根据给出类图定义了一个私有成员数组mon_maxnum,用于存储每个月份的最大天数。 Date类还包含了:一个检查日期输入是否合法的方法checkInputValidity(),通过检查年、月、日是否在合法范围内来判断输入是否正确,这个方法的实现依赖于之前的日期成员变量和set方法;一个判断当前年份是否为闰年的方法isLeapYear(),基于闰年的定义来进行实现,这个方法的实现比较简单,只需要分别对年份取余并进行判断即可;一个获取下一个日期的方法getNextDate(),通过判断年份是否为闰年,月份是否是12月,日份是否为最大天数等条件,进行计算和输出下一个日期信息。
4.日期类设计
参考题目3和日期相关的程序,设计一个类DateUtil,该类有三个私有属性year、month、day(均为整型数),其中,year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 除了创建该类的构造方法、属性的getter及setter方法外,需要编写如下方法:
public boolean checkInputValidity();//检测输入的年、月、日是否合法 public boolean isLeapYear(int year);//判断year是否为闰年 public DateUtil getNextNDays(int n);//取得year-month-day的下n天日期 public DateUtil getPreviousNDays(int n);//取得year-month-day的前n天日期 public boolean compareDates(DateUtil date);//比较当前日期与date的大小(先后) public boolean equalTwoDates(DateUtil date);//判断两个日期是否相等 public int getDaysofDates(DateUtil date);//求当前日期与date之间相差的天数 public String showDate();//以“year-month-day”格式返回日期值
应用程序共测试三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
题目已给出主方法:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int year = 0; int month = 0; int day = 0; int choice = input.nextInt(); if (choice == 1) { // test getNextNDays method int m = 0; year = Integer.parseInt(input.next()); month = Integer.parseInt(input.next()); day = Integer.parseInt(input.next()); DateUtil date = new DateUtil(year, month, day); if (!date.checkInputValidity()) { System.out.println("Wrong Format"); System.exit(0); } m = input.nextInt(); if (m < 0) { System.out.println("Wrong Format"); System.exit(0); } System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:"); System.out.println(date.getNextNDays(m).showDate()); } else if (choice == 2) { // test getPreviousNDays method int n = 0; year = Integer.parseInt(input.next()); month = Integer.parseInt(input.next()); day = Integer.parseInt(input.next()); DateUtil date = new DateUtil(year, month, day); if (!date.checkInputValidity()) { System.out.println("Wrong Format"); System.exit(0); } n = input.nextInt(); if (n < 0) { System.out.println("Wrong Format"); System.exit(0); } System.out.print( date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:"); System.out.println(date.getPreviousNDays(n).showDate()); } else if (choice == 3) { //test getDaysofDates method year = Integer.parseInt(input.next()); month = Integer.parseInt(input.next()); day = Integer.parseInt(input.next()); int anotherYear = Integer.parseInt(input.next()); int anotherMonth = Integer.parseInt(input.next()); int anotherDay = Integer.parseInt(input.next()); DateUtil fromDate = new DateUtil(year, month, day); DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay); if (fromDate.checkInputValidity() && toDate.checkInputValidity()) { System.out.println("The days between " + fromDate.showDate() + " and " + toDate.showDate() + " are:" + fromDate.getDaysofDates(toDate)); } else { System.out.println("Wrong Format"); System.exit(0); } } else{ System.out.println("Wrong Format"); System.exit(0); } } }
以下为我设计的类图:

DateUtil类的代码如下:
static class DateUtil { private int year; public int getYear() { return year; } public void setYear(int year) { this.year = year; } private int month; public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } private int day; public int getDay() { return day; } public void setDay(int day) { this.day = day; } private int[] mon_maxnum=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; public DateUtil(){ } public DateUtil(int year, int month, int day) { this.year = year; this.month = month; this.day = day; } public boolean checkInputValidity() {//检测输入的年、月、日是否合法 if (this.year < 1820 || this.year > 2020 || this.month < 1 || this.month > 12 || this.day < 1 || this.day > 31) return false; else if (this.month == 2) { if (this.year % 4 == 0 && this.year % 100 != 0 || this.year % 400 == 0) { if (this.day > 29) return false; else return true; } else { if (this.day > 28) return false; else return true; } } else if (this.day > mon_maxnum[this.month]) return false; else return true; } public boolean isLeapYear(int year) {//判断year是否为闰年 if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) { return true; } return false; } public DateUtil getNextDay(){ int newYear = 0; int newMonth = 0; int newDay = 0; if(this.year%4==0&&this.year%100!=0||this.year%400==0){ mon_maxnum[2]=29; if(this.month==12&&this.day==31){ if(this.year!=2020){ newYear =this.year + 1; newMonth = 1; newDay = 1; } } else if(this.month!=12 && this.day==mon_maxnum[this.month]){ newYear = this.year; newMonth = this.month + 1; newDay = 1; } else{ newYear = this.year; newMonth = this.month; newDay = this.day + 1; } } else{ if(this.month==12&&this.day==31){ if(this.year==2020) System.out.print("Wrong Format"); else if(this.year!=2020){ newYear = this.year + 1; newMonth = 1; newDay = 1; } } else if(this.month!=12 && this.day==mon_maxnum[this.month]){ newYear = this.year; newMonth = this.month + 1; newDay = 1; } else{ newYear = this.year; newMonth = this.month; newDay = this.day + 1; } } return new DateUtil(newYear, newMonth, newDay); } public DateUtil getNextNDays(int n) {//取得year-month-day的下n天日期 DateUtil newDate = new DateUtil(year, month, day); int newYear = this.year; int newMonth = this.month; int newDay = this.day; for (int i = 0; i < n; i++) { //newDate = newDate.getNextDay(); if(newYear%4==0&&newYear%100!=0||newYear%400==0){ mon_maxnum[2]=29; if(newMonth==12&&newDay==31){ newYear =newYear + 1; newMonth = 1; newDay = 1; } else if(newMonth!=12 && newDay==mon_maxnum[newMonth]){ newMonth = newMonth + 1; newDay = 1; } else{ newDay = newDay + 1; } } else{ mon_maxnum[2]=28; if(newMonth==12&&newDay==31){ newYear = newYear + 1; newMonth = 1; newDay = 1; } else if(newMonth!=12 && newDay==mon_maxnum[newMonth]){ newMonth = newMonth + 1; newDay = 1; } else{ newDay = newDay + 1; } } } return new DateUtil(newYear, newMonth, newDay); } public DateUtil getPreviousDay(){ int newYear = 0; int newMonth = 0; int newDay = 0; if(this.day==1 && (this.month==2 || this.month==4 || this.month==6 || this.month==8 || this.month==9 || this.month==11 || this.month==1)){ if(this.month == 1){ newYear = this.year - 1; newMonth = 12; newDay = 31; } else{ newYear = this.year; newMonth = this.month - 1; newDay = 31; } } else if(day==1 && (this.month==5 || this.month==7 || this.month==10 || this.month==12)){ newYear = this.year; newMonth = this.month - 1; newDay = 30; } else if(day==1 && month==3 && !isLeapYear(year)){ newYear = this.year; newMonth = 2; newDay = 28; } else if(day==1 && month==3 && isLeapYear(year)){ newYear = this.year; newMonth = 2; newDay = 29; } else{ newYear = this.year; newMonth = this.month; newDay = this.day - 1; } return new DateUtil(newYear, newMonth, newDay); } public DateUtil getPreviousNDays(int n) {//取得year-month-day的前n天日期 DateUtil newDate = new DateUtil(year,month,day); for (int i=0;i<n;i++){ newDate = newDate.getPreviousDay(); } return newDate; } public boolean compareDates(DateUtil date) {//比较当前日期与date的大小(先后) if (this.year > date.getYear()) { return true; } else if (this.year < date.getYear()) { return false; } else { if (this.month > date.getMonth()) { return true; } else if (this.month < date.getMonth()) { return false; } else { if (this.day > date.getDay()) { return true; } else { return false; } } } } public boolean equalTwoDates(DateUtil date) {//判断两个日期是否相等 if (this.year == date.getYear() && this.month == date.getMonth() && this.day == date.getDay()) { return true; } else return false; } public int getDaysofDates(DateUtil date) {//求当前日期与date之间相差的天数 int days = 0; if (compareDates(date)) { while (!equalTwoDates(date)) { date = date.getNextDay(); days++; } } else { while (!equalTwoDates(date)) { date = date.getPreviousDay(); days++; } } return days; } public String showDate(){//以“year-month-day”格式返回日期值 return year+"-"+month+"-"+day; } }
题目4是题目3的拓展,如果整理好思路和设计对方法可以较快解决这道题。参考题目3(求下一天),设计一个求下一天的方法,在求下n天的方法中的循环中调用,求前n天是同一个道理,设计一个求前一天的方法,在求前n天的方法中的循环中调用。而在求当前日期与date之间相差的天数,也调用了求下一天的方法和求前一天的方法,以及比较当前日期与date的大小(先后)的方法和判断两个日期是否相等的方法,如在先,则循环求下一天直至两个日期相等;如在后,则循环求前一天直至两个日期相等。不过我这个代码写的很糟糕,具体在踩坑心得中说吧。
三、踩坑心得
踩坑心得主要是对训练集03的第三题和第四题进行总结。
- 题目3提交了差不多5次,编译成功后主要是无效边界值测试总是过不去,一开始跨年测试和闰年12月底测定点也没过,后来发现,其实是格式不对,我却还以为我在闰年的时候把mon_maxnum[2]的值改成29,而后面没改回来的原因,折腾了一番才突然醒悟,在闰年的时候把mon_maxnum[2]的值改成29放在if里面,怎么也不影响后面的过程。还有一个原因可能是其中有一个测试点应该是输入2000 12 31是,我也认定为输入数据非法。
以下是只得了22分的代码和测试点错误截图:

import java.util.Scanner; public class Main{ static class Date{ private int year; public int getYear(){ return this.year; } public void setYear(int year){ if(year>=1900&&year<=2000){ this.year=year; } else{ System.out.println("Date Format is Wrong"); return; } } private int month; public int getMonth(){ return this.month; } public void setMonth(int month){ if(month>=1&&month<=12){ this.month=month; } else{ System.out.println("Date Format is Wrong"); return; } } private int day; public int getDay(){ return this.day; } public void setDay(int day){ if(day>=1&&day<=31){ this.day=day; } else{ System.out.println("Date Format is Wrong"); return; } } public Date(){ } public Date(int year,int month,int day){ this.year=year; this.month=month; this.day=day; } private int[] mon_maxnum=new int[]{0,31,28,31,30,31,30,31,31,30,31,30,31}; public boolean isLeapYear(int year){ if(year%4==0&&year%100!=0||year%400==0){ return true; } else{ return false; } } public boolean checkInputValidity(){ if(this.month==2){ if(this.year%4==0&&this.year%100!=0||this.year%400==0){ if(this.day>29) return false; else return true; } else{ if(this.day>28) return false; else return true; } } if(this.day>mon_maxnum[this.month]) return false; else return true; } public void getNextDate(){ if(this.year%4==0&&this.year%100!=0||this.year%400==0){ mon_maxnum[2]=29; if(this.month==12&&this.day==31){ if(this.year==2000) System.out.print("Date Format is Wrong"); else if(this.year!=2000) System.out.print("Next day is:"+(this.year+1)+"-1-1"); } else if(this.month!=12 && this.day==mon_maxnum[this.month]){ System.out.print("Next day is:"+this.year+"-"+(this.month+1)+"-1"); } else{ System.out.print("Next day is:"+this.year+"-"+this.month+"-"+(this.day+1)); } } else{ if(this.month==12&&this.day==31){ if(this.year==2000) System.out.print("Date Format is Wrong"); else if(this.year!=2000) System.out.print("Next day is:"+(this.year+1)+"-1-1"); } else if(this.month!=12 && this.day==mon_maxnum[this.month]){ System.out.print("Next day is:"+this.year+"-"+(this.month+1)+"-1"); } else{ System.out.print("Next day is:"+this.year+"-"+this.month+"-"+(this.day+1)); } } } } public static void main(String[] args){ Scanner in=new Scanner(System.in); Date d=new Date(); int year=in.nextInt(); int month=in.nextInt(); int day=in.nextInt(); d.getYear(); d.setYear(year); d.getMonth(); d.setMonth(month); d.getDay(); d.setDay(day); if(d.checkInputValidity()){ d.getNextDate(); } else{ System.out.print("Date Format is Wrong"); } } }
全是无效边界值测试点错误,随便输入一个非法测试值,运行结果如下:

可以很清楚地看到,输出“Date Format is Wrong"后还紧接着输出了下一天。
再看其它的测试值


可以看到闰年平年的二月测试是没有问题的,问题出在年份和月份上,月份输入非法以及月和日对应不上又会再输出一遍”Date Format is Wrong"。所以问题应该出在年份还有return上。也是我没设计好的原因,我对于非法输入的判断写的很分散,并没有全部写在一个方法里,后来修改在全都写在一个方法checkInputValidity(),就解决了这个问题。
- 题目4踩的最大一个坑是内存超限。
我真的,哭死。本来以为我想的这个设计天衣无缝(详情见二、设计与分析),没想到居然内存超限了......

在idea上测试这两个点,答案是也是错的.......后面又小改了下方法,结果错的测试点更多,但是内存不超限了,反正越改越错......后来听了同学的建议,我重新写过了getNextDays()方法,代码如下:
public DateUtil getNextNDays(int n) {//取得year-month-day的下n天日期 DateUtil newDate = new DateUtil(year, month, day); int newYear = this.year; int newMonth = this.month; int newDay = this.day; for (int i = 0; i < n; i++) { //newDate = newDate.getNextDay();这是之前写的方法里,调用getNextDay(),这样写会内存超限 if(newYear%4==0&&newYear%100!=0||newYear%400==0){ mon_maxnum[2]=29; if(newMonth==12&&newDay==31){ newYear =newYear + 1; newMonth = 1; newDay = 1; } else if(newMonth!=12 && newDay==mon_maxnum[newMonth]){ newMonth = newMonth + 1; newDay = 1; } else{ newDay = newDay + 1; } } else{ mon_maxnum[2]=28; if(newMonth==12&&newDay==31){ newYear = newYear + 1; newMonth = 1; newDay = 1; } else if(newMonth!=12 && newDay==mon_maxnum[newMonth]){ newMonth = newMonth + 1; newDay = 1; } else{ newDay = newDay + 1; } } } return new DateUtil(newYear, newMonth, newDay); }
我不在getNextDays()里调用getNxetDay(),删除之后重新写过,就好了,求下n天的代码超限的问题解决了,求前n天的问题也是一样的,所以我打算,用和求下n天一样的解决办法,然后写完发现,代码长度又超出限制!.......我的代码太乱太冗长了,再这么一改,已经有三四百行了。但是又不能直接删掉getNxetDay()和getPreviousDay(),因为我在getDaysofDates(DateUtil date)中也调用了这两个方法,如果删掉,getDaysofDates(DateUtil date)也要重新写过,但我暂时还没想到怎么重新写,我当时脑子里就这一个方案。
四、改进建议
对于训练集03的题目四,上面已经说过问题了,如果把getNxtDay()和getPreviousDay()删掉,那么重新写过getDaysofDates(DateUtil date),代码如下:
1 public int getDaysofDates(DateUtil date){ 2 int count1=0; 3 int count2=0; 4 for(int i=1820;i<this.year;i++){ 5 if(isLeapYear(i)) 6 count1+=366; 7 else count1+=365; 8 } 9 for(int j=1;j<this.month ;j++){ 10 if(isLeapYear(this.year)){ 11 mon_maxnum[2]=29; 12 } 13 else mon_maxnum[2]=28; 14 count1+=mon_maxnum[j]; 15 } 16 count1+=this.day ; 17 for(int i=1820;i<date.year;i++){ 18 if(isLeapYear(i)) 19 count2+=366; 20 else count2+=365; 21 } 22 for(int j=1;j<date.month ;j++){ 23 if(isLeapYear(date.year)){ 24 mon_maxnum[2]=29; 25 } 26 else mon_maxnum[2]=28; 27 count2+=mon_maxnum[j]; 28 } 29 count2+=date.day ; 30 return Math.abs(count1-count2) ; 31 }
这样改过之后,再把getNxtDay()和getPreviousDay()删掉,getPreviousDays()参照getNxtDays()重新写过,不再调用getPreviousDay(),内存不超限,代码也不会超过规定长度。
另外,对于这三次训练集,我应该再多一些注释,目前看来,这三次训练集的题目我是一点注释没写,之后应该多写注释。因为在后面修改代码时,一旦代码一长,我自己也总找不到自己要找要修改的代码在哪,一定要养成写注释的习惯。
五、总结
通过这三次训练集,我对Java语法的运用更加熟练了,前两个星期主要学习和练习Java语法。第三个星期主要学习了类的设计,学习了采用内部类实现对象的创建和访问控制,封装成员变量和方法来确保信息安全和正确性。通过训练,能够运用一点点一些比较典型的面向对象编程思想和技巧,但是还不足以在面向对象这一门中达到入门。在写PTA作业时,还是感到很匆忙,感觉时间不够用,还须加强时间管理能力。对一些Java语法的知识点还是不太了解,没有学习完全,有时候还需要查找资料来辅助完成作业,还须在Java语法方面再深入学习。
不足还有很多,少年还须努力。

浙公网安备 33010602011771号