JAVA基礎——接口(全網最詳細教程)


Java基礎——接口

 

接口概念
官方解釋:Java接口是一系列方法的聲明,是一些方法特征的集合,一個接口只有方法的特征沒有方法的實現,因此這些方法可以在不同的地方被不同的類實現,而這些實現可以具有不同的行為(功能)。

我的解釋:接口可以理解為一種特殊的類,里面全部是由全局常量和公共的抽象方法所組成。接口是解決Java無法使用多繼承的一種手段,但是接口在實際中更多的作用是制定標准的。或者我們可以直接把接口理解為100%的抽象類,既接口中的方法必須全部是抽象方法。(JDK1.8之前可以這樣理解)

 

接口的特點
就像一個類一樣,一個接口也能夠擁有方法和屬性,但是在接口中聲明的方法默認是抽象的。(即只有方法標識符,而沒有方法體)。

 

接口指明了一個類必須要做什么和不能做什么,相當於類的藍圖。
一個接口就是描述一種能力,比如“運動員”也可以作為一個接口,並且任何實現“運動員”接口的類都必須有能力實現奔跑這個動作(或者implement move()方法),所以接口的作用就是告訴類,你要實現我這種接口代表的功能,你就必須實現某些方法,我才能承認你確實擁有該接口代表的某種能力。
如果一個類實現了一個接口中要求的所有的方法,然而沒有提供方法體而僅僅只有方法標識,那么這個類一定是一個抽象類。(必須記住:抽象方法只能存在於抽象類或者接口中,但抽象類中卻能存在非抽象方法,即有方法體的方法。接口是百分之百的抽象類)
一個JAVA庫中接口的例子是:Comparator 接口,這個接口代表了“能夠進行比較”這種能力,任何類只要實現了這個Comparator接口的話,這個類也具備了“比較”這種能力,那么就可以用來進行排序操作了。
為什么要用接口
接口被用來描述一種抽象。
因為Java不像C++一樣支持多繼承,所以Java可以通過實現接口來彌補這個局限。
接口也被用來實現解耦。
接口被用來實現抽象,而抽象類也被用來實現抽象,為什么一定要用接口呢?接口和抽象類之間又有什么區別呢?原因是抽象類內部可能包含非final的變量,但是在接口中存在的變量一定是final,public,static的。

 

 

接口的語法實現
為了聲明一個接口,我們使用interface這個關鍵字,在接口中的所有方法都必須只聲明方法標識,而不要去聲明具體的方法體,因為具體的方法體的實現是由繼承該接口的類來去實現的,因此,接口並不用管具體的實現。接口中的屬性默認為Public Static Final.一個類實現這個接口必須實現這個接口中定義的所有的抽象方法。

一個簡單的接口就像這樣:擁有全局變量和抽象方法。

 

為了實現這個接口,我們使用implements關鍵詞去實現接口:

 

其中testClass類實現了我們上面剛才定義的 in1 這個接口,既然你要實現接口,也就是實現接口代表的一種能力,那么你就必須去實現接口給你規定的方法,只有把接口給你規定的抽象方法都給實現了,才承認你這個類實現了這個接口,實現了這個接口代表的某種功能。上圖實現了接口中規定的display()方法。

 

寫一個測試類,用來測試一下我們剛才實現的這個接口,因為testclass類的對象t實現了接口規定的display方法,那么自然而然就可以調用display()方法咯。

 

有興趣的同學可以去這個在線IDE親自試一試:點擊打開鏈接

 

 

接口的進一步理解

我們知道,如果某個設備需要向電腦中讀取或者寫入某些東西,這些設備一般都是采用USB方式與電腦連接的,我們發現,只要帶有USB功能的設備就可以插入電腦中使用了,那么我們可以認為USB就是一種功能,這種功能能夠做出很多的事情(實現很多的方法),其實USB就可以看做是一種標准,一種接口,只要實現了USB標准的設備我就認為你已經擁有了USB這種功能。(因為你實現了我USB標准中規定的方法),下面是具體的例子:

 

