本文是系列文章「Java 初階篇」的第二章,著重於基礎概念的建立。
1. 初探 Java 程式
建立第一個 Java 程式,取名為Main.java,並輸入以下程式碼:
class Main {
/*
我是第一支Java程式
我會顯示出文字:Hello World!
*/
public static void main(String[] args) {
System.out.println("Hello World!"); // 顯示出文字:Hello World!
}
}
執行結果:
Hello World!
1.1 類別
類別(Class)名需要與檔名一樣,必須是以大寫英文字母開頭,例如類別Main與檔名Main.java。
class Main {
}
1.2 程式進入點
JVM 執行程式時,會先找程式進入點(Program Entry),而且規定必須是public static void main(String[] args)。
public static void main(String[] args) {
}
- public:公開,表示此方法為公開。
- static:靜態,表示程式執行前,需要把這些內容載入到記憶體。
- void:此處為回傳值的型態,void 表示沒有回傳值。
- main:表示程式進入點的名稱,JVM 規定一定要取名「main」。
- String[] args:JVM 規定 main 接受字串陣列當做參數。
- String[]:表示字串陣列。
- args:表示字串陣列的變數名稱。
重點:
- 在 Java 的函數(Functions、Methods)中,可提供或不提供 input,然後獲得一個 output。
- Class 規則:名稱要與文件名稱相同、名稱要以大寫英文字母開頭、要寫在
public static void main(String[] args)裡面。
1.3 標準輸出
Java 的標準輸出是透過 System.out 物件來達成。
System.out.println("Hello World!");
System 類別 (Class) 的 out 屬性 (Field) 中有print()方法 (Method) ,印出參數(Parameter)。
- System:一個叫 System 的類別。
- out:在 System 類別中的一個屬性。
println():在 System 類別的 out 屬性中有println()方法,印出參數。println 是 print line 的縮寫,指將後方括號中的內容打印到螢幕上,並且之後會換行。
注意:
- 每一行程式碼要以分號「;」作結尾。
1.4 註解
註解(Annotation)功能是讓你在程式碼旁邊作備註,讓程式可以更方便閱讀與維護。
【多行註解】
/*
我是第一支Java程式
我會顯示出文字:Hello World!
*/
符號/* */中間可輸入你想要的註解,若註解比較長,需要多行才能輸入完成,則可使用多行註解。
【單行註解】
// 顯示出文字:Hello World!
符號//後面可輸入你想要的註解,若註解比較短,只要單行就可輸入完成,則可使用單行註解。
2. 初探物件導向
我們做出上面的程式「Hello World!」之後,相信你開始有了對程式的基本認識。接下來,要開始進入物件導向的基礎概念,簡單了解當中的詞彙定義與作用。
2.1 類別與物件
【類別 Class】
類別就像是一個藍圖,可以定義物件的屬性、方法,沒有實體(Instance)的概念,屬於靜態的,例如房屋的設計藍圖。
【物件 Object】
物件就像是建造好的房屋,有其屬性、方法,有實體概念,屬於動態的,在記憶體中佔有空間。
屬性與方法是什麼?
- 屬性(Property):以人來說就像姓名、性別、身高、體重等等。
- 方法(Method):以人來說就像說話、吃飯、走路、跑步等等。
【定義與創造】
有了類別與物件的概念,就可以開始學如何設計(定義)與建造(創造)。
先定義類別,以中文來表達:
class Human{ // 類別名稱
姓名; // 定義屬性
年齡; // 定義屬性
吃飯(); // 定義方法
睡覺(); // 定義方法
}
以程式碼來表達就是:
class Human{
String name;
int age;
void eat(){
System.out.println("eating...");
}
void sleep(){
System.out.println("sleeping...");
}
}
有了類別藍圖之後,就可以開始創造物件。
創造物件需要:
- 宣告:
類別名稱 物件名稱;。 - 初始化:
物件名稱 = new 類別建構子();。
例如:
Human ken; // 宣告
ken = new Human(); // 初始化
還可以簡化成一行:
Human ken = new Human();
宣告一個人類,叫「ken」,此時記憶體中就會有一塊空間叫「ken」。
物件名稱「ken」透過關鍵字「new」,利用建構子Human()進行初始化,此時記憶體中就會另一塊空間存放人類藍圖(屬性、方法),再把這塊空間的記憶體地址回傳到物件名稱「ken」,這樣物件名稱與類別的屬性、方法就連接起來了。
這樣我們就等於創造了一個叫 ken 的人類,具有人類藍圖中的屬性與方法,這就是「物件的實體化(Instantiated)」,而實體就是在記憶體當中佔有空間的物件。
2.2 屬性與方法
我們有一個人類藍圖「Human」:
class Human {
String name;
int age;
void eat(){
System.out.println("eating...");
}
void sleep(){
System.out.println("sleeping...");
}
}
裡面有定義:
- 屬性:姓名、年齡。
- 方法:吃飯、睡覺。
然後我們有另一個類別「World」:
class World {
public static void main(String[] args) {
Human ken = new Human();
ken.name = "ken";
ken.age = 18;
System.out.println(ken.name + ", " + ken.age);
ken.eat();
ken.sleep();
}
}
在這個世界(World)裡面,我們透過類別「Human」(人類藍圖),創造一個物件叫 ken(實體化的人類)。
要如何為這個人類賦予屬性與方法呢?
就是透過「點」運算子(Dot Operator),去存取物件中的屬性與方法。
存取屬性與方法:
- 賦予這個人類的姓名,叫 ken:
ken.name = "ken";。 - 賦予這個人類的年齡,為 18 歲:
ken.age = 18; - 打印出一段文字「姓名, 年齡」:
System.out.println(ken.name + ", " + ken.age);。 - 執行這個人類的動作「吃飯」:
ken.eat();。 - 執行這個人類的動作「睡覺」:
ken.sleep();。
然後執行程式,輸出結果:
ken, 18
eating...
sleeping...
上面這些程式碼其實還可以再簡化,這時就需要運用到下文提到的「建構子」。
2.3 建構子
在上文中,我們有遇到一個名詞叫「建構子」(Constructor),建構子是什麼?
我們先看一下這一行:
Human ken = new Human();
- Human:類別名稱。
- ken:物件名稱。
- =:指定運算子,作用是將等號右方的值指定(Assign)給等號左方。
- new:new 關鍵字,作用是根據一個類別「新建」一個物件。
Human():建構子(Constructor)。
建構子Human()長什麼樣子?
class Human {
Human(){
}
}
- 與類別名稱同名。
- 不可以有回傳值。
- 有引數(Arguments):
Human([arguments])。 - 被 new 關鍵字呼叫,功能是初始化物件。
- 建構子可以有好幾個,但引數型態的個數不可以相同。
如果在類別當中,你沒有定義建構子的話,Java 會幫你定義一個不帶參數的建構子,而且你看不到:
class Human {
String name;
int age;
/*
Human(){
}
*/
void eat(){
System.out.println("eating...");
}
void sleep(){
System.out.println("sleeping...");
}
}
如果你有定義建構子的話,Java 就不會幫你定義一個不帶參數的建構子。
上文中有提到可以透過建構子簡化程式碼,接下來我們就來定義有帶參數的建構子:
class Human {
String name;
int age;
// 建構子1:姓名
Human(String strName){
name = strName;
}
// 建構子2:姓名, 年齡
Human(String strName, int intAge){
name = strName;
age = intAge;
}
void eat(){
System.out.println("eating...");
}
void sleep(){
System.out.println("sleeping...");
}
}
我們寫了兩個建構子,接著我們再創造物件時,就可以用 new 關鍵字去呼叫這些建構子:
class World {
public static void main(String[] args) {
Human tony = new Human("tony"); // 呼叫建構子1
System.out.println(tony.name);
Human ken = new Human("ken", 18); // 呼叫建構子2
System.out.println(ken.name + ", " + ken.age);
ken.eat();
ken.sleep();
}
}
執行結果:
tony
ken, 18
eating...
sleeping...
此時,如果你初始化一個不帶參數的 test 物件,就會編譯錯誤:
class World {
public static void main(String[] args) {
Human test = new Human(); // 編譯錯誤
Human tony = new Human("tony");
System.out.println(tony.name);
Human ken = new Human("ken", 18);
System.out.println(ken.name + ", " + ken.age);
ken.eat();
ken.sleep();
}
}
因為你在類別「Human」裡面已經寫了帶有參數的建構子,Java 就不會幫你定義一個不帶參數的建構子,如果你想要有一個不帶參數的建構子,就要自行定義:
class Human {
String name;
int age;
// 自行定義一個不帶參數的建構子
Human(){
}
// 建構子1:姓名
Human(String strName){
name = strName;
}
// 建構子2:姓名, 年齡
Human(String strName, int intAge){
name = strName;
age = intAge;
}
void eat(){
System.out.println("eating...");
}
void sleep(){
System.out.println("sleeping...");
}
}
補充:
- 參數(Parameter):方法定義中的屬性,例如範例中的 strName、intAge。
Human(String strName, int intAge){ name = strName; age = intAge; }
- 引數(Argument):呼叫方法時所傳入的數值,例如範例中的 “ken”、18。
Human ken = new Human("ken", 18);
3. 後記
本篇文章從第一個 Java 程式開始,逐步講到當中所遇到詞彙的定義與功用,相信對讀者來說很簡單,應該能夠寫出一個比單純打印出文字「Hello World!」再複雜一點的程式了,下篇文章將進入 Java 的基礎語法。