目录
前言
通过实现一个日期和时间类来加深对类和对象的印象,理解理解什么是面向对象。
一、基本要求
1. 日期类具有年月日三个属性(1000年到3000年之间),时间类具有时分秒三个属性
2. 日期类具有前一天、后一天以及间隔天数、输出字符串的方法。时间类具有后一秒输出字符串的方法。
3. 将日期类和时间类结合起来,实现浅拷贝和深拷贝的方法。
二、实现日期类
1.思路
很明显年月日使用实例属性(private的)。对于构造方法,我们还需要对参数进行检测,其中年分必须在1000到3000中,月份是在1-12月,具体到天的话比较麻烦,我们需要根据年份和月份来对天数进行判断,因此需要用另外的方法进行检查。具体的就是需要根据闰年、2月、大小月来分别进行判断。
下一天的方法需要让天数+1,同时我们还要考虑如果该天是末尾的话,需要让月份+1,天数为1。该月是末尾的话,需要让年份+1,月份为1。并且还需要判断该 月的最后一天是多少号。前一天的方法同理。
输出字符串只需要使用String.format("%04d-%02d-%02d", year, month, day)就行了。
判断两个日期类之间的天数,只需要让前一个日期一直调用下一天的方法,直到两个日期相等。为此,我们需要判断两个天数是否相等以及两个天数哪个在前,哪个在后,并且根据该情况进行输出。
2. 重要部分实现
2.1 检查天数是否正确
根据是否闰年以及月份来进行判断。
private static boolean checkday(int year, int month, int day) {
if (isrunnian(year)) {
if (month == 2) {
return day >= 1 && day <= 29;
} else if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
return day >= 1 && day <= 31;
} else {
return day >= 1 && day <= 30;
}
} else {
if (month == 2) {
return day >= 1 && day <= 28;
} else if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
return day >= 1 && day <= 31;
} else {
return day >= 1 && day <= 30;
}
}
}
2.2 下一天
根据具体的情况来看是否需要进行进位。其中关于边界的方法在2.3给出。
public void nextday() {
day++;
if (day <= monthbound(year, month, year)) {
return;
}
month++;
day = 1;
if (month <= 12) {
return;
}
year++;
month = 1;
}
2.3 根据月份输出天数的边界
private static int monthbound(int year, int month, int day) {
if (isrunnian(year)) {
if (month == 2) {
return 29;
} else if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
return 31;
} else {
return 30;
}
} else {
if (month == 2) {
return 28;
} else if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
return 31;
} else {
return 30;
}
}
}
2.4 输出两个日期的间隔天数
其中func2(d1,d2)的作用是d1,d2的一个比较,如果d1>d2就会输出正数。其中comp(tmp,d2)是用来比较两个日期是否相等的。因为使用了下一天方法,会对原始的天数造成改变,为了避免这种情况的发生,我们用另外一个日期对象来代替天数小的那一天。
public static int datesub(Date d1, Date d2) {
boolean b = true;
if (func2(d1, d2) > 0) {
Date d = d1;
d1 = d2;
d2 = d;
b = false;
}
int count = 0;
Date tmp = new Date(d1);
while (!comp(tmp, d2)) {
tmp.nextday();
count++;
}
return b ? count : -count;
}
三、实现时间类
对于时间类就和日期类很类似了,并且更加简单。主要方法如下
public boolean nextSecond(){
second++;
if(second<60){
return false;
}
minute++;
second=0;
if(minute<60){
return false;
}
hour++;
minute=0;
if(hour<24){
return false;
}
hour=0;
return true;
}
四、时间类和日期类的使用
为了使用时间类以及日期类,在原始的时间类和日期类上添加了一些构造方法和get方法方便我们读取信息。具体细节不再赘述。
我们在日期时间类中加入了一个下一秒的方法,只要要调用时间类中的下一秒的方法,然后再判断是否需要进入下一天,这就是为什么我们在时间类中的下一秒的方法使用boolean类型的返回值。
public void nextSecond(){
if(time.nextSecond()){
date.nextday();
}
}
1.浅拷贝与深拷贝
· 我们为了使用这个对象而不对这个对象造成影响。像直接进行对象的赋值肯定是不行的,因为这样相当于给对象换了个名字,本质上还是这个对象。
浅拷贝:我们表面上重新new了一个对象,但是内部的对象还是指向之前的对象的内部的对象。也就是说,我们拷贝了但是完全没有拷贝。
public DateTime sCopy(){
DateTime dateTime = new DateTime();
dateTime.date=this.date;
dateTime.time=this.time;
return dateTime;
}
深拷贝:就是真正的拷贝,完全不因为之前的对象的变化而变化。
public DateTime dCopy(){
DateTime dateTime = new DateTime();
dateTime.date=new Date(this.date);
dateTime.time=new Time(this.time);
return dateTime;
}
我们并不是要学习浅拷贝和深拷贝,而是通过这两个方法来加深这两种思想。
总结
通过这样的小练习,来加深我们对于Java中类和对象的理解。熟悉Java的语法,熟悉IDEA的操作方法。然后多多练习。