接口interface
本章目標:
- 什麼是接口?
- 什麼時候使用接口?
- 接口怎麼使用?
- 3.1 定義格式
3.2 基本實現
3.3 接口中的常量
3.4 接口的多實現3
3.5 接口的多繼承
3.6 其他成員特點 - 接口作為一種約定和能力的含義
- 總結 具體講解: 接口的概念在現實生活中使用得很多,例如:計算機上提供的USB接口,專門供USB設置使用,如U盤、USB風扇、USB鼠標等等。計算機通過提供統一的USB接口來接高通用性,使計算機不再需要同時具備U盤專用接口、鼠標專用接口、鍵盤專用接口等。以USB接口為例,它提供統一的設計規範,使得遵守這個規範的鼠標、鍵盤、風扇、移動硬盤等都可以插在USB上使用。那麼接口到底是什麼呢?
`
7. 1. 什麼是接口?
接口(硬件類接口)是指同一計算機不同功能層之間的通信規則稱為接口。如下圖: 接口(軟件類接口)是指對協議進行定義的引用類型。也可以説軟件中的接口軟件之間的一種規約、規範。大家按照接口中的規約或規範進行操作,就能實現相互訪問。我們通常的見的API——應用程序編程接口,就是軟件類接口,也是一種發展趨勢。
1.1. Java中的接口Java語言中的接口是方法的集合,是一種引用類型,是一套規範。 如果説類的內部封裝了成員變量、構造方法和成員方法,那麼接口的內部主要就是封裝了方法,包含抽象方法(JDK 7及以前)、默認方法和靜態方法(JDK 8)、私有方法(JDK 9)。 接口也會被編譯成.class文件,但要一定要明確接口並不是類,而是另外一種引用數據類型。(引用數據類型:數組,類,接口) 接口不能創建對象,但是可以被實現(implements,類似於被繼承)。一個實現接口的類(可以看做是接口的子類),需要實現接口中所有的抽象方法,創建該類對象,就可以調用方法了,否則它必須���一個抽象類。
1.2. 接口的規範由誰來實現?
顯示接口的規範是由實現這個接口的具體類來實現的。例如,使用計算機的USB接口的是那些實現USB接口規範的產品,如U盤、USB鼠標等,這些具體產品會實現如何傳輸數據。
2.為什麼使用接口?
在系統開發中,系統的各種功能是由許許多多的不同對象協作完成的。在這種情況下,各個對象內部是如何實現的,對系統設計人員來講就不那麼重要了;而各個對象之間的協作關係則成為系統設計的關鍵。面向接口編程就是指按照這種思想來編程。實際上,在日常工作中,你已經按照接口編程了,只不過如果你沒有這方面的意識,那麼你只是在被動的實現這一思想;表現在頻繁的抱怨別人改的代碼影響了你(接口沒有設計到),表現在某個模塊的改動引起其他模塊的大規模調整(模塊接口沒有很好的設計)等等。
前面學過抽象類,抽象類一般做為父類使用,但父類的資源是相當寶貴的,而類又不能多繼承,因此如果一個類有兩個父類,這個時候繼承的缺點就非常明顯了。
l 父類只能繼承一個,而接口可以實現多個,接口用來彌補不支持多繼承的缺點。
l 可對外提供規則或規範。
l 提高系統的可擴展性、重用性、可維護性。l 提高系統的耦合,通過接口來解耦。
3. 接口怎麼使用?
3.1. 定義格式接口的定義,它與定義類方式相似,但是使用interface關鍵字。如下
:publicinterface接口名稱{
//抽象方法
//默認方法
//靜態方法
//私有方法}
(1)含有抽象方法抽象方法:使用abstract關鍵字修飾,可以省略,沒有方法體。該方法主要供子類實現使用。如下代碼:
publicinterfaceInterFaceName {
public abstract void method();
//abstract可省略
}
(2)含有默認方法和靜態方法默認方法:使用default修飾,不可省略,供子類調用或者子類重寫。靜態方法:使用static修飾,供接口直接調用。如下代碼
:publicinterfaceInterFaceName {
publicdefaultvoid method1() {
//執行語句
}
publicstaticvoid method2() {
//執行語句 }
}
(3)含有私有方法和私有靜態方法私有方法:使用private修飾,供接口中的默認方法或者靜態方法調用。
如下代碼:publicinterface InterFaceName { private void method3() { //執行語句 }}
3.2. 基本實現類與接口的關係為實現關係,即類實現接口,該類可以稱為接口的實現類,也可以稱為接口的子類。實現類似於繼承,格式相仿,只是關鍵字不同,實現使用implements關鍵字。類與類之間的關係:繼承關係接口與接口之間的關係:繼承關係 非抽象子類實現接口:l 必須重寫接口中所有抽象方法。l 繼承了接口的默認方法,即可以直接調用,也可以重寫。
3.2.1. 實現的格式class類名implements接口名 { //重寫接口中抽象方法【必須】 //重寫接口中默認方法【可選】}
3.2.2. 抽象方法的使用接口的抽象方法,子類必須全部實現,
代碼如下:定義接口:public interfaceLiveAble{ //定義抽象方法 public abstract void eat(); public abstract void sleep();}
定義實現類:public classAnimalimplementsLiveAble{ @Override public void eat() { System.out.println("吃東西"); } @Override public void sleep() { System.out.println("晚上睡"); }}
定義測試類:public classInterfaceDemo{ public static void main(String[] args) { //創建子類對象 Animal a = new Animal(); //調用實現後的方法 a.eat(); a.sleep(); }}輸出結果: 吃東西 晚上睡
3.2.3. 默認方法的使用接口中的默認方法,子類可以繼承,可以重寫,二選一,但是隻能通過實現類的對象來調用。 A. 繼承默認方法,
代碼如下:定義接口:public interfaceLiveAble{ public default void fly(){ System.out.println("天上飛"); }} 定義實現類:public classAnimalimplementsLiveAble{ //繼承了接口中的默認方法,什麼都不用寫,直接調用} 定義測試類:public classInterfaceDemo{ public static void main(String[] args) { //創建子類對象 Animal a = new Animal(); //調用默認方法 a.fly(); }}輸出結果: 天上飛 B. 重寫默認方法,
代碼如下:定義接口:public interfaceLiveAble{ public default void fly(){ System.out.println("天上飛"); }} 定義實現類:public classAnimalimplementsLiveAble{ @Override public void fly() { System.out.println("自由自在的飛"); }} 定義測試類:public classInterfaceDemo{ public static void main(String[] args) { //創建子類對象 Animal a = new Animal(); //調用重寫方法 a.fly(); }}輸出結果: 自由自在的飛
3.2.4. 靜態方法的使用靜態與.class文件相關,只能使用接口名調用,不可以通過實現類的類名或者實現類的對象調用,
代碼如下:定義接口:public interfaceLiveAble{ public static void run(){ System.out.println("跑起來~~~"); }} 定義實現類:public classAnimalimplementsLiveAble{ //無法重寫靜態方法} 定義測試類:public classInterfaceDemo{ public static void main(String[] args) { // Animal.run(); //【錯誤】無法繼承方法,也無法調用 LiveAble.run(); }}輸出結果: 跑起來~~~
3.2.5. 私有方法的使用私有方法:只有默認方法可以調用。私有靜態方法:默認方法和靜態方法可以調用。如果一個接口中有多個默認方法,並且方法中有重複的內容,那麼可以抽取出來,封裝到私有方法中,供默認方法去調用。從設計的角度講,私有的方法是對默認方法和靜態方法的輔助。同學們在已學技術的基礎上,可以自行測試
。定義接口:public interfaceLiveAble{ default void func(){ func1(); func2(); } private void func1(){ System.out.println("跑起來~~~"); } private void func2(){ System.out.println("跑起來~~~"); } }
3.3. 接口中的常量接口還可以定義變量,只不過這些變量默認是用public static final修飾的,變量值也不能改變,這種變量也稱為常量。示例代碼如下:public class MathConstant{double PI = 3.1415926; //定義數學上的PI常量
}
3.4. 接口的多實現前面學過,在繼承體系中,一個類只能繼承一個父類。而對於接口而言,一個類是可以實現多個接口的,這叫做接口的多實現。並且,一個類能繼承一個父類,同時實現多個接口。
3.4.1. 多實現的格式class類名[extends父類名]implements接口名1,接口名2,接口名
3... { //重寫接口中抽象方法【必須】 //重寫接口中默認方法【不重名時可選】}説明:[ ]: 表示可選操作。
3.4.2. 抽象方法接口中,有多個抽象方法時,實現類必須重寫所有抽象方法。如果抽象方法有重名的,只需要重寫一次。代碼如下:定義多個接口:interfaceA{ public abstract void showA(); public abstract void show();}interfaceB{ public abstract void showB(); public abstract void show();} 定義實現類:public classC implements A,B{ @Override public void showA() { System.out.println("showA"); } @Override public void showB() { System.out.println("showB"); } @Override public void show() { System.out.println("show"); }}
3.4.3. 默認方法接口中,有多個默認方法時,實現類都可繼承使用。如果默認方法有重名的,必須重寫一次。代碼如下:定義多個接口:interfaceA { public default void methodA(){} public default void method(){}}interfaceB { public default void methodB(){} public default void method(){}} 定義實現類:public classC implementsA,B{ @Override public void method() { System.out.println("method"); }}
3.4.4. 靜態方法接口中,存在同名的靜態方法並不會衝突,原因是隻能通過各自接口名訪問靜態方法。 優先級的問題:當一個類繼承一個父類,又實現若干個接口時,父類中的成員方法與接口中的默認方法重名,子類就近選擇執行父類的成員方法。代碼如下:定義接口:interfaceA { public default voidmethodA(){ System.out.println("AAAAAAAAAAAA"); }}定義父類:classD { public voidmethodA(){ System.out.println("DDDDDDDDDDDD"); }}定義子類:classC extendsD implementsA { //未重寫methodA方法} 定義測試類:public classTest{ public static void main(String[] args) { C c = new C(); c.methodA(); }}輸出結果: DDDDDDDDDDDD 3.5. 接口的多繼承一個接口能繼承另一個或者多個接口,這和類之間的繼承比較相似。接口的繼承使用extends關鍵字,子接口繼承父接口的方法。如果父接口中的默認方法有重名的,那麼子接口需要重寫一次。代碼如下:定義父接口:interfaceA{ public default void method(){ System.out.println("AAAAAAAAAAAAAAAAAAA"); }}interfaceB { public default void method(){ System.out.println("BBBBBBBBBBBBBBBBBBB"); }} 定義子接口:interfaceD extendsA,B{ @Override public default void method() { System.out.println("DDDDDDDDDDDDDD"); }}小貼士:子接口重寫默認方法時,default關鍵字可以保留。子類重寫默認方法時,default關鍵字不可以保留。
3.6. 接口的其他特點l 接口中,無法定義成員變量,但是可以定義常量,其值不可以改變,默認使用public static final修飾。l 接口中,沒有構造方法,不能創建對象。l 接口中,沒有靜態代碼塊。4. 接口作為一種約定和能力的含義生活中,我們使用的電源插座,規定了:l 兩個接頭間的額定電壓l 兩個接頭間的距離l 接頭的形狀接口是一種約定,體現在接口名稱和註釋上。有些接口只有名字,沒有任何方法;方法的實現方式要通過註釋來約定。面向接口編程,程序設計時面向接口的約定,而不考慮具體的實現。 5. 總結
(1)接口是用關鍵字interface定義的。
(2)接口中包含的成員,最常見的有全局常量、抽象方法。注意:接口中的成員都有固定的修飾符。 成員變量:public static final 成員方法:public abstractinterface Inter{ public static final int x = 3; public abstract void show();}
(3)接口中有抽象方法,説明接口不可以實例化。接口的子類必須實現了接口中所有的抽象方法後,該子類才可以實例化。否則,該子類還是一個抽象類。
(4)類與類之間存在着繼承關係,類與接口中間存在的是實現關係。接口與接口之間存在繼承關係繼承用extends ;實現用implements ;
(5)接口和類不一樣的地方,就是接口可以被多實現,這就是多繼承改良後的結果。java將多繼承機制通過多現實來體現。
(6)一個類在繼承另一個類的同時,還可以實現多個接口。所以接口的出現避免了單繼承的侷限性。還可以將類進行功能的擴展。
(7)其實Java中是有多繼承的。接口與接口之間存在着繼承關係,接口可以多繼承接口。
(8)抽象類與接口:���象類:一般用於描述一個體系單元,將一組共性內容進行抽取,特點:可以在類中定義抽象內容讓子類實現,可以定義非抽象內容讓子類直接使用。它裏面定義的都是一些體系中的基本內容。接口:一般用於定義對象的擴展功能,是在繼承之外還需這個對象具備的一些功能。
(9)抽象類和接口的區別:抽象類和接口的共性:都是不斷向上抽取的結果。
1:抽象類只能被繼承,而且只能單繼承。接口需要被實現,而且可以多實現。
2:抽象類中可以定義非抽象方法,子類可以直接繼承使用。接口中都有抽象方法,需要子類去實現。
3:抽象類使用的是 is a 關係。接口使用的like a 關係
。4:抽象類的成員修飾符可以自定義。接口中的成員修飾符是固定的。全都是public的。 在實際開發之前,應先定義規則,A和B分別開發,A負責實現這個規則,B負責使用這個規則。至於A是如何對規則具體實現的,B是不需要知道的。這樣這個接口的出現就降低了A和B直接耦合性。
本文章為轉載內容,我們尊重原作者對文章享有的著作權。如有內容錯誤或侵權問題,歡迎原作者聯繫我們進行內容更正或刪除文章。