java接口的理解

最開始接觸java接口時(shí)候焕刮,有個(gè)疑問『例如我定義了一個(gè)接口涎嚼,但是我在繼承這個(gè)接口的類中還要寫接口的實(shí)現(xiàn)方法,那我不如直接就在這個(gè)類中寫實(shí)現(xiàn)方法豈不是更便捷模捂,還省去了定義接口?』蜘矢。
Object-C類似與 interface的特性叫 protocol即協(xié)議狂男,意思更加明確。遵守協(xié)議就必須實(shí)現(xiàn)協(xié)議品腹。

一.基礎(chǔ)知識

接口(英文:Interface)岖食,在JAVA編程語言中是一個(gè)抽象類型,是抽象方法的集合舞吭,接口通常以interface來聲明泡垃。一個(gè)類通過繼承接口的方式,從而來繼承接口的抽象方法羡鸥。
接口并不是類蔑穴,編寫接口的方式和類很相似,但是它們屬于不同的概念惧浴。類描述對象的屬性和方法存和。接口則包含類要實(shí)現(xiàn)的方法。
除非實(shí)現(xiàn)接口的類是抽象類衷旅,否則該類要定義接口中的所有方法捐腿。
接口無法被實(shí)例化,但是可以被實(shí)現(xiàn)柿顶。一個(gè)實(shí)現(xiàn)接口的類茄袖,必須實(shí)現(xiàn)接口內(nèi)所描述的所有方法,否則就必須聲明為抽象類嘁锯。另外宪祥,在 Java 中,接口類型可用來聲明一個(gè)變量家乘,他們可以成為一個(gè)空指針品山,或是被綁定在一個(gè)以此接口實(shí)現(xiàn)的對象。

1.接口與類相似點(diǎn):

一個(gè)接口可以有多個(gè)方法烤低。
接口文件保存在 .java 結(jié)尾的文件中,文件名使用接口名笆载。
接口的字節(jié)碼文件保存在 .class 結(jié)尾的文件中扑馁。
接口相應(yīng)的字節(jié)碼文件必須在與包名稱相匹配的目錄結(jié)構(gòu)中涯呻。

2.接口與類的區(qū)別:

接口不能用于實(shí)例化對象。
接口沒有構(gòu)造方法腻要。
接口中所有的方法必須是抽象方法复罐。
接口不能包含成員變量,除了 static 和 final 變量雄家。
接口不是被類繼承了效诅,而是要被類實(shí)現(xiàn)。
接口支持多重繼承趟济。

3.接口特性:

