OOP第一次博客作业
Posted jujujujuluo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OOP第一次博客作业相关的知识,希望对你有一定的参考价值。
OOP第一次博客作业
前言
第一次作业
总的来说,本次作业的难度较小,主要是为了让同学们对java语言有一个基本的了解 ,像变量 , 数组, 循环 , 函数 ,字符串等基础语法。虽然一共有12道题,但是真正花费的时间并没有多久。
第二次作业
这一次作业的题量相比第一次作业的题量有所减少,第八题和第九题有一定的难度,但是认真思考一番还是可以完成的。在第二次作业中,题目也有了一定的要求,需要我们写方法来解题,为接下来的面对对象编程打下了基础。
第三次作业
这一次作业一共只有四道题,第一题和第二题比较简单,只需要构建一个简单的类。第三题和第四题相比之前所有的题有了一个相当大的跳跃。这两题都是要求写一个日期类,并且要求实现类的封装性。这两题的代码量也有了一个巨大的变化,都到达了两百行以上,对打字不熟练的同学也是一个巨大的考验。
设计与分析
在这里主要对第三次作业的第三道和第四道进行分析
定义日期类分析
定义日期类源码
import java.util.*;
public class Main
public static void main(String[] args)
Scanner sc = new Scanner(System.in);
int year = sc.nextInt();
int month = sc.nextInt();
int day = sc.nextInt();
Date myDate = new Date(year , month , day);
if(myDate.checkinputValidity(year , month , day) == false)
System.out.println("Date Format is Wrong");
return;
myDate.getNextDate();
class Date
private int year;
private int month;
private int day;
int [] m = new int[]0 , 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31;
public Date(int year , int month , int day)
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 % 400 == 0 || ((year % 2 == 0) && (year % 100 != 0));
public boolean checkinputValidity(int year , int month , int day)
if(isLeapYear(year))
m[2] = 29;
if(year >= 1900 && year <= 2000 && month >= 1 && month <= 12 && day >= 1 && day <= m[month])
return true;
else
return false;
public void getNextDate()
if(month == 12 && day == 31)
System.out.printf("Next day is:%d-%d-%d",year + 1 , 1 , 1);
else if(day == 31)
System.out.printf("Next day is:%d-%d-%d",year , month + 1, 1);
else if(month == 2)
if(isLeapYear(year))
if(day == 29)
System.out.printf("Next day is:%d-%d-%d",year, 3 , 1);
else
if(day == 28)
System.out.printf("Next day is:%d-%d-%d",year, 3 , 1);
else if(m[month] == day)
System.out.printf("Next day is:%d-%d-%d",year,month + 1, 1);
else
System.out.printf("Next day is:%d-%d-%d",year, month, day + 1);
定义日期类类图
题目思路
题目较简单,只需要按照题面中给出的类图写出相应的类就行,在Main函数中先判定数据是否合法,然后直接调用Date类的方法就可以解决。
难点
应该只有打字速度吧
主要知识点
- 类的封装性
- 类的基本应用
日期类设计分析
日期类设计源码
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;
int [] m = 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 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 % 400 == 0 || ((year % 4 == 0) && (year % 100 != 0));
public boolean checkInputValidity()
if(year <= 2020 && year >= 1820 && month <= 12 && month >= 1 && day <= m[month] && day >= 1)
return true;
else
return false;
public DateUtil getNextNDays(int n)
DateUtil res = new DateUtil(year , month , day);
for (int i = 0; i < n; i++)
if(isLeapYear(res.year))
m[2] = 29;
else
m[2] = 28;
res.day++;
if(res.day == m[res.month] + 1)
res.day = 1;
res.month++;
if(res.month == 13)
res.year++;
res.month = 1;
return res;
public DateUtil getPreviousNDays(int n)
DateUtil res = new DateUtil(this.year , this.month , this.day);
for (int i = 0; i < n; i++)
if(isLeapYear(res.year))
m[2] = 29;
else
m[2] = 28;
res.day--;
if(res.day == 0)
res.month--;
if(res.month == 0)
res.year--;
res.month = 12;
res.day = m[res.month];
return res;
public boolean compareDates(DateUtil date)
if(this.year > date.getYear())
return true;
else if(this.year == date.year && this.month > date.month)
return true;
else if(this.year == date.year && this.month == date.month && this.day > date.day)
return true;
return false;
public boolean equalTwoDates(DateUtil date)
return this.year == date.year && this.month == date.month && this.day == date.day;
public int getDaysofDates(DateUtil date)
int res = 0;
if(this.compareDates(date))
while(true)
if(isLeapYear(date.year))
m[2] = 29;
else
m[2] = 28;
date.day++;
if(date.day == m[date.month] + 1)
date.month++;
date.day = 1;
if(date.month == 13)
date.year++;
date.month = 1;
if(date.year == year && date.month == month && date.day == day)
break;
res++;
else
while(true)
if(isLeapYear(year))
m[2] = 29;
else
m[2] = 28;
day++;
if(day == m[month] + 1)
month++;
day = 1;
if(month == 13)
year++;
month = 1;
if(date.year == year && date.month == month && date.day == day)
break;
res++;
return res + 1;
public String showDate()
return this.year + "-" + this.month + "-" + this.day;
日期类分析类图
题目思路
本题是题三的升级版,对于程序的要求更高,但因为只需要写出类,难度也还能接受。基本思路就是按照题目中的要求实现给出来的八个类,Main函数已经给出,只需要考虑当前类就行。
难点
- 日期之间的计算
- 润年二月的特判
- 打字速度
主要知识点
- 类的基本应用
- 类的封装性
- 类之间关系的理解
- 日期间的计算
踩坑心得
浮点数不能直接用等于号
以第二次作业的第八题为例(判断三角形类型)
第一次提交的源码如下
import java.util.*;
public class Main
public static void main(String[] args)
Scanner sc = new Scanner(System.in);
double num[] = new double[3];
for(int i = 0; i < 3; i++)
num[i] = sc.nextDouble();
Arrays.sort(num,0,3);
double a = num[0];
double b = num[1];
double c = num[2];
if(a >= 1 && a <= 200 && b <= 200 && b >= 1 && c <= 200 && c >= 1)
if(a + b <= c)
System.out.print("NOT a triangle");
else
if(a == b && b == c)
System.out.print("Equilateral triangle");
else if(a == b && a * a + b * b == c * c)
System.out.print("Isosceles right-angled triangle");
else if(a == b)
System.out.print("Isosceles triangle");
else if(a * a + b * b == c * c)
System.out.print("Right-angled triangle");
else
System.out.print("General triangle");
else
System.out.print("Wrong Format");
第一次实验结果如下
解决方法
通过将浮点数之间等于号全部替换成小于一个非常小的数,我这里定义的是t为1e-6。
第二次提交源码如下
import java.util.*;
public class Main
public static void main(String[] args)
Scanner sc = new Scanner(System.in);
double num[] = new double[3];
for(int i = 0; i < 3; i++)
num[i] = sc.nextDouble();
Arrays.sort(num,0,3);
double a = num[0];
double b = num[1];
double c = num[2];
double t = 1e-6f;
if(a >= 1 && a <= 200 && b <= 200 && b >= 1 && c <= 200 && c >= 1)
if(a + b <= c)
System.out.print("Not a triangle");
else
if(Math.abs(a - b) < t && Math.abs(b - c) < t)
System.out.print("Equilateral triangle");
else if(Math.abs(a - b) < t && Math.abs(a * a + b * b - c * c) < t)
System.out.print("Isosceles right-angled triangle");
else if(Math.abs(a - b) < t || Math.abs(c - b) < t)
System.out.print("Isosceles triangle");
else if(Math.abs(a * a + b * b - c * c) < t)
System.out.print("Right-angled triangle");
else
System.out.print("General triangle");
else
System.out.print("Wrong Format");
第二次实验结果如下
字符串下标不能像数组一样直接访问,需要使用charAt(),也可以将字符串转为字符数组进行直接访问。
第一种访问方式
String str="2022 fight";
for(int i=0;i < str.length();i++)
System.out.println(str.charAt(i));
第二种访问方式
String str="2022 fight";
char[] s = str.toCharArray();
for(int i=0;i < str.length();i++)
System.out.println(s[i]);
错误的访问方式
String str="2022 fight";
for(int i=0;i < str.length();i++)
System.out.println(str[i]);
错误方式报错
字符串间不能之间用等于号来判断是否相等,应使用equals()。
正确写法
String a = "abc" , b = "abc";
if(a.equals(b))
System.out.println("Yes");
else
System.out.println("No");
错误写法
String a = "abc" , b = "abc";
if(a == b)
System.out.println("Yes");
else
System.out.println("No");
原理分析
Java中, ==相等判断符用于判断基本数据类型和引用数据类型。当判断基本数据类型时,判断的是数值,当判断引用数据类型时,判断变量是否指向同一引用对象。
使用 ==判断字符串时,判断的是两个字符串是否指向同一个对象。如果两个字符串指向同一个对象,那么它们就是相同的,使用 ==比较的结果也就是True。
如果两个字符串指向不同的对象,那么它们不相同,使用 ==比较的结果也就是False。
改进建议
第一次作业第五题元素去重可以用HashSet或StringBuilder类
HashSet用法核心思路
核心思路:利用HashSet的add()方法,如果元素存在,则返回false;只有不存在才返回true
HashSet写法
import java.util.Scanner;
import java.util.HashSet;
public class Main
public static void main(String[] args)
Scanner sc = new Scanner(System.in);
String op = sc.nextLine();
char[] c = op.toCharArray();
HashSet st = new HashSet();
for(int i = 0;i < c.length;i ++)
if(st.add(c[i]))//如果返回true则直接打印
System.out.printf("%c", c[i]);
StringBulider用法核心思路
核心思路:用循环遍历字符串中的单个字符,利用String类中的两个方法:
- indexOf(): 返回指定字符第一次出现的索引(下标)
- lastIndexOf(): 返回指定字符最后一次出现的索引(下标)
StringBulider类写法
import java.util.Scanner;
import java.util.HashSet;
public class Main
public static void main(String[] args)
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
StringBuilder sbd = new StringBuilder();
for (int i = 0; i < s.length(); i++)
char c = s.charAt(i);
if (s.indexOf(c) == s.lastIndexOf(c)) //第一次出现的下标跟最后一次相等,表示当前字符没有出现重复,直接添加进StringBuilder中
sbd.append(c);
else //出现重复
if (s.indexOf(c) == i) //如果重复出现的字符的位置等于当先字符的索引值,即表示当前字符为重复字符出现的第一次,将其加入StringBuilder中
sbd.append(c);
System.out.println(sbd.toString());
总结
收获与接下来的进一步学习
- 通过这三次作业,我的java语法基础有了明显的提高 。刚开始时从C语言转为java时的不适,到现在的逐步适应。
-
通过这三次作业,我个人进步最大的学习就是学习面对对象程序设计的思想(OOP),不再是C语言的面向过程,需要考虑的东西变得更多了。
-
此外,我个人对于面对对象的三大特性之一的封装有了一个基本的了解,另外两大特性继承和多态还需要在接下来的时间里抓紧学习。
-
个人的设计思想也有所欠缺,在面对一道实际问题时,经常需要花费较长一段时间才能理清题目里的基本逻辑。有时还会考虑不周,导致浪费大量的时间。接下来的时间里,我也会不断培养这方面的能力。
-
随着题目代码量的增加,我个人的打字速度也有所欠缺,经常出现想的比打的快的情况,在接下来的时间里,我也会着重这一方面的练习。同时也会尽快的熟悉IDEA的快捷键,增加编码速度。
个人建议
- PTA题目难度梯度可以稍微平滑一些,目前的题目集给人感觉还行, ~~希望以后也是这个难度~~。
- 对题目的描述应该更加清晰一些,不要出现一些模棱两可的题。
以上是关于OOP第一次博客作业的主要内容,如果未能解决你的问题,请参考以下文章