java面对对象第一次博客作业

发布时间 2023-03-25 22:23:54作者: 何高翔

一、前言

1、三次pta作业的知识点

    1.java中的基础程序语法 ;

    2.数据的输入与输出;

    3.java中变量的构造;

    4.java中运算符的使用

    5.类的构造方法、方法的调用、参数传递、对象的构造与使用;

    6.String类的一些方法,和定义。

    6.Java中的控制流程(循环结构、选择结构)等;

    7.学习编写结构清晰、逻辑正确、功能完善的java代码;

    8.java方法(Method)如tostring,equals,replace

 

 

2、题量以及难度:

  •  第一次题集总量略多但单题难度不高都是比较基础的题目代码行数都不高;
  •     第二次题集数量中等但题目难度偏高要灵活构造类方法;
  •     第三次题集数量是最少的题集但单题难度过高需要灵活掌握类的使用以及封装的思想以及判断和循环的灵活运用;

二、设计与分析:

第三次pta7-3题目

定义一个类Date,包含三个私有属性年(year)、月(month)、日(day),均为整型数,其中:年份的合法取值范围为[1900,2000] ,月份合法取值范围为[1,12] ,日期合法取值范围为[1,31] 。
注意:不允许使用Java中和日期相关的类和方法,否则按0分处理。

要求:Date类结构如下图所示:

类图.jpg

输入格式:

在一行内输入年月日的值,均为整型数,可以用一到多个空格或回车分隔。

输出格式:

    • 当输入数据非法及输入日期不存在时,输出“Date Format is Wrong”;
    • 当输入日期合法,输出下一天,格式如下:Next day is:年-月-日

 

题集3的7-3生成分析报告

 

 

 

题集3的7-3的类关系图

 

 

 

源代码

import java.util.Scanner;
public class Main {


public static void main(String[] args) {
Scanner in=new Scanner(System.in);
Date date=new Date();
int year=in.nextInt();
int month=in.nextInt();
int day=in.nextInt();

date.setYear(year);
date.setMonth(month);
date.setDay(day);
if(date.checkInputValidity( year, month, day))
date.getNextDate(year, month, day);
else {
System.out.print("Date Format is Wrong");

}
}
}
class Date{
private int year;
private int month;
private int day;

//private int[] mon_maxunm=new int[] {0,31,28,31,30,31,30,31,31,30,31,30,31};



// public Date(int year, int month, int day) {
// super();
// this.year = year;
// this.month = month;
// this.day = day;
// }

public Date() {
super();
// TODO 自动生成的构造函数存根
}

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 isLeapYear(int year){
if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
return true;
return false;
}

public boolean checkInputValidity(int year,int month,int day) {
if(year<1900||year>2000||month>12||month<1||day<1||day>31) {
return false;
}
if(isLeapYear(year)){
if((month==4||month==6||month==9||month==11)&&day>30)
return false;
if(month==2&&day>29)
return false;
}
else{
if((month==4||month==6||month==9||month==11)&&day>30)
return false;
if(month==2&&day>28)
return false;
}
return true;
}

public void getNextDate(int year,int month,int day) {
int nextYear = year;
int nextMonth = month;
int nextDay = day + 1;

if (month == 2) {
if (isLeapYear(nextYear)) {
if (nextDay > 29) {
nextMonth = 3;
nextDay = 1;
}
} else {
if (nextDay > 28) {
nextMonth = 3;
nextDay = 1;
}
}
} else if (month == 4 || month == 6 || month == 9 || month == 11) {
if (nextDay > 30) {
nextMonth++;
nextDay = 1;
}
} else {
if (nextDay > 31) {
nextMonth++;
nextDay = 1;
if (nextMonth > 12) {
nextMonth = 1;
nextYear++;
}
}
}
System.out.println("Next day is:" + nextYear+"-" + nextMonth + "-" + nextDay );
}
}

 

第4次pta7-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”格式返回日期值
 

应用程序共测试三个功能:

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数

注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)

程序主方法如下:

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);
        }        
    }
}
 