接口中每一個(gè)方法也是隱式抽象的,接口中的方法會被隱式的指定為 public abstract(只能是 public abstract乱投,其他修飾符都會報(bào)錯(cuò))。
接口中可以含有變量顷编,但是接口中的變量會被隱式的指定為 public static final 變量(并且只能是 public戚炫,用 private 修飾會報(bào)編譯錯(cuò)誤。
接口中的方法是不能在接口中實(shí)現(xiàn)的媳纬,只能由實(shí)現(xiàn)接口的類來實(shí)現(xiàn)接口中的方法双肤。

4.抽象類和接口的區(qū)別:

  1. 抽象類中的方法可以有方法體,就是能實(shí)現(xiàn)方法的具體功能钮惠,但是接口中的方法不行茅糜。
  2. 抽象類中的成員變量可以是各種類型的,而接口中的成員變量只能是 public static final 類型的素挽。
  3. 接口中不能含有靜態(tài)代碼塊以及靜態(tài)方法(用 static 修飾的方法)蔑赘,而抽象類是可以有靜態(tài)代碼塊和靜態(tài)方法。
  4. 一個(gè)類只能繼承一個(gè)抽象類毁菱,而一個(gè)類卻可以實(shí)現(xiàn)多個(gè)接口米死。

二.個(gè)人理解

接口是一種規(guī)范,是一種統(tǒng)一的標(biāo)準(zhǔn)贮庞。
統(tǒng)一標(biāo)準(zhǔn)的目的峦筒,是大家都知道這個(gè)是做什么的,但是具體不用知道具體怎么做窗慎。比如說:我知道 Comparable 這個(gè)接口是用來比較兩個(gè)對象的物喷,那么如何去比較呢?數(shù)字有數(shù)字的比較方法遮斥,字符串有字符串的比較方法峦失,學(xué)生(自己定義的類)也有自己的比較方法。然后术吗,在另外一個(gè)負(fù)責(zé)對象排序(不一定是數(shù)字喔)的代碼里面尉辑,肯定需要將兩個(gè)對象比較。
這兩個(gè)對象是什么類型呢较屿?Object a,b隧魄?肯定不行卓练,a > b 這樣的語法無法通過編譯。int a,b购啄?也不行襟企?一開始就說了,不一定是數(shù)字狮含。....所以顽悼,Comparable 就來了。他告訴編譯器几迄,a b 兩個(gè)對象都滿足 Comparable 接口蔚龙,也就是他們是可以進(jìn)行比較的。具體怎么比較乓旗,這段程序不需要知道府蛇。所以,他需要一些具體的實(shí)現(xiàn)屿愚,Comparable 接口有一個(gè)方法汇跨,叫 compareTo。那么這個(gè)方法就是用來取代 <妆距、> 這樣的運(yùn)算符穷遂。因?yàn)檫\(yùn)算符是編譯器保留給內(nèi)置類型(整數(shù)、浮點(diǎn)數(shù))進(jìn)行比較用的娱据,而不是一個(gè)廣義的比較運(yùn)算蚪黑。如果你可以明白 JDK 自身庫里面諸如 Comparable 這樣已經(jīng)有的接口,那么就很容易理解自己在開發(fā)程序的時(shí)候?yàn)槭裁葱枰玫浇涌诹恕?/p>

接口是一種規(guī)范中剩,適合多人合作開發(fā)忌穿。當(dāng)你需要調(diào)用別人的代碼時(shí)候,可以規(guī)定好接口结啼。別人看到你的接口就知道該實(shí)現(xiàn)哪些內(nèi)容了掠剑。我寫個(gè)接口,再把調(diào)用函數(shù)寫好郊愧,你把接口實(shí)現(xiàn)了朴译,傳個(gè)實(shí)例進(jìn)來,任務(wù)就完成了属铁,雙方的工作都不會收到影響眠寿。interface在OC里面叫做protocol,即協(xié)議的意思焦蘑。實(shí)現(xiàn)了這個(gè)接口盯拱,代表完成接口規(guī)定的任務(wù)。A需要一些能做某些事情的東西,于是A要求坟乾,必須實(shí)現(xiàn)了xx接口迹辐,才能被我調(diào)用。實(shí)際上也就是個(gè)“規(guī)范”甚侣。

比如發(fā)送短信業(yè)務(wù)。一般發(fā)送短信的場景包括注冊用戶间学,找回密碼殷费,重要通知,修改交易密碼等低葫。短信現(xiàn)在的結(jié)構(gòu)是先接上各家短信通道公司详羡,再經(jīng)由聯(lián)通移動等發(fā)送出去。一般公司備用多個(gè)短信通道嘿悬。我們想要實(shí)現(xiàn)在更換短信通道方的時(shí)候实柠,不更改其他模塊中被引入的代碼?接口就能完美的實(shí)現(xiàn)了這一點(diǎn)善涨。在開始我們要規(guī)定好接口窒盐,每個(gè)短信通道都實(shí)現(xiàn)這些接口。對于我們上層我們不需要管各個(gè)通道是如何實(shí)現(xiàn)的钢拧,只需要在用到這個(gè)業(yè)務(wù)時(shí)候調(diào)用這個(gè)接口就可以了蟹漓。

