抽象類別

      在〈抽象類別〉中尚無留言

抽象類別(abstract class)

抽象類別有兩個主要目的

1. 禁止類別被實例化(new 物件)
2. 規範子類別必須遵循的契約 (強制實作抽象方法)

為什麼要禁止類別 new 出物件呢? 比如 Animal 是所有動物的統稱,是一個抽象名詞。如果可以 new 出 Animal,請問它應該長什麼樣子,貓、狗還是獅子?

直接產生 Animal 物件並沒有實際意義,所以會把 Animal 設計為抽象類別。

abstract class Animal{
}

或者為

abstract class Animal{
}

抽象方法

抽象類別中可以包含抽象方法,抽象方法必需使用 abstract 修飾子,且不能有方法本體

abstract class Animal{
    abstract public void food(String s);
}

子類別 Tiger 繼承抽象類別後,必需實作其抽象方法

class Tiger extends Animal{
    @Override
    public void food(String f) {
        
    }
}

實作方法時,子類別跟父類別的方法參數名稱不需一樣,但參數型別與順序必需相同,如上紅色部份。

抽象類別不一定要有抽象方法

其目的很單純的就是不讓類別實例化。

public class Main {
    public static void main(String[] args) {
        os.utf8();
        Tiger t1=new Tiger();
    }
}
abstract class Animal{
    //無任何東西
}
class Tiger extends Animal{
    //無任何東西
}

抽象類別可以有一般方法

抽象類別可以同時擁有抽象方法、一般方法、成員變數、建構子,如下藍色部份。

abstract class Animal{
    abstract public void food();
    public void move(){
        System.out.println("動物都是會移動的");
    }
}

多型

不管是 Animal 參考型態或是 Tiger 參考型態,都可以調用其方法 food/move。

public class Main {
    public static void main(String[] args) {
        os.utf8();
        Animal a1 = new Tiger();
        a1.move();
        a1.food();
        Tiger t1 = new Tiger();
        t1.move();
        t1.food();        
    }
}
abstract class Animal{
    abstract public void food();
    public void move(){
        System.out.println("動物都是會移動的");
    }
}
class Tiger extends Animal{
    @Override
    public void food() {
        System.out.println("老虎是吃肉的");
    }
}

存取權限規則

抽象方法不可以為 private,因為抽象方法是為了讓繼承者遵循必定的合約,即然要別人遵守,然後又不公佈合約的內容,這就矛盾了。所以抽象方法只能為 protected、預設、或 public。

另外子類別實作抽象方法時,子類別方法權限必需等於或寬於抽象方法的權限。如下面代碼中,因為父類別的抽象方法是 protected,所以藍色那行必需是 protected 或 public,不能是預設權限。

abstract class Animal{
    public int level;
    abstract protected void food();
}
class Tiger extends Animal{
    @Override
    public void food {}
}

抽象子類別

子類別使用 extends 繼承抽象類別,而且子類別不實作所有的抽象方法,則子類別需宣告為抽象類別。

abstract class Animal{
    abstract public void food();
}
abstract class Tiger extends Animal{

}

 分層實作設計

抽象子類別的用途是什麼呢,這是為了分層實作設計,請參照下說明。

abstract class Animal{
    abstract public void food();
    //.......還有 99 個抽象方法
}
abstract class Tiger_Factory extends Animal{
    //由系統商(比如Java)實作 99 個抽象方法
}
class Tiger extends Tiger_Factory{
    public void food(){

    }
}

抽象類別總結

  1. 子類別繼承抽象類別時,必須實作抽象方法(IDE 可用 Alt+Enter 自動產生)。
  2. 若子類別沒有實作所有抽象方法,則子類別也必須宣告為 abstract。
  3. 抽象方法只有方法宣告,不可以有方法本體。
  4. 子類別實作時,參數名稱可以不同,但型別與順序必須一致。
  5. 抽象類別不一定要有抽象方法,但如果有抽象方法,類別一定要宣告為 abstract。
  6. 抽象方法不能是 private。
  7. 子類別實作時,存取權限不能縮小。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *