有很多人說過:別濫用繼承,或者是優先考慮介面而非繼承。
# 什麼是介面?
如果有個人想開發一個海洋遊樂園的遊戲,當中所有東西都會游泳。
於是,第一個當下,會想到魚會游泳!!所以,馬上就設定 Fish 為一抽象類別,內部定義一個抽象的方法 swim()
,就可以實現啦!!
但是,如果那個會游泳的東西,不是魚呢??就像是人也會游泳阿!!難道,他就要繼承為魚了嗎?
為了解決這個問題,我們開發了介面,描述不同的類別的共通行為。
# 宣告介面
以上面的描述作為例子,我們可以用 interface 定義一個游泳這個行為:
[修飾子] interface 介面名稱{ | |
// 定義成員 | |
} | |
public interface Swimmer{ | |
void swim(); | |
} |
# 實作介面
# 單一介面
在定義類別時,您可以使用 implements 關鍵字來指定要實作哪個介面,介面中所有定義的方法都要實作:
public class Fish implements Swimmer{ | |
void swim(){ | |
System.out.println("魚仔底哩由來油漆~~"); | |
} | |
} |
必須實作『所有』該介面宣告的方法,否則會編譯錯誤!!!
# 多個介面
在 Java 不允許多重繼承,但同一個類別可以實作多個介面,算是彌補了不能多重繼承所帶來的不方便。
實作多個介面用 ,
隔開,寫上介面名稱,並且該類別必須實作每個介面所制定的方法。
class 類別名 implements 介面1, 介面2,...{ | |
// 定義成員 | |
} |
# 內定修飾子
在 interface
中定義的欄位、方法都有規定好的修飾子,可以寫也可以不寫,但不能衝突。
public abstract 回傳型態 方法名稱(); |
我們在撰寫時,可以不寫,但不能與其衝突!!
interface MyInterface{ | |
public abstract void A(); // ok | |
public void B(); // ok,編譯完會自行在執行檔加上 public abstract | |
void C(); // ok,編譯完會自行在執行檔加上 public abstract | |
private void D(); //not ok, 編譯錯誤,修飾子有衝突!! | |
void E(){}; //not ok, 編譯錯誤,只能定義原型,不行定義方法本體 | |
} |
# 介面欄位存取
介面內部也可以儲存資料,使用 介面名稱.欄位名稱
的方式就能將資料提出做使用~~
interface Park{ | |
int number = 10; | |
} | |
class Test{ | |
public static void main(String[] args){ | |
System.out.println(Park.number); // 10 | |
} | |
} |
要注意的是在介面中的欄位都是 public static final
的修飾,
所以不能改變其值,一般都是當作該介面的常數來使用。
# 介面繼承
介面也可以做到繼承的動作喔!!甚至,還可以多重繼承~~
interface 介面名稱 extends 介面1,介面2,...,介面n{ | |
// 定義成員 | |
} |
彼此繼承的話... 實作該介面的類別還是必須實作每個定義的方法。
interface A{ | |
void a(); | |
} | |
interface B{ | |
void b(); | |
} | |
interface C extends A,B{ // 介面的繼承,繼承多個介面以逗號『,』隔開 | |
void c(); | |
} | |
class MyClass implements C{ // 必須實作介面 C 及其所有父類別定義的方法 | |
public void a() { | |
} | |
public void b() { | |
} | |
public void c() { | |
} | |
} |
# 抽象類別與介面的比較
抽象類別與介面有點像,兩個都不行被實體化成物件。
# 抽象類別
- 用於被繼承,子類別要實作定義的抽象方法。
- 抽象類別中可以定義完整的方法 (方法本體),也可以只定義方法原型。
- 可以定義完整的資料欄位供繼承類別使用。
- 設計中心以資料為主體。
# 介面
- 用於被實作,子類別要實作定義的方法。
- 介面中只能定義方法原型,不能有方法本體。
- 方法的修飾子必為
public abstract
,欄位的修飾子必為public static final
,可省略不可衝突。 - 定義的資料欄位用於作為常數使用。
- 設計中心以方法 (行為) 為主體。
- 若只是行為相同以介面來設計會比較恰當。