Java 類別方法 - 翻轉工作室
文章推薦指數: 80 %
某一類別程式呼叫其他類別方法時,兩類別實體(class 檔案)必須儲存於同一目錄下;宣告與引用語法 ... 吾人利用 dateTool.java 檔案規劃 Date 與 dateTool 兩類別。
Java
程式設計(二)
:第八章方法與方法庫產生
上一頁
下一頁
8-3類別方法
內容:
8-3-1類別方法宣告與引用
8-3-2範例研討:製作日期計算工具
8-3-3自我挑戰:預估葡萄成長採收日期
8-3-1類別方法宣告與引用
類別可不經由new產生物件,類別內的方法成員可被直接引用,則稱為類別方法;宣告時只要在方法前面加入static關鍵字即可。
某一類別程式呼叫其他類別方法時,兩類別實體(class檔案)必須儲存於同一目錄下;宣告與引用語法如下:
宣告語法:
範例:
classclass_name{
staticreturn_typemethod_name(){
method_body;
}
…..
}
//
引用類別方法
class_name.method_name();
classmathFun{
staticint Add(intx,inty){
…..
}
…..
}
//
引用類別方法
mathFun.Add();
如同一般類別的宣告語法,可以將類別宣告成私有性(privateclass)或公有性(publicclass),也可將方法成員宣告成私有性(privatestatic)或公有性(publicstatic)。
8-3-2範例研討:製作日期計算工具
(A)程式功能:Ex8_2.java、dateTool.java
許多系統都可能遇到日期計算問題,造成程式設計師困擾。
因此,軟體公司裡期望建立相關日期計算工具,爾後所有工程師直接引用即可。
該公司對日期計算規劃有下列工具:
(1)dataAfter():指定某一日期(年、月、日),再給予幾個天數之後的日期,應該是何日期。
呼叫方法時,給予指定某一特定日期,與之後的天數。
執行方法後回覆相對日期的年、月、日之日期。
(2)
dataBefore():指定某一日期,再給予該日期之前的天數,則計算出相對應的日期。
呼叫此方法時,給予指定特定日期(年、月、日),與之前的天數。
執行後回覆相對應的年、月、日。
(3)
dataInterval():指定兩個日期(年、月、日),則計算出兩日期之間的天數。
呼叫此方法時,給予兩個日期,執行後回覆之間的天數。
期望操作及測試結果如下:
G:\Examples\chap11\EX8_2>javaEx8_2
設定目前日期(年/月/日)
=>2004/3/12
目前是
2004
年
3
月
12
日
請輸入之前的天數
(日)
=>100
之前是
2003
年
12
月
2
日
目前是
2003
年
12
月
2
日
請輸入之後的天數
(日)
=>100
之後是
2004
年
3
月
12
日
目前是
2004
年
3
月
12
日
後面的第二個日期
(年/月/日)
=>2005/4/6
兩點日期相差
390
天
(B)製作技巧研討:
研發計算日前之前,需制定一個通用型的日期物件(Date),應包含有:年(year)、月(month)與(day)等三個變數成員。
另外,每個月的天數並不相同,需要利用一個陣列(Months[])來表示每個月最高天數。
還有一個重點,如欲利用數值的加減運算子,製作日期計算工具是非常困難的,採用計數累加方法,可能較為容易達成。
製作技巧說明如下:
(1)
之後天數的日期(dateAfter()):輸入第一點日期,與該日前之後的天數(value),計算並輸出第二點日期。
製作方法是以第一點日期作基礎,由『日』(day)開始累計加一,當他超過該月最高天數(Months[])後,『月』(month)則累計加一,又如果『月』超過12時,則『年』累計加一;如此一個循環則輸入天數(value)減一,一直到該數值為0。
最後得到的日期即是第二點日期。
(2)
之前天數的日期(dateBefore()):輸入第一點日期,與該日前之前的天數(value),計算並輸出第二點日期。
方法是以第一點日期作基礎,由『日』開始累計減一,當它等於零,則『月』數累計減一,並將『日』設定為該月最高日數;如果『月』減一後等於0,則『年』減一,亦將『月』設定為12;如此一個循環則輸入天數(value)減一,依此類推,一直到輸入數值為0。
(3)
兩日期之間天數(dateInterval()):與dataAfter()相似,由第一個日期開始累計,每次value數值累計加一。
一直到第一個日期與第二個日期相同,最後value的數值即是兩日期之間的天數。
日期計算工具大多僅簡單的輸入與輸出運算,極少牽涉到共享資料的處理,製作成靜態類別方法即可。
因此我們將宣告日期物件(Date)與日期工具(dateTool())兩類別規劃於dateTool.java檔案內,編譯後(javac)將產生Data.class與dateTool.class兩類別檔案,其中dateTool.class包含三個類別方法。
另一方面,也製作了一個主程式(Ex8_2.java)測試這三個類別方法是否正確。
(C)程式範例:dateTool.java
吾人利用dateTool.java檔案規劃Date與dateTool兩類別。
Date類別可宣告產生儲存日期的物件(年、月、日)。
dateTool類別包含4個靜態方法成員與1個變數成員,分別說明如下:(如圖8-4所示)
(a)
Date
類別:規劃日期物件的儲存格式,包含年(year)、月(month)與日(day)等變數成員。
(b)
Month[]
類別變數:儲存每年12個月,每月的日數(12個元素)。
(c)
getDate()
方法:將日期字串(年/月/日)轉換成日期物件格式(年、月、日)。
(d)
dateBefore()
方法:計算某一指定日期,相對應之前的天數量,應該是何日前(年、月、日)。
(e)
dateAfere()
方法:計算某一指定日期,相對應之後的天數量,應該是何日前(年、月、日)。
(f)
dateInterval():計算兩日期之間的天數量。
圖8-4Date與dateTool類別的功能
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//dateTool.java
importjava.util.*;
/*
日期類別,
產生日期物件的格式
*/
classDate{
intyear;
intmonth;
intday;
}
/*
時間工具類別,
包含
4
個方法
(計算器)
*/
classdateTool{
/*
每月的天數
*/
staticintMonths[]={31,28,31,30,31,30,
31,31,30,31,30,31};
/*
轉換字串成為日期物件格式
*/
staticDategetDate(Stringdate_S){
Datedate=newDate();
Scanners=newScanner(date_S).useDelimiter(“/”);
date.year=s.nextInt();
date.month=s.nextInt();
date.day=s.nextInt();
returndate;
}
/*
之後天數的日期計算器
*/
staticDatedateAfter(Datenow,intvalue){
intk;
while(value>0){
now.day=now.day+1;
if(now.day>Months[now.month-1]){
now.day=1;
now.month=now.month+1;
if(now.month>12){
now.month=1;
now.year=now.year+1;
}
}
value=value–1;
}
returnnow;
}
/*
之前天數的日期計算器
*/
staticDatedateBefore(Datenow,intvalue){
while(value>0){
now.day=now.day–1;
if(now.day<1){
now.month=now.month–1;
if(now.month<1){
now.month=12;
now.year=now.year–1;
}
now.day=Months[now.month-1];
}
value=value–1;
}
returnnow;
}
/*
計算兩個日期之間天數的計算器
*/
staticintdateInterval(Datestart,Dateend){
intnumber=0;
while(!((end.year==start.year)&&
(end.month==start.month)&&
(end.day==start.day))){
start.day=start.day+1;
if(start.day>Months[start.month-1]){
start.month=start.month+1;
start.day=1;
if(start.month>12){
start.year=start.year+1;
start.month=1;
}
}
number=number+1;
}
returnnumber;
}
}
程式重點說明:
(1)
第6~10
行:『classDate{…}』。
宣告日期類別。
產生日期物件的格式。
(2)第13~84
行:『classdateTool{…}』。
宣告日期工具類別。
(3)
第15~16
行:『staticintMonths[]={…}』。
每月最高日期陣列。
(D)程式範例:Ex8_2.java
完成時間計算工具製作之後,吾人編寫Ex8_2.java程式來驗證工具是否運作正常。
又dateTool工具內的方法皆被宣告成靜態方法,可不經由產生物件,即可直接引用執行,如圖8-4所示。
圖8-5Date物件產生與dateTool的類別方法
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//Ex8_2.java
/*dateTool.class,Date.class
需儲存於相同目錄下
*/
importjava.io.*;
importjava.util.*;
publicclassEx8_2{
publicstaticvoidmain(Stringargs[])throws
IOException{
BufferedReaderkeyin=newBufferedReader(new
InputStreamReader(System.in));
Datenow=newDate(); //
儲存當時日期
Datedate_T=newDate(); //
日期暫存變數
Datedate_B=newDate(); //
日期暫存變數
Stringdate_S; //
讀入日期字串
intvalue;
/*
設定目前日期
*/
System.out.printf("設定目前日期(年/月/日)
=>");
date_S=keyin.readLine();
now=dateTool.getDate(date_S);
/*
測試某日前之前天數的日期
*/
System.out.printf("\n目前是
%d
年
%d
月
%d
日\n",
now.year,now.month,
now.day);
System.out.printf("請輸入之前的天數
(日)
=>");
value=Integer.parseInt(keyin.readLine());
date_B=dateTool.dateBefore(now,value);
System.out.printf("之前是
%d
年
%d
月
%d
日\n",
date_B.year,date_B.month,
date_B.day);
/*
測試某日前之後天數的日期
*/
System.out.printf("\n目前是
%d
年
%d
月
%d
日\n",
now.year,now.month,
now.day);
System.out.printf("請輸入之後的天數
(日)
=>");
value=Integer.parseInt(keyin.readLine());
date_B=dateTool.dateAfter(now,value);
System.out.printf("之後是
%d
年
%d
月
%d
日\n",
date_B.year,date_B.month,
date_B.day);
/*
測試計算兩日前之間的天數
*/
System.out.printf("\n目前是
%d
年
%d
月
%d
日\n",
now.year,now.month,
now.day);
System.out.printf("後面的第二個日期
(年/月/日)
=>");
date_S=keyin.readLine();
date_T=dateTool.getDate(date_S);
value=dateTool.dateInterval(now,date_T);
System.out.printf("兩點日期相差
%d
天\n",
value);
}
}
8-3-3自我挑戰:預估葡萄成長採收日期
(A)程式功能:PM8_2.java
南投縣信義鄉種植葡萄的生長情況大致上是這樣,葡萄收成後農夫會將所有綠葉剪光,此時讓葡萄樹休養,等到希望葡萄開始成長時,再將成長激素擦拭於藤枝的某些地方,新芽將由擦拭藥水的地方開始成長。
由擦拭成長激素日開始計算,其他工作週期如下:
(a)
7
天後會發新芽。
(b)
30
天後會長出花苞;
(c)之後每隔10
天必須噴農藥一次,連續5
次;
(d)同時,每隔20
天必須下普通有機肥料一次,連續3
次;離最後加肥
40
天,必須加高蛋白有機肥料一次。
(e)最後噴農藥後,隔20
天需葡萄果實需套裝紙袋。
(f)從擦拭成長激素到收割葡萄,大約需要200
天。
農民除了需要依照整個成長過程施肥與噴灑農藥外,也需時常觀察葡萄藤與樹葉的變化,是否『落菌』感染,如發現有被感染必須立即再噴灑消除藥水,絕對不可延遲到隔日,否則就前功盡棄。
種植葡萄並不容易,整個成長過程中有稍微瑕疵的話,輕者品質不良,收成當然不好;重者整片葡萄園全部作廢,血本無歸。
當然農民也希望辛苦可以得到代價,葡萄可以賣到好價錢。
但葡萄要賣到好價錢,除了需要細心照顧外,也要仰賴上天不要有天然災害(雨水過量、寒流、下冰砲、颱風...等),更重要的是採收日期是否剛好合時,譬如:採收當時其他水果產量不豐,或葡萄成長時期天然災害少果實賣像好,就更容易賣到好價錢。
由此可見,選定何時可以採收葡萄是很重要的。
掌握了這些因素之外,信義鄉梁姓與黃姓兩位年輕農民,便組織了一個葡萄產銷班,期望班友之間採收期錯開。
因此,建立一個教導同班農民種植葡萄的教學網站,農民只要輸入預期何時採收葡萄,系統會告知何時擦拭成長激素的,也會一序列告知農民需要從事哪些工作的日期,也隨時提醒農民應該預備哪些工作。
所有班友依照此系統種植葡萄,如成長過程與系統不符,則可能種植過程有瑕疵,或系統評估不正確。
因此該產銷班必須定期開會,農民將種植心得提出意見,再來修飾系統。
請您幫他們製作一個雛型系統,期望操作介面如下:(數據並非確實,僅作教學參考)
G:\Examples\chap11\PM8_2>javaPM8_2
==
信義鄉葡萄第
#
產銷班
種植施工預估系統
==
=>本系統評估成長及種植過程僅供農友參考
<=
=>系統有不妥或有新種植技術請與班長聯繫
<=
請輸入預定採收日期
(國曆
年/月/日)
=>2008/9/15
預計採收日期
2008
年
9
月
15
日種植工程序列如下:
預估自擦拭成長激素後
200
天可採收
擦拭日期是
2008
年
2
月
27
日
發芽日期是
2008
年
3
月
6
日
開花日期是
2008
年
4
月
5
日
==
開花後噴灑農藥日期
==
第
1
次是
2008
年
4
月
15
日
第
2
次是
2008
年
4
月
30
日
第
3
次是
2008
年
5
月
15
日
第
4
次是
2008
年
6
月
4
日
第
5
次是
2008
年
6
月
24
日
==
發芽後施放有機肥料日期
==
第
1
次是
2008
年
4
月
10
日
第
2
次是
2008
年
4
月
30
日
第
3
次是
2008
年
5
月
20
日
最後一次是高蛋白有機肥料,
請到班長處索取配方
套裝紙袋日期是
2008
年
5
月
25
日
==
列印完畢,
歡迎再度使用
==
(B)製作技巧提示:
引用Ex8_2範例的日期工具(dateTool),製作本系統就非常簡單了,只要將dataTool.java檔案複製到目前目錄下,再重新編譯即可。
除了日期工具外,吾人以虛擬碼提示部份程式要點,如下:
/*
dateTool.class,Date.class
需儲存於相同目錄下
*/
/*
預估相關成長與施工週期
*/
finalinttotalDays=200; //
所需成長時間
(天)
finalintbornLeaf=7; //
發芽時間
finalintbornFlower=30; //
開出花苞時間
finalintdust[]={10,15,15,20,20}; //
花苞後噴灑農藥週期
finalintorganic[]={5,20,20}; //
發芽後有機肥料週期
finalintbagging=50; //
開出發苞後需套裝紙袋天數
/*
宣告所需物件與變數
*/
DatecropDate=newDate(); //
收成日期
DatestartDate=newDate(); //
擦拭成長激素日期
DateleafDate=newDate(); //
發芽日期
DatebornDate=newDate(); //
開出花苞日期
DatetempDate=newDate(); //
日期暫存器
Stringdate_S; //
讀入日期字串
int
value;
………
System.out.printf("請輸入預定採收日期
(國曆
年/月/日)
=>");
date_S=keyin.readLine();
cropDate=dateTool.getDate(date_S); //
類別方法引用
列印預計採收日期;
/*
計算擦拭成長激素日期
*/
startDate=dateTool.dateBefore(cropDate,totalDays); //
類別方法引用
列印擦拭成長激素日期;
/*
計算發芽日期
*/
leafDate=dateTool.dateAfter(startDate,bornLeaf); //
類別方法引用
列印發芽日期;
/*
計算開花日期
*/
bornDate=dateTool.dateAfter(startDate,bornFlower); //
類別方法引用
列印開花日期;
/*
計算噴灑農藥日期
*/
tempDate.year=bornDate.year;
tempDate.month=bornDate.month;
tempDate.day=bornDate.day;
for(inti=0;i