本文是系列文章「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 的基礎語法。