输入格式:

有三种输入方式(以输入的第一个数字划分[1,3]):

  • 1 year month day n //测试输入日期的下n天
  • 2 year month day n //测试输入日期的前n天
  • 3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数

输出格式:

  • 当输入有误时,输出格式如下:
    Wrong Format
  • 当第一个数字为1且输入均有效,输出格式如下:
    year1-month1-day1 next n days is:year2-month2-day2
    
     
  • 当第一个数字为2且输入均有效,输出格式如下:
    year1-month1-day1 previous n days is:year2-month2-day2
    
     
  • 当第一个数字为3且输入均有效,输出格式如下:

    The days between year1-month1-day1 and year2-month2-day2 are:值

     

 

题集3的7-4生成分析报告

 

 

 

 

题集3的7-4的类关系图

 

 

 

源代码

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);
}
}
}


class DateUtil{
private int year;
private int month;
private int day;
private int[] mon_maxnum = new int[] {0,31,28,31,30,31,30,31,31,30,31,30,31};

public DateUtil(int year, int month, int day) {
super();
this.year = year;
this.month = month;
this.day = day;
}

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 isLeapYear(int year){
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}

public boolean checkInputValidity() {
if(year<1820||year>2020||month>12||month<1||day<1||day>31) {
return false;
}
if(isLeapYear(year)){
if((month==4||month==6||month==9||month==11)&&day>30)
return false;
if(month==2&&day>29)
return false;
}
else{
if((month==4||month==6||month==9||month==11)&&day>30)
return false;
if(month==2&&day>28)
return false;
}
return true;
}

public DateUtil getNextNDays(int n) {

while (n > 0) {
int maxDay = mon_maxnum[month];
if (month == 2 && isLeapYear(year)) {
maxDay = 29;
}

if (day < maxDay) {
day++;
} else {
day = 1;
if (month < 12) {
month++;
} else {
month = 1;
year++;
}
}
n--;
}

return new DateUtil(year, month, day);
}

public DateUtil getPreviousNDays(int n) {
int day = this.day - n;
int month = this.month;
int year = this.year;
while (day < 1) {
month--;
if (month < 1) {
month = 12;
year--;
}
if (month == 2 && isLeapYear(year)) {
mon_maxnum[2] = 29;
} else {
mon_maxnum[2] = 28;
}
day += mon_maxnum[month ];
}
return new DateUtil(year, month, day);
}

public boolean compareDates(DateUtil date) {
if (year < date.getYear()) {
return true;
} else if (year > date.getYear()) {
return false;
} else if (month < date.getMonth()) {
return true;
} else if (month > date.getMonth()) {
return false;
} else if (day < date.getDay()) {
return true;
} else {
return false;
}
}

public boolean equalTwoDates(DateUtil date) {
return (year == date.getYear() && month == date.getMonth() && day == date.getDay());
}

public int getDaysofDates(DateUtil date) {
int days = 0;
DateUtil earlierDate;
DateUtil laterDate;

if (compareDates(date)) {
earlierDate = this;
laterDate = date;
} else {
earlierDate = date;
laterDate = this;
}
while (earlierDate.getYear() < laterDate.getYear()
|| (earlierDate.getYear() == laterDate.getYear() && earlierDate.getMonth() < laterDate.getMonth())
|| (earlierDate.getYear() == laterDate.getYear() && earlierDate.getMonth() == laterDate.getMonth() && earlierDate.getDay() < laterDate.getDay())) {
days++;
earlierDate = earlierDate.getNextNDays(1);
}
return days;
}



public String showDate() {
return year+"-"+month+"-"+day;
}

}

 

三、采坑心得

1.第一次作业中,提交代码时经常会有编译错误,编译错误的问题比较容易解决。一般就是代码格式不符合要求。比如public class Main,类必须是Main,这是第一次提交作业时遇到的简单的编译问题。

2.第二次作业相对第一次作业,难度上有了很大的提升。不过和第一次作业相似,基本上代码都是在主函数里完成的,使用的方法和c语言相似。不同的是,我开始在主方法外定义方法,并且在主方法中调用自己定义过的方法。通过这样使我的代码更加简洁。

