介面(Interface)
完全不相關的類別, 卻擁有相同的功能. 比如鳥跟飛機, 一個是生物, 一個是機械, 但卻同樣擁有 “飛” 的功能. 這有種群組的功能.
另外也可以想成, 二個完全不相關的類別, 但擁有相同的方法, 此時可以用Interface讓每個類別實作.
這種觀念有點像具某種功能一樣. 比如皮卡丘是神奇寶貝, 是爬蟲類. 而劍魚也是神奇寶貝, 但屬於水中生物.
其實介面是為了彌補Java單一繼承的缺陷, 也就是多型的部份. 多型會在日後的章節中詳述. 所以在有多重繼承的語言中, 比如Python, 就沒有interface了.
介面同時也跟抽象類別一樣, 規定繼承者必需遵守的契約
interface Land{ void walk(); } interface Water{ void swin(); } abstract class Pokemon{ abstract public void setLevel(int l); } class Pikachi extends Pokemon implements Land{ @Override public void walk() { System.out.println("用爬的"); } @Override public void setLevel(int level){} } class Fish extends Pokemon implements Water{ @Override public void swin() { System.out.println("用游的"); } public void setLevel(int level){} }
interface修飾子
interface中的方法, 一定是 abstract public, 系統會自動加入, 也可以手動加入. 不過請注意, C#是不允許雞婆的手動加入.
若介面的抽象方法宣告為private or protected, 則會編譯錯誤
public interface Returnable{ abstract public String doReturn(); }
子類別實作
子類別繼承了介面, 此時的關鍵字就不再是extends了, 而是 implements.
class Pikachu implements Land{}
此時的Pikachu就必需實作Land的所有抽象方法.
實作多個介面
為什麼要實作多個介面呢?? 讓我們思考一下青蛙 class Frog, 它到底是要實作Land, 還是Water? 青蛙是兩棲生物嘛, 所以當然是一起實作. 多個介面中間, 以 “,” 隔開
interface Land{} interface Water{} class Frog implements Land, Water{}
抽象類別與介面同時實作
類別可以在繼承類別或抽象類別時, 又同時實作多個介面. 但此類別就必需實作抽象類別及所有介面的所有抽象方法
abstract class Pokemon{ public int level; protected abstract void setLevel(int l); } interface Land{ void setWalk(); } interface Water{ void setSwinning(); } class Frog extends Pokemon implements Land, Water{ @Override protected void setLevel(int l) {} @Override public void setWalk() {} @Override public void setSwinning() {} }
多型
若要使用interface裏的方法, 則物件參考必需是此Interface或是implement此介面的類別才可以, 若物件參考是沒實作此介面的類別則無法存取
public static void main(String[] args) { Pokemon p1=new Pikachi(); //p1.walk(); Pikachi p2=new Pikachi(); p2.walk(); }
p1屬Pokemon, 跟Land沒關係, 所以不能使用 walk();
p2屬Pikachi, is a Land, 所以可以使用walk();
介面的變數
介面內的變數, 一定是常數欄位(constant fields), 系統會自動視為public static final 變數. 所以變數都要自行給定初始值.
interface Running{ public static final String WARNING="這是爬蟲類"; public void run(); }
介面繼承
青蛙是兩棲生物, 所以實作了Land及Water二個介面. 那可以將Land及Water變成一個 Amphibian 介面, 再給青蛙實作嗎. 是的, 介面可以繼承介面, 而且是可以多重繼承的.
請注意喔, 介面的繼承是 extends.
abstract class Pokemon{
public int level;
protected abstract void setLevel(int l);
}
interface Land{
void setWalk();
}
interface Water{
void setSwinning();
}
interface Amphibian extends Land, Water{}
class Frog extends Pokemon implements Amphibian{
@Override
protected void setLevel(int l) {}
@Override
public void setWalk() {}
@Override
public void setSwinning() {}
}
介面與抽象類別的抽象方法相衝
類別可以implements 多個介面. 試想, 若每個介面都有相同的方法時, 那類別要怎麼實作? 其實不相衝, 只要實作一個就好了
介面總結
1. 介面只能有抽象方法, 不能有實体代碼
2. 介面的抽象方法一定是abstract public
3. 介面可以有變數, 但系統會自動加入 final public static
考題
有二個介面及一個抽象類別
interface Land{}
interface Water{}
abstract class Pokemon{}
請問以下何者是正確的
1. class Frog implements Pokemon{}
2. class Frog extends Pokemon{}
3. class Frog extends Land{}
4. class Frog implements Land, Water{}
5. class Frog extends Pokemon implements Land, Water{}
6. interface Amphibian implements Land{}
7. interface Amphibian extends Land, Water{}
Ans:
2, 4, 5, 7