日曆(設計構造器與預設構造器)

瘦小的花捲發表於2020-11-06

日曆(預設構造器)

要求:
做一個日曆,功能和電腦、手機上的日曆一樣,能顯示每個月的天數,1至12月每個月的天數都能正確顯示(包括閏年2月29天,平年2月28天)。然後每個月的每一號顯示該天對應的星期數。

程式碼:

package com.softeem.lesson06.oop;
/**
 * 建立一個方法,獲取一個指定年份,月份當月的總天數
 * @author admini
 *
 */
public class MyCalendar {

        //判斷是否是閏年
		public boolean isLeapYear(int year){
		
				return (year % 4 == 0 && year % 100 != 0)|year % 400 == 0;
	
			
			
		}
		//判斷每個月的天數
	public int getDaysOfMonth(int y,int m) {
	switch(m) {
	case 4:
	case 6:
	case 9:
	case 11:
		return 30;
	case 2:
	    //是閏年返回29,不是則返回28
		return isLeapYear(y)?29:28;
		default:
			return 31;
	}
		
	}
	/**
	 * 計算從1900年1月份到引數的年份月份上一個月的總天數
	 * @param y
	 * @param m
	 * @return
	 */
	public int getTotalDaysFrom1900(int y,int m) {
		//區域性變數使用前必須先初始化
		int days = 0;;
		//計算整年的總天數1900~(y-1)
		for(int i = 1900;i < y;i++) {
		    //是閏年加366,否則加365
			days += isLeapYear(i)?366:365;//days = days + 366/365
		}
		//計算從1-(m-1)月的總天數
		for(int i = 1;i < m;i++) {
			days += getDaysOfMonth(y, i);//days = days + 28/29/30/31
		}
			
		
		return days;
	}
	
	/**
	 * 列印日曆
	 * @param args
	 */
	public void printCalendar(int y,int m) {
		
		//獲取列印日曆之前需要預留的空格數
		//通過1900年到(y-1)年的總天數除以7來判斷預留數(1900年1月1日正好對應星期一)
		int space = getTotalDaysFrom1900(y,m) % 7;
		//獲取目標月份的總天數
		int days = getDaysOfMonth(y,m);
		//用表格的方式呈現日曆,更符合實際,也更美觀
		System.out.println("===========SOFTEEM【"+y+"]年【"+m+"】月================");
		//天數的最上一排顯示星期數
		System.out.println("一\t二\t三\t四\t五\t六\t日");
		System.out.println("===================================================");
		int count = 0;
		//列印日期,用“\t"留出該月份需要預留的空格數
		for(int i = 0;i < space;i++) {
			System.out.print("\t");
			count++;
		}
		//列印日期
		for(int i = 1;i <=days; i++) {
			count++;
			System.out.print(i +"\t");
			//是否達到周天,達到周天則換一行
			if(count == 7){
				System.out.println();
				//計數器歸零,再在下一輪重新判斷是否達到周天
				count = 0;
			}
		}
		
	}
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
        //定義新物件
		MyCalendar mc = new MyCalendar();
		//判斷2019是否是閏年
		boolean b = mc.isLeapYear(2019);
		//是閏年列印“是”,否則列印“不是"
		System.out.println(b?"shi":"bushi");
		//定義2020年2月的天數
		int days = mc.getDaysOfMonth(2020, 2);
		//列印得到的結果
		System.out.println(days);
	    //從1900年1月1日到2020年11月前的總天數
		days = mc.getTotalDaysFrom1900(2020,11);
		System.out.println(days);
		//列印2020年11月的日曆,是日曆編寫的總程式,可以通過設定引數得到我們想要月份的日曆
		mc.printCalendar(2020,11);
	

 }
}

執行結果:

在這裡插入圖片描述

日曆(設計構造器)

與預設的日曆的程式基本設計一致,只是這裡通過自己設計構造器的引數來達到降低編碼的複雜度的目的。通過構造器賦值給全域性變數不用再設定多個引數和區域性變數。

程式碼:

package com.softeem.lesson07.example;

public class MyCalendar {

	int year;
	int month;
	//定義構造器的引數,通過構造器直接將引數的數值直接賦值給全域性變數
	public MyCalendar(int _year,int _month) {
		year = _year;
		month = _month;
	}
	
	/**
	 * 判斷指定的年份是否是閏年
	 * 
	 * @param year
	 * @return
	 */
	public boolean isLeapYear(int year) {
		return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
	}

	/**
	 * 根據提供的年份月份,返回當前月的總天數
	 * 
	 * @param y
	 * @param m
	 * @return
	 */
	public int getDaysOfMonth(int y, int m) {
		switch (m) {
		case 4:
		case 6:
		case 9:
		case 11:
			return 30;
		case 2:
			return isLeapYear(y) ? 29 : 28;
		default:
			return 31;
		}
	}

	/**
	 * 計算從1900年1月份到目標的年份月份上一個月的總天
	 * 
	 * @param y
	 * @param m
	 * @return
	 */
	 //不用定義該方法內的引數,方法內直接引入全域性變數”month”和“year”
	public int getTotalDaysFrom1900() {
		// 區域性變數使用前必須先初始化
		int days = 0;
		// 計算整年的總天數1900~(y-1)
		for (int i = 1900; i < year; i++) {
			days += isLeapYear(i) ? 366 : 365; // days = days + 366/365
		}
		// 計算從1-(m-1)月的總天數 1 2 3 4 5 .. 10
		for (int i = 1; i < month; i++) {
			days += getDaysOfMonth(year, i);  // days = days + 28/29/30/31
		}
		return days;
	}

	/**
	 * 列印日曆
	 * 
	 * @param y
	 * @param m
	 */
	public void printCalendar() {

		// 獲取列印日曆之前需要預留的空格數
		int space = getTotalDaysFrom1900() % 7;

		// 獲取目標年份月份的總天數
		int days = getDaysOfMonth(year, month);

		System.out.println("============SOFTEEM萬年曆 【" + year + "】年【" + month + "】月=============");
		System.out.println("一\t二\t三\t四\t五\t六\t日");
		System.out.println("====================================================");
		
		int count = 0;
		//列印空格
		for (int i = 0; i < space; i++) {
			System.out.print("\t");
			count++;
		}
		//列印日期
		for (int i = 1; i <= days; i++) {
			count++;
			System.out.print(i + "\t");
			//是否達到周天
			if(count == 7) {
				System.out.println();
				//計數器歸零
				count = 0;
			}
		}
		
	}

	public static void main(String[] args) {
	   //只通過定義構造器的引數來實現功能,幾乎不需要定義其他引數
		MyCalendar mc = new MyCalendar(2019,11);
		mc.printCalendar();
	}
}

執行結果:

在這裡插入圖片描述

總結

設計構造器的日曆和預設構造器的日曆實現功能一樣,程式碼長度相近,從日曆這個例子看不出兩種方法的優劣之分。每種方法都有自己獨特的應用,我們能做的不是區分方法的好壞,從而一味推崇一種或者一類方法。而是面對不同的情況,不同的要求,用更方便的方法來實現要求的功能。沒有強調好壞,只是我們通過該方法實現的功能bug更少,更清楚理解整體結構。
我目前能力有限,對該方面的認識可能比價淺顯,只有不斷的學習,才能掌握理解更多的方法,理解透徹後才能更加靈活的運用在實踐中。

相關文章