3.為什么@Autowired使用在interface上而不是實(shí)現(xiàn)類上?
Firstly, it is always a good practice to code to interfaces in general. Secondly, in case of spring, you can inject any implementation at runtime. A typical use case is to inject mock implementation during testing stage.
首先源内,一般使用接口是很常用并且有益的變成技術(shù)葡粒。其次,在spring中膜钓,你可以在運(yùn)行過程中注入各種實(shí)現(xiàn)嗽交。一個(gè)很經(jīng)典的情況就是在測試階段,注入模擬的實(shí)現(xiàn)類颂斜。

如果你是一個(gè)有了那么點(diǎn)經(jīng)驗(yàn)的程序員夫壁,如果你還沒有習(xí)慣TDD的開發(fā)》傧剩可以體驗(yàn)一下這種寫法掌唾。還是拿短信為例。先寫一個(gè)SMSServiceTest忿磅。然后寫一個(gè)Test方法糯彬。 這個(gè)時(shí)候什么都沒有,不用管葱她。先直接這么寫撩扒。int code=SMSSevice.sendTextMessage(mobile,content,type);這個(gè)時(shí)候IDE會提示你沒有這個(gè)SMSService,用代碼自動生成工具去創(chuàng)建這么一個(gè)接口出來。再根據(jù)提示把方法創(chuàng)建出來搓谆。再寫 SMSService smsService=new SMSServiceCorpaImpl();再根據(jù)代碼把實(shí)現(xiàn)類生成了炒辉。一般來說IDE會自動留一個(gè)空的方法。不用管泉手。這里只是一個(gè)簡單的例子黔寇,但是你發(fā)現(xiàn),當(dāng)你用TDD的這種方式去寫代碼的時(shí)候斩萌,完全不用關(guān)系SMSService是怎么內(nèi)部實(shí)現(xiàn)的缝裤。你只需要繼續(xù)寫你的單元測試代碼好了,明確的知道這個(gè)SMSService要做的功能是發(fā)送短信颊郎,需要傳遞手機(jī)號憋飞,內(nèi)容,類型姆吭,返回一個(gè)狀態(tài)碼榛做。那么接著說為什么對單元測試很方便?一般而言會用Spring配置Bean内狸,所以實(shí)際上你的單元測試代碼也不用有改動检眯,無論是測試哪一個(gè)實(shí)現(xiàn)類,都只通過更改配置文件就可以完成答倡。想想轰传,如果沒有接口呢?是不是要對每一個(gè)短信通道單獨(dú)寫一個(gè)單元測試的方法瘪撇?