3.第三次作业难度大有提升,前两题还好并不是太难做出来,第三题求一元多项式的倒数,我至今还没有实现。前两道题目类似,但也还是比较复杂,第三次作业是和类有关的。我们开始自己使用类来编写程序,比如7-1中让我们创建账户类,并要求使用私有属性。使用指定的方法,在这个题中,一共有两个类,第一个类中是主方法。账户类中有自己定义的属性,自己定义的方法。程序要求使用构造方法,一开始不怎么理解构造方法,不知道为什么要有个无参构造方法,还要有个有参的构造方法。构造方法原来是为了给类中的属性初始化,还有getter和setter方法,一开始都不是很理解,通过不断查阅资料才发现这种方法也是为了该类中的属性。

4.条件判断表达式比较长的情况下,可以封装成一个方法isXXX(),返回boolean

5.当出现最大值这个点的错误时,变量的类型看看是不是有问题,如把int改成long,把范围扩大。

7.在使用eclipse时因为不熟练常常出现一些操作性问题,伤害不大,但是烦人又费时

8.不会设置测试用例,面对多且杂的测试点一筹莫展,只会把源码看一遍又一遍。好在老师前几天讲课讲了如何设置测试点,很有帮助

9.一定要仔细审题,先构思类图与类与类的关系,再构思方法,最后再动手写。

10.Java变量的命名规则如下:

(1).可以以数字、字母、‘_’、'$'符组成

(2).首字符不能以数字开头

(3).中文可以作为变量名,但不提倡使用

(4).Java大小写敏感,命名变量时要注意

(5).不能使用Java保留字

 

 

四、改进建议

  题目集2的7-2、7-3可以用函数形式来表达;题目集3的7-1的类的设计不合理,可将格式检查、字符串转换、点这三个类合并,让代码更简洁明了;题目集3的7-2、7-3两题在设计类方法时传参时不妥,导致方法的重复使用增加了难度,因此我认为在设计方法时设计好传参对于函数重复使用是很重要的。然后就是编写代码的习惯并不好,这要在之后的练习中不断地改进,不断养成一个好的习惯,让代码逻辑性、可读性更佳。

       写程序时应先确定一个思路再顺着往下写,要是边写边想边改,会造成代码思路不清晰且难以找出错误。

 

 

五、总结

  目集1的大部分题目,几乎第一次提交就通过所有测试点;题目二对我来说有一定的难度,很多测试点不能通过,所以我花费了大量的时间提交测试,虽然最终通过,但多次修改导致代码复杂性高,可读性不高;题目三虽然只有四道题,但我只能写出算法,多次修改了好久才发现问题所在。所以越长越复杂的题目,越应该确定思路。

       这三次作业,每一次都是很有价值的,题目的难度梯度在攀升,也需要我们自己更多的去总结,反思。之所以老师布置博客作业来总结,是给我更多的时间去认识自己的不足,缺点,改正错误。三次作业搭配一次博客作业,我认为这种学习方法非常适用我们这个专业的学习,不仅能通过大量的实践提升自己写代码的能力。写完代码后,又有一定的时间消化知识点。争取在每一次的作业中都能够发现自己的问题,改进曾经出现过的问题,把每一次程序往好的去做。

       这几次作业最明显的感觉就是类的构造吧,我想,这也是老师要求我们必须要掌握的东西。通过学会类的使用,在学会多种函数中需要用到的方法,熟练运用。但前几次作业,发现自己并没有掌握好类应该如何使用。前几次作业,就第三次作业的7-2用到了类,并且根据题目中的要求给予类中属性和构造方法。在主方法中调用自创类中的方法。

       老师平时督促也很紧,但更多的还是需要我们自主学习。平时课程为线上线下双教学模式,老师上课讲的东西更具有针对性,对我们的作业有启发。而课下更需要自己去钻研,要有不怕累,不怕苦的精神。