整體結構就是宣告類別,類別名稱之後用一對大括弧把定義圍起來,裡頭有屬性 (field) 、建構子 (constructor) 、方法 (method) 的的定義,如果這個類別還需要是可執行的,就得額外定義 main() 方法。我們將上面的定義例子寫成完整的範例程式,如下
// 宣告類別名稱 public class Demo2 { // 這裡定義屬性 int a; int b; // 這裡定義建構子 public Demo2(int a, int b) { this.a = a; this.b = b; } // 這裡定義方法 public int do_something() { return a + b; } // 這裡定義 main() 方法 public static void main(String[] args) { Demo2 demo = new Demo2(11, 22); System.out.println(); System.out.printf("a = %d, b = %d\n", demo.a, demo.b); System.out.printf("a + b = %d\n", demo.do_something()); System.out.println(); } } /* 《程式語言教學誌》的範例程式 http://pydoing.blogspot.com/ 檔名:Demo2.java 功能:示範 Java 程式 作者:張凱慶 時間:西元 2011 年 4 月 */
先來編譯執行,看看執行出什麼結果囉
程式的執行在 main() 方法的定義地方
// 這裡定義 main() 方法 public static void main(String[] args) { Demo2 demo = new Demo2(11, 22); System.out.println(); System.out.printf("a = %d, b = %d\n", demo.a, demo.b); System.out.printf("a + b = %d\n", demo.do_something()); System.out.println(); }
我們在 main() 中宣告 (declare) 並建立相同 Demo2 型態的物件 demo ,為什麼可以這樣做呢?為什麼要在 main() 中另外建立物件 (object) ,而非直接存取屬性 a 及 b 呢?答案很簡單,首先,因為 a 與 b 沒有給初值,我們當然可以定義後直接給初值,例如
// 這裡定義屬性 int a = 11; int b = 22;
這樣屬性 a 與 b 就各自擁有初值 11 及 22 ,我們的作法卻是
// 這裡定義屬性 int a; int b;
屬性通常定義在所有方法之外,通常直接放在大括弧之後,類別宣告的下一行。這裡只有進行屬性的宣告,也就是宣告屬性為 int 型態的變數,注意,這裡我們在 int 之後空一格,然後接上屬性的識別字 (identifier) 名稱。
Java 並沒有嚴格限制程式的編排方式,所以只要合乎語法, int 空一格,或空兩格並沒有多大關係,但須小心,如果把 int 跟識別字連結在一起,如 inta 或 intb ,編譯器會認為這是額外的識別字名稱,並非我們想要的 a 或 b 了。
因為我們的目的是宣告類別 Demo2 有哪些屬性,也就是先宣告屬性的資料型態,以及屬性的識別字名稱,屬性的值實際是由建構子所賦予,這也是建構子的主要功能之一。再來看到建構子定義的地方
// 這裡定義建構子 public Demo2(int a, int b) { this.a = a; this.b = b; }
建構子如同方法,但不具有回傳值 (return value) 型態 (type) ,因為建構子的目的就是建立物件 (object) ,因此無須指明回傳值的型態。這裡,建構子有兩個參數 (parameter) ,分別是 a 與 b ,由於名稱和屬性相同,在建構子後面的大括弧,也就是建構子的程式區塊 (block) 中,參數 a 與 b 作為此區塊的區域變數 (local variable) ,屬性名稱 a 與 b 便無法使用,因此我們利用關鍵字 (keyword) this 來存取屬性,並把參數指派 (assignment) 給屬性。
當然,若是屬性名稱與建構子的參數名稱不同,我們可以不用 this 便可直接存取屬性名稱,例如
// 這裡定義建構子 public Demo2(int c, int d) { a = c; b = d; }
這樣的小程式中,怎麼寫倒是看個人喜好,往後陸續介紹 public 、 private ,也就是權限方面的修飾詞 (modifier) 之後,我們會提供另外一種寫法。附帶一提, public 是公開的意思, private 則是私有的意思。
Demo2 只有定義一個方法,也就是 do_something()
// 這裡定義方法 public int do_something() { return a + b; }
do_something() 回傳兩個屬性的相加值, return 是關鍵字之一,用來在方法中回傳數值。這裡 + 是 Java 的算術運算子 (arithmetic operator) 之一,用來作加法,因此 a + b 構成一個運算式 (expression) ,運算式會有一個計算結果, return 就是回傳這個計算結果。
注意, + 是鍵盤上直接打出來的半形字元,非全形字元 + 。
方法宣告時,除了回傳值型態,就是小括弧中的參數列 (parameter list) ,若無提供參數,小括弧就應該留空,也就是不填進任何東西,類似的,方法若無回傳值,應該宣告為 void ,像是 main() 就宣告成沒有回傳值的 void 。
我們回到最早的問題,也就是為什麼可以在 main() 中建立與 Demo2 相同的物件?其實原因很簡單,就是 static 的緣故。 static 中文稱為靜態的,由於屬性與方法在類別中合稱為成員 (member) ,宣告為 static 的成員被稱為 static 成員, static 成員屬於類別,非 static 成員屬於物件。
成員屬於類別跟屬於物件到底有什麼不同呢?差別在, static 成員可以以類別名稱呼叫,我們不是已經用過很多個 System.out.println() 的例子了嗎?
System.out.println()
out 是 System 類別的 static 成員, out 是個 PrintStream 型態的物件,而 println() 為 out 的非 static 成員,其為印出字串 (string) 結尾附加上新行符號的方法。
所以,我們要讓 Demo2 變成可執行的類別,我們就得替 Demo2 加上 main() 方法的定義,由於 main() 屬於 static 的成員, static 成員不能存取非 static 成員,這裡所謂的不能,其實是 Java 的語法規則,所以為了使 Demo2 可以測試 Demo2 自己,語法允許我們可以在 Demo2 的 main() 中建立 Demo2 的物件。
有很難懂嗎?如果我們不想用 Demo2 測試 Demo2 他自己,那我們就得另寫一個含有 main() 的類別,如 Demo3 ,然後在 Demo3 中的 main() 建立 Demo2 的物件
// 測試 Demo2 的類別 public class Demo3 { public static void main(String[] args) { Demo2 demo = new Demo2(11, 22); System.out.println(); System.out.printf("a = %d, b = %d\n", demo.a, demo.b); System.out.printf("a + b = %d\n", demo.do_something()); System.out.println(); } } /* 《程式語言教學誌》的範例程式 http://pydoing.blogspot.com/ 檔名:Demo3.java 功能:示範 Java 程式 作者:張凱慶 時間:西元 2011 年 4 月 */
Demo3 必須和 Demo2 在相同資料夾內,兩個類別檔案也必須分開編譯 (compile) 。嗯, Demo2 、 Demo3 等等講了這麼多名稱,這些都是識別字,我們接下來看看變數命名規則吧!
中英文術語對照 | |
---|---|
類別 | class |
屬性 | field |
建構子 | constructor |
方法 | method |
宣告 | declare |
物件 | object |
識別字 | identifier |
回傳值 | return value |
型態 | type |
物件 | object |
參數 | parameter |
區塊 | block |
區域變數 | local variable |
關鍵字 | keyword |
指派 | assignment |
修飾詞 | modifier |
算術運算子 | arithmetic operator |
運算式 | expression |
參數列 | parameter list |
成員 | member |
字串 | string |
編譯 | compile |
您可以繼續參考
基礎篇
相關目錄
回 Java 入門指南
回 Java 教材目錄
回首頁
參考資料
The JavaTM Tutorials: Getting Started
The JavaTM Tutorials: Learning the Java Language
The JavaTM Tutorials: Essential Classes
The Java Language Specification, Third Edition
本文於 2013 年 1 月訂正
2 則留言:
out 應該是 System類別的 "物件" 而不是System類別的成員
類別中的 field 與 method 合稱為成員沒錯,當然這裡也有說明 out 是 PrintStream 型態的物件 ^_^
張貼留言