方法
本章重點 了解方法 呼叫方法 引數與參數 單一引數傳值呼叫 兩個引數傳值呼叫 具有回傳值方法呼叫 set與get 多載方法(Overloading) 建立private私有成員與public公有成員 建構子(Constructor) 建構子多載 建構子呼叫建構子,在建構子中使用this( ) 私有建構子被建立 再談this
了解方法 在使用方法之前,必須要先瞭解方法對Java程式所產生的影響性。最簡單的方法定義為「呼叫」,透過呼叫的方式,可讓程式的執行流程直接跳到被呼叫的物件執行其內容。
了解方法 在Java程式碼中第一個方法被呼叫的是從main( )開始執行,從上圖中不難看出使用呼叫的整體程式執行順序,一般程式皆為從上而下執行,但在具有呼叫的方法中,程式執行是先從主類別開始執行,如同上圖的步驟1。 一旦執行到須要開始呼叫方法時,就會暫時停止程式繼續往下執行,此時程式將會直接跳至定義類別中找出相同名稱的被呼叫的方法名稱,如同上圖的步驟2。 當被呼叫的方法處理完成後,程式又會直接跳至主類別來確認是否還有其他的方法須要呼叫,如同上圖的步驟3。
呼叫方法 當一個方法被呼叫執行時,可能會下列三種情況會發生: 會有傳回值(return a value) 例外處理,本部份將留到第12章再詳細討論 不管是以上的那一種,皆會直接跳至被呼叫的方法中執行其程式內容。
範例檔: Ch7_1.java class Date { int day, month, year; int getDay( ) System.out.println("這是getDay的方法"); return day; } void printDate( ) System.out.println("這是printDate的方法"); System.out.println("日期: " + month + "/" + day + "/" + year);
範例檔: Ch7_1.java class Ch7_1 { public static void main(String args[ ]) System.out.println("這是從主類別開始執行"); Date today = new Date( ); today.day = 10; today.month = 3; today.year = 2005; System.out.println("日期: " + today.getDay( )); System.out.println("日期傳送中... "); today.printDate( ); }
輸出結果
引數與參數 類別還可以利用引數傳遞的方式來得到結果。所謂的引數與參數分別定義如下: 引數:在主類別中所要傳遞的資料值 參數:在定義類別中的方法名稱括號內的變數名稱
引數與參數 有關於引數與參數的相互關係,請看下面的比較圖:
引數與參數 從這個比較圖中可看出具有引數與參數的類別架構與先前所學的似乎差不多,但是可看出不同之處在於箭頭所指之處有差異,即是分別有引數與參數在括號內。 在上圖中可明顯看出引數與參數的所在位置,而且這兩者必須是要對應,亦即如果有兩個引數,相對地,參數也有兩個來對應。
單一傳值呼叫引數 詳細的架構如下
單一傳值呼叫引數 假設現在定義類別為BankAccount的物件類別名稱,可藉由下列四個步驟來得到「餘額balance」及「利率rate」的輸出結果: Step1: 先做資料成員變數宣告 宣告型式如下: double balance; double rate; Step2: 呼叫方法名稱設定 通常我們習慣使用「set」這個字加上變數名稱來代表呼叫方法名稱,例如,餘額的變數名稱為「balance」,故呼叫方法名稱使用「setBalance」代表,如有其他呼叫方法名稱須設定,依此類推。 Step3: 加入參數 在呼叫方法名稱後的括號內加入具有資料型態的參數宣告,此參數必須與變數名稱的資料型態相同,如double。型式如下: void setBalance(double amount) Step4: 將參數指定給資料成員變數使用 此目的是參數自主類別中得到的資料傳遞值指定給資料成員變數使用,來做為輸出結果,型式如下: balance = amount; System.out.println("此帳號餘額為 " + balance);
單一傳值呼叫引數 最後在定義類別中可得到完整的程式碼如下 class BankAccount { double balance; double rate; void setBalance(double amount) balance = amount; System.out.println("此帳號餘額為 " + balance); } void setRate(double r) rate = r; System.out.println("此帳號利率為 " + rate);
單一傳值呼叫引數 在主類別的設計中,就顯得簡單多了,有兩個步驟: Step1: 建立新物件 這是天經地義的道理,不管是否具有引數類別與否,皆一定要先使用new建立新物件,根據此範例,型式如下: BankAccount account = new BankAccount( ); Step2: 引數傳遞值 建立好新物件後,則設定引數值傳遞給方法名稱使用,引數值必須與參數對應,故置放在括號內,型式如下: account.setBalance(1000); account.setRate(0.25);
兩個傳值呼叫引數 其實兩個或多個傳值呼叫引數的作法與單一傳值呼叫大致相同,有下列幾點改變須注意的地方: 方法名稱只有一個且給每個資料成員共用,例如: void setAccountInfo(double amount, double r) 在這裡使用setAccountInfo的方法名稱 括號內的引數與參數變不管為兩個或多個,引數與參數的數目必須要相同且資料型態須相同,例如,在方法名稱有兩個參數,故新物件內的引數必須要有兩個且對應,型式如下: account.setAccountInfo(1000, 0.25);
兩個傳值呼叫引數 要是將上題改為account.setAccountInfo(0.25, 1000)的話,那可會鬧出天下笑話,因為引數與參數必須是對應且數目一致,對調之後則變成利率將高達1000,豈不成超高利率了?
範例檔: Ch7_3.java class BankAccount { double balance; double rate; void setAccountInfo(double amount, double r) balance = amount; rate = r; System.out.println("此帳號餘額為 " + balance); System.out.println("此帳號利率為 " + rate); } class Ch7_3 public static void main(String args[]) BankAccount account = new BankAccount(); account.setAccountInfo(1000, 0.25);
輸出結果
具有回傳值方法呼叫 當您瞭解了引數與參數的方法應用後,也許您會問有了帳戶餘額及存款利率,那要如何求出利息所得呢?這時候就可使用「return」得到結果。 有關於return的內容敘述如下: 所謂return即是回傳值的運算,例如,加、減、乘、除。 所以在return後所接的型式一定是「運算式」,型式如下: return balance*rate; 沒有呼叫方法,亦即沒有void的呼叫字眼出現,通常使用具有整數資料型態或浮點數資料型態來回傳值,型式如下: double interestEarned( )
具有回傳值方法呼叫 具有回傳值方法呼叫的架構
定義類別部份 以BankAccount為物件類別名稱,由下列三個步驟來得到「利息所得」的輸出結果 Step1: 先做資料成員變數宣告 宣告型式如下: double balance; double rate; 此步驟與先前所提到的範例宣告相同,但下一個步驟就明顯不同。 Step2: 回傳值方法名稱宣告 可設定一方法名稱做為回傳使用,本範例是要求得利息所得, 故方法名稱為interestEarned,且具有浮點數資料型態,型式如下: double interestEarned( ) Step3: 求得運算式 眾所週知,利息所得的公式為本金與利率的相乘,然後使用return回傳,型式如下: return balance*rate;
在主類別部份 步驟如下: Step1: 建立新物件並指定資料值 此步驟也是與先前所提到的範例方式相同,故很快得到如下型式: BankAccount account1=new BankAccount( ); account1.balance=1000; account1.rate=0.25; Step2: 輸出回傳資料值 因為在步驟1建立了新物件為account1,故可將回傳值給該物件使用,將得到輸出結果程式碼如下: System.out.println("利息所得 = "+ account1.interestEarned( ));
輸出結果
set與get set: 加上資料成員變數名稱來代表呼叫方法名稱,例如setBalance。 get: 加上資料成員變數名稱來代表傳回值方法名稱,例如getBalance。 也許您會問為什麼要使用這個set與get呢?其實也不是一定要使用,隨人習慣而定,使用set與get的好處應該只有一個,那就是給程式設計者一個參考依據,只要見到set在前,則想到與呼叫方法有關,然而get在前,就與return傳回值有關。
範例檔: Ch7_5.java class BankAccount { double balance; double rate; double getBalance( ) return balance; } double getRate( ) return rate; void setAccountInfo(double amount, double r) balance = amount; rate = r; System.out.println("目前餘額: " + balance); System.out.println("利率: " + rate); System.out.println("利息所得 = " + (balance*rate));
範例檔: Ch7_5.java class Ch7_5 { public static void main(String args[ ]) BankAccount account = new BankAccount( ); account.setAccountInfo(1000, 0.25); double myBalance = account.getBalance( ); double myRate = account.getRate( ); }
多載方法(Overloading) 在前面幾個類別中,您可能有發現在每一個範例中皆有兩個不同方法名稱,例如setBalance、setRate。試想,要是一個程式中有數個方法名稱,是否有可能記錯名稱造成資料存取錯誤?答案是有可能的。為了解決此類問題可能地發生,「多載」便是解決上述的方法最佳選擇。
多載方法(Overloading) 多載有下列三個特點: 1.共同使用一個呼叫方法名稱,例如,將原先setBalance、setRate等方法名稱改為setAccount套到每個方法名稱,這樣一來,就不用記多個不同的名稱,只要記得一個方法名稱即可
多載方法(Overloading) 2. 在多載方法中,參數的資料型態及數目不可相同。是什麼意思呢?如果第一個方法名稱內的參數為整數資料型態,那第二個方法名稱內的參數就不能為整數資料型態。
多載方法(Overloading) 3. 使用多載方法宣告排列順序如何皆不影響資料值傳遞,因為每一個方法宣告的資料型態不同,所以在主類別中的引數會自動根據相同型態來傳遞資料值,例如下圖之排列:
多載方法(Overloading) 如果將主類別的setAccount( 1000, 0.25)誤寫成setAccount(0.25, 1000),程式也無法順利執行,因為在定義類別中的多載方法的第一個參數是為balance的整數資料型態,所以與setAccount(0.25, 1000) 資料型態不符。
建立private私有成員與public公有成員
建立private私有成員與public公有成員
建立private私有成員與public公有成員 public void setAccount(int amount) public void setAccount(double r) 當然,public公有成員是公開可供使用,故可省略掉public不寫。
範例檔: Ch7_6.java class BankAccount { private int balance; private double rate; public void setAccount(int amount) balance = amount; System.out.println("此帳號餘額為 " + balance); } public void setAccount(double r) rate = r; System.out.println("此帳號利率為 " + rate); public void setAccount(int amount, double r) System.out.println("帳號餘額為 " + balance + ", 利率為 " + rate); void show( ) System.out.println("利息所得= " + balance*rate );
範例檔: Ch7_6.java class Ch7_6 { public static void main(String args [ ]) BankAccount account = new BankAccount( ); account.setAccount(1000, 0.25); account.setAccount(1000); account.setAccount(0.25); account.show( ); }
輸出結果:
建構子(constructor) 現在將為您介紹另一種方法,可以不須要事先建立物件方法名稱,一樣能順利執行運算,那就是「建構子(constructor)」。 首先讓我們對建構子下一個簡單定義為: 建構子只要定義類別產生物件時,就能直接執行其建構子內的程式。
建構子(constructor) 建構子還有兩個非常重要的觀念: 建構子的方法名稱必須與定義類別的物件類別的名稱相同 建構子沒有回傳值,也沒有void的呼叫方法
建構子(constructor) 建構子的基本架構如下:
建構子(constructor) 接下來讓我們開始一步一步地編寫建構子的程式,假設現在定義類別為BankAccount的物件類別名稱,希望藉由建構子的方法分別求得帳戶所有者名字name及帳戶餘額balance
建構子(constructor) 過程如下步驟: Step1: 先命名定義類別的物件類別名稱 將物件類別名稱命名為BankAccount,型式如下: class BankAccount { … } Step2: 先做資料成員變數宣告 在這邊可依照前一單元所述,將宣告型式設定為私有成員如下: private String name; // name為字串的資料型態,故使用String private double balance; Step3: 建立建構子 因為建構子的方法名稱必須與定義類別的物件類別的名稱相同,故建構子的 方法名稱一定是:BankAccount, 絕對不可能會有其他名稱出現,而且不能 有void的呼叫型態 Step4: 參數的建立 在步驟2中,我們建立了兩個資料成員變數宣告,所以參數也是會有兩個,而 且對應的資料型態也必須相同,故型式如下: public BankAccount(String str, double amount) { name = str; balance = amount; } Step5: 輸出處理 輸出處理可利用void呼叫方式來顯示出畫面結果。
在主類別的設計過程步驟 Step1: 建立新物件並加入引數傳遞值 這步驟與之前所學得方式皆同,程式如下行: BankAccount account = new BankAccount("Paul", 3500); Step2: 呼叫輸出處理
範例檔: Ch7_7.java class BankAccount { private String name; private double balance; public BankAccount(String str, double amount) name = str; balance = amount; } public void show( ) System.out.println("帳號用戶: " + name +"\n帳號餘額: " + balance); class Bank public static void main(String args[ ]) BankAccount account = new BankAccount("Paul", 3500); account.show( );
輸出結果
建構子多載 是否還記得先前在學過的多載方法呢?多載除了可以用在物件方法,在建構子程式中,當然也可以與多載一起搭配。如果要使用建構子多載的方式,仍然有幾個要點必須要瞭解: 引數的資料型態與數目不可相同 使用定義類別的物件類別名稱 建構子沒有回傳值,也沒有void的呼叫方法
範例檔: Ch7_8.java class BankAccount { private String name; private double balance; public BankAccount( ) name = "Susan"; balance = 4500; } public BankAccount(String str, double amount) name = str; balance = amount; public void show( ) System.out.println("此帳號用戶為 " + name +", 帳號餘額為 " + balance);
範例檔: Ch7_8.java class Ch7_8 { public static void main(String args[ ]) BankAccount account1 = new BankAccount( ); account1.show( ); BankAccount account2 = new BankAccount("Paul", 3500); account2.show( ); }
輸出結果
建構子呼叫建構子,在建構子中使用this( ) 本單元所要討論的是建構子呼叫建構子,可透過this( )方式呼叫。這種方式是從範例Ch7_7.java延伸變化而來。讓我們先利用下面的比較圖,看看其不一樣的地方:
建構子呼叫建構子,在建構子中使用this( ) 一旦改為建構子呼叫建構子型態,可明顯看出有兩個變化之處: 增加了一個建構子,且透過this( )來呼叫。 增加的部份如同上圖有框起灰色的地方,並且使用 this( )來呼叫。 引數的易位 原本的引數是在新物件這邊,型式如下: 新物件.物件類別名稱(引數1, 引數2); 在建構子呼叫建構子型態中,則將引數移到 this( ),型式如下: this(引數1, 引數2); 最後在新物件這邊就沒有引數,型式如下: 新物件.物件類別名稱( );
範例檔: Ch7_9.java class BankAccount { private String name; private double balance; public BankAccount( ) this("Paul", 3500); } public BankAccount(String str, double amount) name = str; balance = amount; public void show( ) System.out.println("此帳號用戶為 " + name +"\n帳號餘額為 " + balance); class Ch7_9 public static void main(String args[ ]) BankAccount account = new BankAccount( ); account.show( );
輸出結果
私有建構子被建立 本章曾討論過資料成員可設為private私有成員,那建構子當然也可以建立私有建構子。之前提到private私有成員只能在同一類別下被呼叫,相對地,當建構子被設為私有建構子,也是只能在同一類別下被呼叫
範例檔: Ch7_10.java class BankAccount { private String name; private double balance; private BankAccount( ) System.out.println("私有建構元被建立"); } public BankAccount(String str, double amount)必須要放在這裡 this( ); name = str; balance = amount; public void show( ) System.out.println("此帳號用戶為 " + name +"\n帳號餘額為 " + balance); class Bank public static void main(String args[ ]) BankAccount account = new BankAccount("Paul", 3500); account.show( );
輸出結果
再談this 在類別程式設計中,有時會使用到自己的資料成員或方法成員,為了要能確認這個資料成員是否屬於該類別中的成員,這時可使用this來驗證,如果可以得到成員的資料值傳遞,那肯定是該類別中的成員,否則,就不可能會傳遞資料值。 this的表示型態如下: this.資料成員名稱
範例檔: Ch7_11.java class BankAccount { int checking=1000; //資料成員名稱 public void show( ) int checking=2000; //區域變數名稱 System.out.println("this.checking = "+ this.checking); System.out.println("checking = "+ checking); } class Ch7_11 public static void main(String args[ ]){ BankAccount account=new BankAccount( ); account.show( );
輸出結果
課堂綜合範例練習
課堂練習1:類別具回傳值之練習 請先開啟本書所附上的Practice7_1.java主類別檔,然後再根據此程式需求設計一個可以得到下面輸出畫面結果之定義類別:
課堂練習2:建構子之練習 此範例是練習建構子的程式設計,記得建構子的格式嗎?沒錯,就是使用定義類別名稱,根據下列畫面的輸出,我們可將此練習題的程式碼寫成如同範例檔Ch7_13.java之內容:
課堂練習3:多載化之練習 此範例是練習多載化的程式設計,只要具有不同引數型態及引數的數目不一樣,就可達成多載化的要件,此題以計算機形式來說明多載化的程式設計,輸出畫面參考如下:
The End