本文是系列文章「Java 初階篇」的第四章,介紹物件導向程式設計。

物件導向程式設計(Object Oriented Programming)是一種具有物件概念的程式設計典範,我們真實世界中的事物都可以抽象化為物件,例如鍵盤、汽車、畫筆等等,在腦子裡描述物件的這個過程就是抽象化。物件導向程式設計的優點大致有程式易讀易懂、易維護、支持更大的系統、多人合作等等。

1. 封裝

把某事物抽象化為物件之後,裡面有些資訊想要隱藏起來不給外部使用,只公開一些方法讓外部使用。

例如:

class 蛋糕販賣機{
    private int 蛋糕數量;
    ......
    private boolean 會員確認(會員卡密碼){
        ......
    }
    private void 投出蛋糕(){
        ......
    }
    public void 買蛋糕(會員卡密碼){
        if(會員確認(會員卡密碼) == true)
            投出蛋糕();
        ......
    }
    public void 查詢會員(會員卡密碼){
        ......
    }
    ......
}

利用修飾子 private、public,把各內容做公開或隱藏,讓使用者只能使用某些方法。

1.1 存取修飾子

  • public:公開,任何人都可存取。
  • protected:保護,只有該類別的子類別才可存取。
  • no modifier:預設,只有同一個 package 之中的類別才可存取。
  • private:私有,只有自己類別的成員才可存取。

比較表:

ClassPackageSubclass(same pkg)Subclass(diff pkg)World
publicVVVVV
protectedVVVVX
no modifierVVVXX
privateVXXXX

via stackoverflow

2. 繼承

用物件導向來想像貓跟動物的話,在我們的真實世界中,貓是一種動物,具有動物的屬性與方法,以及只有貓才有的屬性與方法,動物就是父類別(super class),貓就是子類別(sub class),貓繼承了動物的屬性與方法,所以子類別會繼承父類別的屬性與方法,同時也擁有自己的屬性與方法,也就是說子類別就是父類別的延伸(extend)。

在 Java 中,要用關鍵字extends來表示繼承關係:

class 子類別 extends 父類別{
    ......
}

例如:

class 動物{
    int 體重;
    int 年齡;
    ......
    void (){
        ......
    }
    ......
}

class  extends 動物{
    void (){
        ......
    }
    void (){
        ......
    }
    ......
}

3. 多型

利用父類別提供的方法,子類別也可以有自己獨特的行為。

例如:

class 動物 {
    void () {
        System.out.println("啊啊啊!");
    }
}
class  extends 動物 {
    void () {
        System.out.println("喵喵喵!");
    }
}
class  extends 動物 {
    void () {
        System.out.println("汪汪汪!");
    }
}
class  extends 動物 {
    void () {
        System.out.println("啾啾啾!");
    }
}
class Test {
    public static void main(String[] args) {

        動物 a =new 動物();
        動物 b =new ();
        動物 c =new ();
        動物 d =new ();

        a.();
        b.();
        c.();
        d.();

    }
}

輸出結果:

啊啊啊
喵喵喵
汪汪汪
啾啾啾

4. 抽象

關鍵字 abstract(抽象)可以用來修飾類別與方法。

4.1 抽象類別

例如:

abstract class 動物{
    int 體重;
    int 年齡;
    ......
    void (){
        ......
    }
    ......
}
class Test {
    public static void main(String[] args) {
        動物 a = new 動物();
    }
}

此時會編譯錯誤,因為抽象類別無法被實體化,但可以被繼承。

例如:

abstract class 動物 {
    ......
}

class  extends 動物 {
    ......
}

class  extends 動物 {
    ......
}

class  extends 動物 {
    ......
}

動物是一個概念,是抽象的,不能被實體化,而貓、狗、鳥是實際存在的,可以繼承動物的特性。

4.2 抽象方法

把方法變成抽象方法,只能定義其原型,但可以被覆寫。

例如:

abstract class 動物{
    int 體重
    int 年齡
    abstract void ();
}
class  extends 動物{
    void (){
        System.out.println("吃魚......");
    }
}
class  extends 動物{
    void (){
        System.out.println("吃雞腿......");
    }
}

抽象的「動物」類別中,有抽象的「吃()」方法,強制繼承「動物」的子類別必須實作自己的「吃()」方法,同時也擁有「動物」定義的成員。

需注意抽象方法只能定義在抽象類別中。

5. 介面

看完上面的 abstract(抽象),就可以知道如果想要減少重複的程式碼,又想要子類別可以有方法規範,則可使用 abstract(抽象)。

如果想要只規範子類別的方法時,或者想要同個子類別實作多個不同的介面(多重繼承),則可使用 interface(介面)。

5.1 宣告

宣告:

(修飾子) interface 介面名稱 {
    ......
}

例如:

public interface 進食{
    void ();
}

public interface 飛行{
    void ();
}

5.2 實作

關鍵字 implements 可讓類別實作介面,而類別需要定義該介面所制定的方法。

class  implements 進食 {
    public void (){
        System.out.println("貓可以吃食物!")
    }
}

class  implements 飛行 {
    public void (){
        System.out.println("鳥可以飛!")
    }
}

class 老鷹 implements 進食, 飛行 {
    public void (){
        System.out.println("老鷹可以吃食物!")
    }

    public void (){
        System.out.println("老鷹可以飛!")
    }
}
進食 a = new ();
a.();

輸出結果:

貓可以吃食物