3.對于不需要頻繁更變實(shí)現(xiàn)類的方法获茬,是不是就可以不用寫接口了?答案是No倔既。整個(gè)系統(tǒng)架構(gòu)的代碼可以單純認(rèn)為有四部分構(gòu)成恕曲。Model+Interface+Service+UtilModel是純粹的Pojo,貧血模型渤涌,Inteface和Service是接口和實(shí)現(xiàn)分開的佩谣,Util是全項(xiàng)目通用,或者是跨項(xiàng)目通用的实蓬,跟業(yè)務(wù)邏輯沒有任何關(guān)系的茸俭。寫接口最大的好處就是在你寫的Controller代碼,或者是Service里的主要業(yè)務(wù)邏輯代碼的時(shí)候安皱,屏蔽掉細(xì)節(jié)调鬓。寫一個(gè)業(yè)務(wù)邏輯的時(shí)候,比如說修真院的加入班級酌伊。第一步腾窝,做校驗(yàn),用戶是否為空,班級是否不存在虹脯,是否已經(jīng)加入了班級等等驴娃。第二步,更新班級和用戶的關(guān)系表循集,更新班級總?cè)藬?shù)唇敞,更新職業(yè)總?cè)藬?shù),更新用戶的最新班級ID暇榴。第三步厚棵,發(fā)送系統(tǒng)通知,告知用戶加入班級成功蔼紧。如果說不用接口,只用實(shí)現(xiàn)類的話狠轻,第一種方式就是把所有的代碼都寫在這個(gè)Controller里去奸例,代碼會非常非常繁瑣,一個(gè)函數(shù)突破幾千行輕輕松松向楼,而且改動起來很麻煩查吊。第二種方式就是抽象出來函數(shù)。這種方式在某種程度上能夠解決代碼塊大的問題湖蜕,但是你必須要New一個(gè)實(shí)現(xiàn)類出來逻卖,想想在上述邏輯中,需要new幾個(gè)實(shí)現(xiàn)類昭抒?這些實(shí)現(xiàn)類就會被New的各處都是评也,甚至改個(gè)名字都很蛋疼。但是如果你使用接口的話灭返,你會發(fā)現(xiàn)盗迟,接口是強(qiáng)制于你去將復(fù)雜的業(yè)務(wù)邏輯抽象成具體做的事兒。比如說熙含,if(user==null){ // to do something}就變成了CheckUser(uid)這么一個(gè)接口罚缕。實(shí)現(xiàn)類也明確了自已要做的事情。從某種程度上來說怎静,抽象成一個(gè)私有方法也能解決這個(gè)問題邮弹,但是一般都會推薦,如果你發(fā)現(xiàn)你寫了很多私有方法蚓聘,要么是他們可以繼續(xù)演化成一個(gè)util腌乡,要么是可以成為一個(gè)Service。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末或粮,一起剝皮案震驚了整個(gè)濱河市导饲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖渣锦,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件硝岗,死亡現(xiàn)場離奇詭異,居然都是意外死亡袋毙,警方通過查閱死者的電腦和手機(jī)型檀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來听盖,“玉大人胀溺,你說我怎么就攤上這事〗钥矗” “怎么了仓坞?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長腰吟。 經(jīng)常有香客問我无埃,道長,這世上最難降的妖魔是什么毛雇? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任嫉称,我火速辦了婚禮,結(jié)果婚禮上灵疮,老公的妹妹穿的比我還像新娘织阅。我一直安慰自己,他們只是感情好震捣,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布荔棉。 她就那樣靜靜地躺著,像睡著了一般伍派。 火紅的嫁衣襯著肌膚如雪江耀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天诉植,我揣著相機(jī)與錄音祥国,去河邊找鬼。 笑死晾腔,一個(gè)胖子當(dāng)著我的面吹牛舌稀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播灼擂,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼壁查,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了剔应?” 一聲冷哼從身側(cè)響起睡腿,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤语御,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后席怪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體应闯,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年挂捻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了碉纺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,852評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡刻撒,死狀恐怖骨田,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情声怔,我是刑警寧澤态贤,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站醋火,受9級特大地震影響抵卫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜胎撇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望殖氏。 院中可真熱鬧晚树,春花似錦、人聲如沸雅采。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽婚瓜。三九已至宝鼓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間巴刻,已是汗流浹背愚铡。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留胡陪,地道東北人沥寥。 一個(gè)月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像柠座,于是被迫代替她去往敵國和親邑雅。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 從三月份找實(shí)習(xí)到現(xiàn)在妈经,面了一些公司淮野,掛了不少捧书,但最終還是拿到小米、百度骤星、阿里经瓷、京東、新浪妈踊、CVTE了嚎、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,278評論 11 349
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法廊营,內(nèi)部類的語法歪泳,繼承相關(guān)的語法,異常的語法露筒,線程的語...
    子非魚_t_閱讀 31,665評論 18 399
  • (一)Java部分 1呐伞、列舉出JAVA中6個(gè)比較常用的包【天威誠信面試題】 【參考答案】 java.lang;ja...
    獨(dú)云閱讀 7,118評論 0 62
  • 有沒有人說過你變了蕾盯?不慌回答!大橙子我...
    隨風(fēng)飄揚(yáng)灬閱讀 165評論 0 0
  • 從二樓小餐廳走出來蓝丙。级遭。。余光看到了和你很像的男生渺尘,沒有正眼看挫鸽,說不出來哪里像,嗯~就是他給我的感覺鸥跟。丢郊。。和你給我的...
    生來癡狂閱讀 89評論 0 0