曾看過很多形象的比喻,比如買電腦回來要有USB接口礼仗,不能直接把鼠標(biāo)焊在主板上之類的,很生動逻悠,但是對初學(xué)者看完還是一臉“啥元践?你說啥?這到底和接口有什么用的問題有啥關(guān)系童谒?”的表情单旁,所以感覺還是用代碼來舉例比較好。
以下是我在知乎上看到的一個回答饥伊,我個人認(rèn)為很好理解象浑,又形象生動,又有代碼可以參考琅豆。
推薦大家看看原答案愉豺,評論里有一些童鞋提的問題,一起看下來會有更深的理解茫因。我根據(jù)原答案和評論修改了接口蚪拦、類和方法的名稱還有部分描述
- 接口的作用對于很多新手來說很不容易理解,我給大家舉個例子冻押。
- 接口只是一個規(guī)范驰贷,所以里面的方法都是空的。
- 假如我開了一個寵物糧店洛巢,聲明了一個買東西的動作括袒,這就相當(dāng)于一個接口,
/**
* Created by wanggs on 2017/7/7.
*/
public interface BuySomeThing {
public abstract void buy();
}
- 當(dāng)一條狗看到了狼渊,自己要買東西箱熬,所以它去實(shí)現(xiàn)這個接口
/**
* Created by wanggs on 2017/7/7.
*/
public class Dog implements BuySomeThing {
public void buy() {
System.out.println("我是狗类垦,我要買狗糧");
}
}
- 當(dāng)一只貓看到了狈邑,自己要買東西,所以也去實(shí)現(xiàn)這個接口
/**
* Created by wanggs on 2017/7/7.
*/
public class Cat implements BuySomeThing {
public void buy() {
System.out.println("我是貓蚤认,我要買貓糧");
}
}
- 當(dāng)狗和貓來我的店之前米苹,我是不知道他們到底是什么,但是當(dāng)他們來到我的店砰琢,我就知道一個要貓糧糧蘸嘶,一個要狗糧糧良瞧。因?yàn)樗麄兌紝?shí)現(xiàn)了我這個接口,都可以買训唱。下面這個類相當(dāng)于一個接待顧客的類褥蚯,即店小二,他接待所有實(shí)現(xiàn)了我這個寵物店接口的動物况增,傳進(jìn)來一個BuySomeThing類型的寵物赞庶,注意,這個BuySomeThing是接口
/**
* Created by wanggs on 2017/7/7.
*/
public class PetShop {
public void sell(BuySomeThing buySomeThing){
buySomeThing.buy();
}
}
- 好了澳骤,這個時候我這個老板出現(xiàn)了歧强,我可以給他們賣糧食了,相當(dāng)于測試類
public class Tests {
public static void main(String[] args) {
BuySomeThing dog = new Dog();//實(shí)例化一條狗为肮,相當(dāng)于把狗顧客實(shí)例化
BuySomeThing cat = new Cat();//實(shí)例化一只貓摊册,相當(dāng)于把貓顧客實(shí)例化
PetShop petShop = new PetShop();//實(shí)例化一個店小二
petShop.Sell(dog);//把狗交給店小二
petShop.Sell(cat);//把貓交給店小二
}
}
- 這樣運(yùn)行的結(jié)果就是
我是狗,我要買狗糧
我是貓颊艳,我要買貓糧
你知道嗎茅特,整個過程我這個店主其實(shí)根本不知道來的到底是貓是狗還是其他什么,我只要有一個店小二棋枕,把這些來的不知什么動物都全部交給店小二温治,店小二就知道怎么去賣了,因?yàn)檫@些狗啊貓啊都實(shí)現(xiàn)了我這個寵物店的接口戒悠,而店小二就負(fù)責(zé)接待所有實(shí)現(xiàn)了我這個接口的動物熬荆。這就有一個好處,假如明天來了一頭小豬绸狐,只要它實(shí)現(xiàn)了我這個接口卤恳,我只管交給店小二處理就OK了,我這個店小二根本不需要變化寒矿,我這個店主也只需要實(shí)例化一下這個動物就OK
你想突琳,假如沒有接口,會怎么辦符相,來一個貓拆融,我要去創(chuàng)造一個貓,還要實(shí)例化啊终,來一只狗镜豹,我要創(chuàng)建一只狗,同樣要實(shí)例化蓝牲,還要配備專門的店小二去接待趟脂,就會相當(dāng)麻煩
說點(diǎn)自己的感想:小白經(jīng)常認(rèn)為的一點(diǎn)是,既然我要重寫所有方法例衍,我為什么還要用這個接口呢昔期?我同樣也寫這些方法已卸,也用這些參數(shù),不用接口行不行硼一?難道接口只是定義了一些非得讓我重寫不可的方法頭累澡?
其實(shí)不然,接口經(jīng)常用在非個人項(xiàng)目上般贼,得合作永乌,不是一個人寫所有。所以不能只想到你實(shí)現(xiàn)了這個功能具伍,要想到你實(shí)現(xiàn)完之后別人會因?yàn)槟氵@個類實(shí)現(xiàn)了規(guī)定好的接口而可以直接用來做下面的工作翅雏,比如你實(shí)現(xiàn)了buy功能,但是別人不知道啊人芽,但是你實(shí)現(xiàn)了BuySomeThing這個接口望几,別人就知道你肯定實(shí)現(xiàn)了buy這個功能,然后可以直接調(diào)用(參考PetShop這個類)
另外接口也很好的規(guī)范了實(shí)現(xiàn)時的方法名參數(shù)啥的萤厅,避免了漏寫一下方法實(shí)現(xiàn)橄抹,錯寫一些參數(shù)。
最后的最后惕味,我總結(jié)一下接口的作用吧:
多態(tài) 向上轉(zhuǎn)型體現(xiàn)了多態(tài)的思想楼誓,本身接口就是面向?qū)ο笏枷肜矬w現(xiàn)出來的一個特性
規(guī)范 定下了一個方法名傳入?yún)?shù)類型返回值類型的規(guī)范,避免了很多不必要的麻煩
協(xié)議 雙方協(xié)議好名挥,只要實(shí)現(xiàn)預(yù)定好的接口的就能用來實(shí)現(xiàn)后續(xù)的功能疟羹,不關(guān)心實(shí)現(xiàn)接口的類的具體實(shí)現(xiàn)
4.擴(kuò)展 擴(kuò)展一個新功能,只要實(shí)現(xiàn)預(yù)定好的接口禀倔,這個新功能就能被調(diào)用維護(hù) 當(dāng)改變一個功能的實(shí)現(xiàn)甚至換成別的類的時候榄融,但如果還有其他地方引用了原類,很難維護(hù)救湖。如果使用接口可以輕易切換成新類的引用
安全 在一個普通類實(shí)現(xiàn)接口以后愧杯,向上轉(zhuǎn)型,則只暴露出接口描述的方法鞋既,別人獲得的引用也只能使用接口描述的方法力九,所以安全,比如回調(diào)機(jī)制