先聲明USB接口:其中規定了要實現USB接口就必須實現接口規定實現的read( )和write( )這兩個方法。

interface USB {
void read();

void write();
}
然后在寫一個U盤類和一個鍵盤類,這兩個類都去實現USB接口。(實現其中的方法)

class YouPan implements USB {
@Override
public void read() {
System.out.println("U盤正在通過USB功能讀取數據");
}
@Override
public void write() {
System.out.println("U盤正在通過USB功能寫入數據");
}
}

 

這是U盤的具體實現。
class JianPan implements USB {
@Override
public void read() {
System.out.println("鍵盤正在通過USB功能讀取數據");
}
@Override
public void write() {
System.out.println("鍵盤正在通過USB功能寫入數據");
}
}

 

這是鍵盤的具體實現。
那么,現在U盤和鍵盤都實現了USB功能,也就是說U盤和鍵盤都能夠調用USB接口中規定的方法,並且他們實現的方式都不一樣。

我們在寫一個測試,來看看具體的實現:

public class Main {
public static void main(String[] args) {
//生成一個實現可USB接口(標准)的U盤對象
YouPan youPan = new YouPan();
//調用U盤的read( )方法讀取數據
youPan.read();
//調用U盤的write( )方法寫入數據
youPan.write();
//生成一個實現可USB接口(標准)的鍵盤對象
JianPan jianPan = new JianPan();
//調用鍵盤的read( )方法讀取數據
jianPan.read();
//調用鍵盤的write( )方法寫入數據
jianPan.write();
}
}

 

結果如下:

 

 

感興趣的同學可以去在線IDE平台自己驗證一下:點擊打開鏈接

 

 

關於接口的幾個重點
我們不能直接去實例化一個接口,因為接口中的方法都是抽象的,是沒有方法體的,這樣怎么可能產生具體的實例呢?但是,我們可以使用接口類型的引用指向一個實現了該接口的對象,並且可以調用這個接口中的方法。因此,上圖中最后的方法調用我們還可以這樣寫:(實際上就是使用了Java中多態的特性)
public class Main {
public static void main(String[] args) {
//生成一個實現可USB接口(標准)的U盤對象
//但是使用一個接口引用指向對象
//USB接口類引用可以指向一個實現了USB接口的對象
USB youPan = new YouPan();
//調用U盤的read( )方法讀取數據
youPan.read();
//調用U盤的write( )方法寫入數據
youPan.write();
//生成一個實現可USB接口(標准)的鍵盤對象
//但是使用一個接口引用指向對象
//USB接口類引用可以指向一個實現了USB接口的對象
USB jianPan = new JianPan();
//調用鍵盤的read( )方法讀取數據
jianPan.read();
//調用鍵盤的write( )方法寫入數據
jianPan.write();
}
}

2.一個類可以實現不止一個接口。

 

3.一個接口可以繼承於另一個接口,或者另一些接口,接口也可以繼承,並且可以多繼承。

4.一個類如果要實現某個接口的話,那么它必須要實現這個接口中的所有方法。

5.接口中所有的方法都是抽象的和public的,所有的屬性都是public,static,final的。

6.接口用來彌補類無法實現多繼承的局限。

7.接口也可以用來實現解耦。

接口的通俗理解

前面我們講多態的時候用“空調”——“遙控器”的方式去理解多態,實際上在上面的的幾個重點中的第一條講的也是多態的實現,比如,我們可以把“節能”作為一種標准,或者說節能就是一個“接口”,這個接口中有一個方法,叫做變頻方法,任何空調,如果要稱得上叫做節能空調的話,那么必須實現“節能”這個接口,實現“節能”這個接口,也就必須實現“節能”接口中規定實現的“變頻”方法,這樣才算是真正的實現了“節能”這個接口,實現了“節能”這個功能。

當某個空調實現了“節能”接口后,這個空調就具備了節能的功能,那么我們也可以不用空調類的引用指向空調對象,我們可以直接使用一個“節能”接口類型引用的“遙控器”去指向“空調”,雖然這個“遙控器”上面只有一個按鍵,只有一個“變頻”的方法,但是“遙控器”所指向的空調是實現了“節能”這個接口的,是有“變頻”方法的實現的,我們用這個只有一個“變頻”方法的遙控器去命令空調調用“變頻”方法,也是行得通的,實在不清楚的同學可以去看我的另一篇文章:JAVA之對象的多態性。

 

 

