抽象類別(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(){
}
}
抽象類別總結
- 子類別繼承抽象類別時,必須實作抽象方法(IDE 可用 Alt+Enter 自動產生)。
- 若子類別沒有實作所有抽象方法,則子類別也必須宣告為 abstract。
- 抽象方法只有方法宣告,不可以有方法本體。
- 子類別實作時,參數名稱可以不同,但型別與順序必須一致。
- 抽象類別不一定要有抽象方法,但如果有抽象方法,類別一定要宣告為 abstract。
- 抽象方法不能是 private。
- 子類別實作時,存取權限不能縮小。
