查了一些國內資料,都說java中extended與implements的區別是,一個類只能有一個繼承,一個類能夠有多個容器。java
後來去看了些國外資料。web
在我理解上,interface就是一個公共的類,能夠包含公共函數、變量。設計模式
Java接口是用於指定一組抽象方法的類來實現一個抽象類型。ide
當一個類實現一個接口,它必須繼承全部的內聲明的抽象方法,好像簽定了一份合同,並履行協議。函數
先來看看怎麼聲明一個接口,文件保存爲 InterFace.java
:this
public class InterFace { public static void main(String[] args) { MyTest x = new MyTest(); x.speak(); x.say(); x.fuck(); } } class MyTest implements MyInterface2, MyInterface3 { @Override public void speak() { System.out.println("MyTest Called => jump() =>"+MyInterface.hello); } @Override public void fuck() { System.out.println("MyTest Called => fuck()"); } @Override public void say() { System.out.println("MyTest Called => say()"); } } interface MyInterface1{ public String hello = "hello"; public void speak(); } interface MyInterface2{ public int num = 1; public void fuck(); } // 接口之間能夠相互繼承 interface MyInterface3 extends MyInterface1{ public void say(); }
輸出以下:spa
$javac InterFace.java $java InterFace MyTest Called => jump() =>hello MyTest Called => say() MyTest Called => fuck()
這裏咱們聲明瞭3個接口,而且interface3繼承自interface1,因此當類容器導入接口interface3就會導入父類接口interface1。.net
只要添加了容器implements,就會包含接口中的全部東西,因此必須在MyTest
類中添加該重寫函數,不然找不到該函數會報錯。設計
再看下面一個例子,多個類共同使用一個interface接口,保存爲Account.java
:
interface Transaction { int BALANCE = 500; Object transaction(Object input); } class CurrentAccount implements Transaction { int bal; public Object transaction(Object input) { this.bal = BALANCE - (int)input; return bal; } public String toString() { return "Current acc"; } } class SavingsAccount implements Transaction { int bal; public Object transaction(Object input) { this.bal = BALANCE + (int)input; return bal; } public String toString() { return "Savings acc"; } } public class Account { public static void payment(Transaction t, Object input) { System.out.println(t + " is debited: " + t.transaction(input)); } public static void deposit(Transaction t, Object input) { System.out.println(t + " is credited: " + t.transaction(input)); } public static void main(String[] args) { Integer input = new Integer(600); deposit(new SavingsAccount(), input); payment(new CurrentAccount(), input); } }
代碼輸出:
$javac Account.java $java Account Savings acc is credited: 1100 Current acc is debited: -100
一個接口能夠供多個類共同使用,而且多個類之間使用不衝突,這樣看來,interface倒有點像是靜態函數了。
觀察一下這兩個實現類活期帳戶和儲蓄帳戶自動的向上轉型在接受Transaction接口Account類中的方法。
payment()和deposit()方法利用咱們所講的戰略設計模式,表明了接口的實現徹底脫鉤的一個實例。
從理論上說,你能夠適應任何類,只需使它們符合的界面,使用這些方法。
對於接口與容器,我見過的一個更具備實用價值的地方,在於類之間的監聽函數調用。
相似於js中的事件驅動函數,當有事件發生時候,經過回調函數,通知主函數。
實例代碼以下,文件命名爲Homeway.java:
public class Homeway { public static void main(String[] args) { System.out.println("\n=======================Implements======================\n"); ClassImplements mClassImplements = new ClassImplements(); mClassImplements.run(); } } class ClassImplements implements Implements1.Listener { public Implements1 mImplements1 = null; public ClassImplements(){ mImplements1 = new Implements1(); mImplements1.setListener(this); } @Override public void onCallStart(){ System.out.println("ClassImplements => onCallStart()"); } @Override public void onCallStop(){ System.out.println("ClassImplements => onCallStop()"); } public void run(){ mImplements1.run(); } } //test 2level implements for class class Implements1 implements Implements2.Listener { private Listener mListener; private Implements2 mImplements2; public Implements1(){ mImplements2 = new Implements2();//把當前類傳給下個類 mImplements2.setListener(this); System.out.println("Init Implements1 =>..."); } public static interface Listener { void onCallStart(); void onCallStop(); } public void setListener(Listener listener) { mListener = listener; } @Override public void onCallStart(){ System.out.println("Implements1 => onCallStart()"); mListener.onCallStart();//call at Implements1 and then throw to ClassImplements } @Override public void onCallStop(){ System.out.println("Implements1 => onCallStop()"); mListener.onCallStop();//call at Implements1 and then throw to ClassImplements } public void run(){ this.mImplements2.run(); } } //3 level implement test class Implements2{ private Listener mListener; public Implements2(){ System.out.println("Init Implements2 =>..."); } public static interface Listener { void onCallStart(); void onCallStop(); } public void setListener(Listener listener) { mListener = listener; } public void onCallStart(){ System.out.println("Implements2 => onCallStart()"); } public void onCallStop(){ System.out.println("Implements2 => onCallStop()"); } public void run() { System.out.println("Run some functions and then callback from Listener..."); mListener.onCallStart(); mListener.onCallStop(); } }
輸出以下:
$javac Homeway.java $java Homeway =======================Implements====================== Init Implements2 =>... Init Implements1 =>... Run some functions and then callback from Listener... Implements1 => onCallStart() ClassImplements => onCallStart() Implements1 => onCallStop() ClassImplements => onCallStop()
咱們先是聲明瞭類ClassImplements,這個是咱們的主類,而且implements了Implements1.Listener
經過一個Listener創建了監聽接口,
而後Implements1
又implements了Implements2.Listener
創建了第2級的監聽。
一旦Implements1
或Implements2
內的某個函數觸發了某個事件,就能經過監聽接口發送給主函數ClassImplements
,相似js中的事件回調函數。
父類與子類經過Listener實現接口調用,此時Listener即爲父類自己。
大體的模型以下:
implements容器與interface接口在java類中有不少很好用的模型,有時間該多去研究研究。