1.完全解耦
- 一個方法 void next(Processor p),如果p僅僅是一個父類 或抽象類的話,那傳入這個方法的p只能是繼承暈Processor的子類或Processor類,
其他的類則不能傳入,而如果是Processor是一個接口的話,那傳入其中的類只要實現這個接口就可以啦,這個類就可以留出空間去繼承其他
的類了,也可以去實現其他接口,這個方法的耦合性就低了很多。 - 讓方法接受接口類型,是一種讓任何類對該方法進行適配的方式,只要這個類implement這個接口。
2.java中的多重繼承
- java是單繼承語言,但可以通過藉口的方式實現多重繼承。
因爲接口根本沒有任何具體實現,也就是說沒有任何與接口相關的存儲, - 實現接口和繼承的不同之處,
繼承 子類需要在構造方法中先調用父類構造方法完成父類的初始化,因爲子類中可能有依賴父類的方法。
接口不用,因爲子類一點點都沒有依賴所實現的接口,這也是接口爲什麼能實現多重繼承的一個原因。 interface CanFight{ void fight(); } interface CanSwim{ void swim(); } interface CanFly{ void fly(); } class ActionCharacter{ public void fight(){} } class Hero extends ActionCharacter implements CanFight,CanFly,CanSwim{ public void swim() {} public void fly() {} /** * 下面這句代碼註釋掉也沒關係,雖然我們implement了CanFight,但因爲父類中有這個方法,所以不需要實現。 * 即使沒有顯示的定義fight()方法,其定義也會隨着父類而來 */ // public void fight(){} } public class Adventure { }
- 當使用Hero時,他會被以此向上轉型爲相應的接口類型。
3.通過繼承來擴展接口(接口繼承接口)
- 接口繼承接口,可以實現接口的擴展。
- 當一個類實現了一個繼承接口的接口的時候,那這個類必須實現所有接口的方法
另外接口繼承接口也用extends關鍵字,但extends後面可以跟多個接口,用逗號隔開。interface CanDos extends CanFly,CanSwim{ void dos(); } class ActionCharacter implements CanDos{ public void fight(){} public void fly() {} public void swim() {} public void dos() {} }
4.組合接口時的方法名字的衝突
- 當打算組合的接口中使用相同的名字會造成代碼的可讀性的混亂,雖然運行不會出什麼問題,儘量避免這種情況。
interface I1{ void f(); } interface I2{ void f(); } interface I3 extends I2{ void f(); } class C1 implements I3,I2{ public void f() {} } public class Test extends C1{ public void f() {System.out.println("呵呵");} public static void main(String[] args) { C1 i = new Test(); i.f(); } }
5.接口相當於枚舉
- 因爲在接口中的域都是final、static和public的(public final static int i = 0;),所以在java沒有枚舉之前接口可以當作其來達到相同的作用。
因爲接口中的域都是final的所以必須對它們初始化。interface RandVal{ Random RAND = new Random(47); int RANDOM_INT = RAND.nextInt(10); long RANDOM_LONG = RAND.nextInt()*10; } public class TestRandVals { public static void main(String[] args) { System.out.println(RandVal.RANDOM_INT); System.out.println(RandVal.RANDOM_LONG); } }
- 這些域不是接口的一部分,他們的值存儲在該接口的靜態存儲區域內。
6.嵌套接口
- 接口可以嵌套在類或其他接口中。
上面的代碼有一處特出的情況,就是接口在類內部被聲明爲private修飾的時候。class A{ interface B{ void f(); } public class BImp implements B{ public void f() {} } private class BImp2 implements B{ public void f() {} } //private類型的 private interface D{ void f(); } private class DImp implements D{ public void f() {} } public class DImp2 implements D{ public void f() {} } } interface E{ interface G{ void f(); } public interface H{ void f(); } void g(); } public class NestingInterfaces { }
這只是一種方法,因爲是private的,它會強制不允許向上轉型。- 當實現某個接口時,並不需要實現嵌套在其內部的任何接口,繼承類也一樣。
7.接口和工廠
- 可以通過接口實現工廠模式,使用工廠對戲那個生成接口的某個實現對象。使用設計模式應該考慮到自身的情況,選擇適合的設計模式。
但也有情況是不能使用模式的。
總結:
- 繼承和接口不能濫用,考慮情況而定,可以直接實現類的時候優先實現類。