接口的標識用法
雖然接口內部定義了一些抽象方法,但是並不是所有的接口內部都必須要有方法,比如Seriallizable接口,Seriallizable接口的作用是使對象能夠“序列化”,但是Seriallizable接口中卻沒有任何內容,也就是說,如果有一個類需要實現“序列化”的功能,則這個類必須去實現Seriallizable接口,但是卻並不用實現方法(因為接口中沒有方法),此時,這個Serilizable接口就僅僅是一個“標識”接口,是用來標志一個類的,標志這個類具有這個“序列化”功能。具體的實現請參考我的另一篇文章——JAVA之IO流。

 

接口在生活中的思想體現
其實,在我們的生活當中,有很多地方都體現了“接口”的思想,想必,正在閱讀這篇博文的你,是不是也喜歡攝影呢?

 

玩攝影的童鞋都知道,單反由相機和鏡頭組成,相機分不同的型號,有半畫幅的,也有全畫幅的。鏡頭也是一樣的,分長焦,短焦;還有定焦和變焦。每種鏡頭都有各自特定的發揮場景。正是因為鏡頭的多元化,使得我們的攝影能夠“術業有專攻”。大家想一想,如果我們的單反相機部分和鏡頭部分是固定在一起的,不能夠更換鏡頭,那么將會多么的糟糕啊!

因此,每個相機品牌為了能夠兼容不同的鏡頭,各自發布了一套鏡頭卡口的標准,這套標准就好比我們前面提到的“接口”,都是某種“約束”。舉個栗子,我們佳能的相機,不管你是哪一家鏡頭生產廠商,騰龍也好,適馬也好,只要你按照我佳能卡口的標准來生產鏡頭,你生產的鏡頭都能夠很好的在我佳能相機上面驅動。

 

因此,當我們打開“狗東”,准備給自己的新相機買鏡頭的時候,就不難發現,我們需要根據自己相機的品牌來挑選特定卡口的鏡頭,這樣的鏡頭才能被我們的相機正常驅動。

 

回到Java上面來說,其實接口給我們帶來的最大的好處就是“解耦”了,相機能夠搭配不同的鏡頭,才能有各種各樣的搭配玩法,變得更加的靈活。在軟件系統中也是一樣的,接口可以有很多不同“特色”的實現類,我們只需要聲明同一個接口,卻可以引用很多個該“接口”引申出來的“子類”,這不也大大增強了我們軟件系統中組件的靈活性嗎?

聰明的你,對於“接口”的理解是不是又更加的深入了呢?

 

基礎不牢?新手不友好?無人帶路?關注《揚俊的小屋》公眾號吧!

 



參考資料
1.《Java開發實戰經典》 李興華著 清華大學出版社

2.https://www.geeksforgeeks.org/interfaces-in-java 作者:Mehak Kumar. and Nitsdheerendra. 翻譯:劉揚俊

 

博客文章版權說明
第一條 本博客文章僅代表作者本人的觀點,不保證文章等內容的有效性。

第二條 本博客部分內容轉載於合作站點或摘錄於部分書籍,但都會注明作/譯者和原出處。如有不妥之處,敬請指出。

第三條 在征得本博客作者同意的情況下,本博客的作品允許非盈利性引用,並請注明出處:“作者:____轉載自____”字樣,以尊重作者的勞動成果。版權歸原作/譯者所有。未經允許,嚴禁轉載。

第四條 對非法轉載者,“揚俊的小屋”和作/譯者保留采用法律手段追究的權利。

第五條 本博客之聲明以及其修改權、更新權及最終解釋權均屬“揚俊的小屋”。

第六條 以上聲明的解釋權歸“揚俊的小屋”所有。
————————————————
版權聲明:本文為CSDN博主「劉揚俊」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_19782019/article/details/80259836


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM