Java 入門指南 V2.00 - 單元 8 - 類別




Java 中一個類別 (class) 就是一個程式檔案,類別名稱要跟檔案名稱相同。典型的類別定義,如下圖



整體結構就是宣告類別,類別名稱之後用一對大括弧把定義圍起來,裡頭可以定義屬性 (field) 與方法 (method) ,屬性就是專屬於類別的變數,方法則是類別進行工作的地方。如果這個類別還需要是可執行的,就得額外定義特別的 main() 方法。我們將上面的定義例子寫成完整的範例程式,如下


001// 宣告類別名稱
002public class ClassDemo01 {
003   // 這裡定義屬性
004   int a;
005     
006   // 這裡定義方法
007   public int doSomething(int p1) {
008      return a + p1;
009   }
010      
011   // 這裡定義 main() 方法
012   public static void main(String[] args) { 
013      ClassDemo01 d = new ClassDemo01();
014      d.a = 11;
015
016      System.out.println();
017      System.out.println(d.doSomething(5));
018      System.out.println();
019   }
020}
021 
022/* 檔名: ClassDemo01.java
023   作者: Kaiching Chang
024   時間: September, 2014  */

記不記得之前完整範例中都有 main() ,先來編譯執行這個範例程式,看看執行出什麼結果囉



程式的執行在 main() 方法的定義地方


011// 這裡定義 main() 方法
012public static void main(String[] args) { 
013   ClassDemo01 d = new ClassDemo01();
014   d.a = 11;
015
016   System.out.println();
017   System.out.println(d.doSomething(5));
018   System.out.println();
019}

我們在 main() 中宣告 (declare) 並建立相同 ClassDemo01 型態的物件 d ,為什麼可以這樣做呢?為什麼可以在 main() 中建立相同類別的物件 (object) ?答案很簡單,這是因為 static 的關係。由於屬性及方法合稱成員 (member) ,類別中的成員有兩種,一種用 static 修飾, static 成員屬於類別,另一種沒有用 static 修飾,這一類成員屬於物件實體 (instance) 。


ClassDemo01 中, a 為實體屬性 (instance field) , doSomething() 是實體方法 (instance method) ,而 main() 則是類別方法 (class method) 。實體成員與類別成員兩者最大的不同就是互相不能直接存取對方,如果要在 main() 中使用 a ,那就得在 main() 裡建立 ClassDemo01 型態的物件實體。


此例在 main() 中建立 ClassDemo01 的實體變數 d ,然後將 d 的屬性 a 設置為 11


013ClassDemo01 d = new ClassDemo01();
014d.a = 11;

然後呼叫 doSomething() 方法


017System.out.println(d.doSomething(5));

接著我們往上找實體屬性 a 的宣告,這在第 4 行


003// 這裡定義屬性
004int a;

通常屬性的宣告會放在 class 關鍵字 (keyword) 的下一行,數量依需求而定。


doSomething() 定義在第 7 行到第 9 行之間


007public int doSomething(int p1) {
008   return a + p1;
009}

此例的 doSomething() 需要一個 int 參數 (parameter) p1 ,結果回傳一個 int 整數。小括弧裡頭放參數,稱之為參數列 (parameter list) ,因為參數的數量也可依需求而定。


Java 允許方法可以有不同的參數列版本,這稱之為多載 (overload) ,我們將 ClassDemo01doSomething() 改成多載版本,如下


001public class ClassDemo02 {
002   int a;
003     
004   // 這裡定義 doSomething() 的第一個版本
005   public int doSomething(int p1) {
006      return a + p1;
007   }
008
009   // 這裡定義 doSomething() 的第二個版本
010   public double doSomething(double p1) {
011      return a + p1;
012   }
013      
014   public static void main(String[] args) { 
015      ClassDemo02 d = new ClassDemo02();
016      d.a = 11;
017
018      System.out.println();
019      System.out.println(d.doSomething(5));
020      System.out.println(d.doSomething(7.2));
021      System.out.println();
022   }
023}
024 
025/* 檔名: ClassDemo02.java
026   作者: Kaiching Chang
027   時間: September, 2014  */

ClassDemo02doSomething() 有兩個版本


005public int doSomething(int p1) {
010public double doSomething(double p1) {

第一個 doSomething() 用了 int 的參數 p1 ,第二個 doSomething() 的參數型態則是 double ,兩者構成不同的多載版本。


回傳值型態 (return type) 並不影響多載的版本差異,只有參數列不同才構成多載,至於參數列指參數的型態、數量、排列順序等。

如果運算式中的兩個數值 (value) 都是基本資料型態 (primitive data type) ,編譯器 (compiler) 會自動替其中一個數值先進行型態轉換,如上面第二個 doSomething()a + p1a 會先轉換成 double ,然後才與 p1 相加。

多載的目的不外就是讓同一個方法可以處理不同型態的參數,如此例可以用 int 呼叫 doSomething() ,也可以用 double 呼叫 doSomehting() ,很簡單的例子,兩個參數列都只有一個參數,差異僅在型態不同而已。


編譯後執行,結果如下



接下來,我們開始介紹物件導向程式設計 (object-oriented programming) 的特性             封裝 (encapsulation) 。


中英文術語對照


類別class
屬性field
方法method
宣告declare
物件object
成員member
實體instance
實體屬性instance field
實體方法instance method
類別方法class method
關鍵字keyword
參數parameter
參數列parameter list
多載overload
回傳值型態return type
基本資料型態primitive data type
編譯器compiler
物件導向程式設計object-oriented programming
封裝encapsulation

重點整理


  1. 一個類別就是一個程式檔案,類別名稱要跟檔案名稱相同。
  2. 定義類別要先宣告類別名稱,其後接大括弧,大括弧內為類別的定義內容,可定義屬性及方法。
  3. 類別有兩種成員,屬性是專屬於類別的變數,方法則是類別進行工作的地方,如果是可執行的類別,就要另外定義 main() 方法。
  4. 類別的成員又分為用 static 修飾的類別成員及沒有用 static 修飾的實體成員,兩者最大的不同是不能直接互相存取?
  5. 方法依參數列的不同而有不同的多載版本,但回傳值型態並不影響版本差異。


問題與討論


  1. 一個程式檔案只能有一個類別定義嗎?
  2. 參數有個數限制嗎?
  3. 類別跟物件有什麼不同?為什麼要有專屬類別的 static 成員?
  4. 多載是什麼?為什麼允許方法可以多載?

the end

沒有留言: