接口的定義與使用

抽象類(lèi)與普通類(lèi)相比最大的特點(diǎn)是約定了子類(lèi)的實(shí)現(xiàn)要求鹤竭,但是抽象類(lèi)有一個(gè)缺點(diǎn):?jiǎn)卫^承局限,如果要想約定子類(lèi)的實(shí)現(xiàn)要求以及避免單繼承的局限就需要使用接口回窘。在你以后的開(kāi)發(fā)設(shè)計(jì)之中:接口優(yōu)先诺擅。在一個(gè)操作既可以使用抽象類(lèi)又可以使用接口的時(shí)候市袖,請(qǐng)優(yōu)先考慮接口啡直。

一. 接口的基本概念

接口就是一個(gè)抽象方法和全局常量的集合,在Java中接口可以使用interface關(guān)鍵字來(lái)進(jìn)行定義苍碟。如果子類(lèi)要想使用接口酒觅,那么就必須利用implements關(guān)鍵字來(lái)實(shí)現(xiàn)接口,同時(shí)一個(gè)子類(lèi)可以同時(shí)實(shí)現(xiàn)多個(gè)接口微峰,也就是說(shuō)可以利用接口來(lái)實(shí)現(xiàn)多繼承的概念舷丹。對(duì)于接口的子類(lèi)(如果不是抽象類(lèi))則必須覆寫(xiě)接口中的全部抽象方法。隨后可以利用子類(lèi)對(duì)象的向上轉(zhuǎn)型通過(guò)實(shí)例化子類(lèi)來(lái)得到接口的實(shí)例化對(duì)象蜓肆。

當(dāng)一個(gè)子類(lèi)繼承了多個(gè)接口之后颜凯,并且接口對(duì)象通過(guò)子類(lèi)進(jìn)行實(shí)例化,那么這多個(gè)父接口之間是允許互相轉(zhuǎn)換的仗扬。

二. 接口使用限制

1. 接口定義完成之后症概,就需要對(duì)其有一個(gè)核心的說(shuō)明,那么首先需要說(shuō)明的是:接口里面只允許存在有public權(quán)限早芭,也就是說(shuō)不管是屬性還是方法其權(quán)限只能是public彼城。

在以后編寫(xiě)接口的時(shí)候,99%的接口里面只會(huì)提供有抽象方法退个,很少在接口里面看見(jiàn)有許多的全局常量募壕。所以很多時(shí)候?yàn)榱朔乐贡苊庖恍╅_(kāi)發(fā)者出現(xiàn)混亂,所以接口的方法上往往都會(huì)加上pubLic语盈。

2. 當(dāng)一個(gè)子類(lèi)需要實(shí)現(xiàn)接口又需要繼承抽象類(lèi)的時(shí)候舱馅,請(qǐng)先使用extends繼承一個(gè)抽象類(lèi),而后再使用implements實(shí)現(xiàn)多個(gè)接口刀荒。

3. 一個(gè)抽象類(lèi)可以使用implements實(shí)現(xiàn)多個(gè)接口习柠,但是接口不能夠去繼承抽象類(lèi)匀谣。

4. 一個(gè)接口可以使用extends來(lái)繼承多個(gè)父接口。

5. 接口可以定義一系列的內(nèi)部結(jié)構(gòu)资溃,包括:內(nèi)部的普通類(lèi)武翎、內(nèi)部抽象類(lèi)、內(nèi)部接口溶锭,其中使用static定義的內(nèi)部接口就相當(dāng)于一個(gè)外部接口宝恶。

對(duì)于內(nèi)部的結(jié)構(gòu)依然不是你們的首選,而且要想清楚接口的實(shí)際開(kāi)發(fā)意義趴捅,需要大量的項(xiàng)目來(lái)驗(yàn)證垫毙。

三. 使用接口定義標(biāo)準(zhǔn)

對(duì)于接口在實(shí)際的開(kāi)發(fā)之中有三大核心應(yīng)用環(huán)境:

①定義操作標(biāo)準(zhǔn);

②表示能力拱绑;

③在分布式開(kāi)發(fā)之中暴露遠(yuǎn)程服務(wù)方法综芥。


class TestDemo {

public static void main(String args[]) {

Computer com = new Computer() ;

com.plugin(new Flash()) ;

com.plugin(new Print()) ;

}

}

interface USB {

public void setup() ;? // 安裝USB驅(qū)動(dòng)

public void work() ;? // 進(jìn)行工作

}

class Computer {

public void plugin(USB usb) {//只能夠插入U(xiǎn)SB設(shè)備

usb.setup() ;

usb.work() ;

}

}

class Flash implements USB {

public void setup() {

System.out.println("安裝U盤(pán)驅(qū)動(dòng)!") ;

}

public void work() {

System.out.println("進(jìn)行數(shù)據(jù)傳輸猎拨!") ;

}

}

class Print implements USB {

public void setup() {

System.out.println("安裝打印機(jī)驅(qū)動(dòng)膀藐!") ;

}

public void work() {

System.out.println("進(jìn)行文件打印红省!") ;

}

}

發(fā)現(xiàn)使用接口和對(duì)象多態(tài)性的概念結(jié)合之后额各,對(duì)于參數(shù)的統(tǒng)一更加明確了。而且可以發(fā)現(xiàn)接口是在類(lèi)之上的設(shè)計(jì)抽象吧恃。

四. 工廠(chǎng)設(shè)計(jì)模式(Factory) ?【重點(diǎn)】

首先來(lái)看一個(gè)簡(jiǎn)單的程序范例: 在進(jìn)行類(lèi)設(shè)計(jì)的時(shí)候虾啦,要求首先需要有接口,而后接口要通過(guò)子類(lèi)才可以進(jìn)行對(duì)象的實(shí)例化處理痕寓。

此時(shí)的程序?qū)崿F(xiàn)的關(guān)鍵是:“IFruit fruit = new Apple() ;”傲醉,如果沒(méi)有此語(yǔ)句,接口對(duì)象將無(wú)法進(jìn)行實(shí)例化的操作處理呻率。但是最大的敗筆也在此硬毕。主方法是一個(gè)客戶(hù)端,那么對(duì)于程序的修改不應(yīng)該影響到客戶(hù)端筷凤。

這個(gè)時(shí)候new是整個(gè)開(kāi)發(fā)過(guò)程之中最大的耦合元兇昭殉,而我們?cè)陂_(kāi)發(fā)之中要想進(jìn)行解耦合的關(guān)鍵就在于要引入一個(gè)第三方,所以這個(gè)類(lèi)可以使用Factory來(lái)描述藐守。

范例:

class TestDemo {

public static void main(String args[]) {

if(args.length != 1) {? // 沒(méi)有傳遞一個(gè)參數(shù)

System.out.println("對(duì)不起挪丢,程序執(zhí)行錯(cuò)誤,正確的格式:java TestDemo 類(lèi)名稱(chēng)") ;

System.exit(1) ;? // 退出程序執(zhí)行

}

System.out.println("hello world !\n") ;

Computer com = new Computer() ;

com.plugin(new Flash()) ;

com.plugin(new Print()) ;

//IFruit fruit = new Apple() ;

// 利用第三方來(lái)進(jìn)行解耦合

IFruit fruit = Factory.getInstance(args[0]) ;

fruit.eat() ;

}

}

class Factory {

// 因?yàn)榇藭r(shí)Factory產(chǎn)生實(shí)例化對(duì)象沒(méi)有意義

public static IFruit getInstance(String className) {

if("apple".equals(className)) {

return new Apple() ;

}

if("orange".equals(className)) {

return new Orange() ;

}

return null ;

}

}

interface USB {

public void setup() ;? // 安裝USB驅(qū)動(dòng)

public void work() ;? // 進(jìn)行工作

}

class Computer {

public void plugin(USB usb) {? //只能夠插入U(xiǎn)SB設(shè)備

usb.setup() ;

usb.work() ;

}

}

class Flash implements USB {

public void setup() {

System.out.println("安裝U盤(pán)驅(qū)動(dòng)卢厂!") ;

}

public void work() {

System.out.println("進(jìn)行數(shù)據(jù)傳輸乾蓬!") ;

}

}

class Print implements USB {

public void setup() {

System.out.println("安裝打印機(jī)驅(qū)動(dòng)!") ;

}

public void work() {

System.out.println("進(jìn)行文件打由骱恪任内!") ;

}

}

interface IFruit {

public void eat() ;

}

class Apple implements IFruit {

public void eat() {

System.out.println("\n削皮吃蘋(píng)果撵渡!") ;

}

}

class Orange implements IFruit {

public void eat() {

System.out.println("\n剝皮吃橘子!") ;

}

}

當(dāng)更換使用的IFruit子類(lèi)的時(shí)候主方法沒(méi)有任何的變化就可以實(shí)現(xiàn)了子類(lèi)的變更死嗦,這樣的設(shè)計(jì)就成為工廠(chǎng)設(shè)計(jì)模式趋距。

總結(jié):以后只要是你編寫(xiě)的接口如果要想取得接口的實(shí)例化對(duì)象,第一反應(yīng):寫(xiě)工廠(chǎng)類(lèi)越除。

五. 代理設(shè)計(jì)模式(Proxy)【重點(diǎn)】

所謂的代理嚴(yán)格來(lái)講就是兩個(gè)子類(lèi)共同實(shí)現(xiàn)一個(gè)接口节腐,其中一個(gè)子類(lèi)負(fù)責(zé)真實(shí)的業(yè)務(wù)實(shí)現(xiàn),而另外的子類(lèi)負(fù)責(zé)輔助真實(shí)業(yè)務(wù)主題的操作摘盆。


class TestDemo {

public static void main(String args[]) {

if(args == null) {

System.out.println("命令行參數(shù)為null") ;

}

if(0 == args.length) {

System.out.println("命令行參數(shù)個(gè)數(shù)為0") ;

}

if(args.length != 1) {? // 沒(méi)有傳遞一個(gè)參數(shù)

System.out.println("對(duì)不起翼雀,程序執(zhí)行錯(cuò)誤,正確的格式:java TestDemo 類(lèi)名稱(chēng)") ;

System.exit(1) ;? // 退出程序執(zhí)行

}

System.out.println("hello world !\n") ;

Computer com = new Computer() ;

com.plugin(new Flash()) ;

com.plugin(new Print()) ;

//IFruit fruit = new Apple() ;

// 利用第三方來(lái)進(jìn)行解耦合

IFruit fruit = Factory.getInstance(args[0]) ;

fruit.eat() ;

//ISubject sub = new ProxySubject(new RealSubject()) ;

ISubject sub = Factory.getInstance() ;

// 通過(guò)代理類(lèi)對(duì)象發(fā)出孩擂,利用代理類(lèi)來(lái)實(shí)現(xiàn)真實(shí)業(yè)務(wù)調(diào)用

sub.save() ;

}

}

class Factory {

// 因?yàn)榇藭r(shí)Factory產(chǎn)生實(shí)例化對(duì)象沒(méi)有意義

public static IFruit getInstance(String className) {? //通過(guò)普通類(lèi)去操作

if("apple".equals(className)) {

return new Apple() ;

}

if("orange".equals(className)) {? ? ? ? ? ? ? ? ? //通過(guò)代理類(lèi)去操作

return new Orange() ;

}

return null ;

}

public static ISubject getInstance() {

return new ProxySubject(new RealSubject()) ;

}

}

interface USB {

public void setup() ;? // 安裝USB驅(qū)動(dòng)

public void work() ;? // 進(jìn)行工作

}

class Computer {

public void plugin(USB usb) {? //只能夠插入U(xiǎn)SB設(shè)備

usb.setup() ;

usb.work() ;

}

}

class Flash implements USB {

public void setup() {

System.out.println("安裝U盤(pán)驅(qū)動(dòng)狼渊!") ;

}

public void work() {

System.out.println("進(jìn)行數(shù)據(jù)傳輸!") ;

}

}

class Print implements USB {

public void setup() {

System.out.println("安裝打印機(jī)驅(qū)動(dòng)类垦!") ;

}

public void work() {

System.out.println("進(jìn)行文件打颖芬亍!") ;

}

}

interface IFruit {

public void eat() ;

}

class Apple implements IFruit {

public void eat() {

System.out.println("\n削皮吃蘋(píng)果护锤!") ;

}

}

class Orange implements IFruit {

public void eat() {

System.out.println("\n剝皮吃橘子官地!") ;

}

}

interface ISubject {

public void save() ;? // 核心功能是救人

}

class RealSubject implements ISubject {

public void save() {

System.out.println("真正的制止了暴力事件酿傍!") ;

}

}

class ProxySubject implements ISubject {? // 代理實(shí)現(xiàn)

private ISubject subject ;? // 真正的操作業(yè)務(wù)

// 在創(chuàng)建代理類(lèi)對(duì)象的時(shí)候必須設(shè)置要代理的真實(shí)主題

public ProxySubject(ISubject subject) {

this.subject = subject ;

}

public void broke() {

System.out.println("1烙懦、破門(mén)而入!") ;

}

public void get() {

System.out.println("2赤炒、得到見(jiàn)義勇為獎(jiǎng)氯析!") ;

}

public void save() {

this.broke() ;? ? ? ? ? // 真實(shí)操作前的準(zhǔn)備

this.subject.save() ;? ? // 調(diào)用真實(shí)的業(yè)務(wù)

this.get() ;? ? ? ? ? ? // 操作后的收尾

}

}

代理的本質(zhì):所有的真實(shí)業(yè)務(wù)操作都會(huì)有一個(gè)與之輔助的功能類(lèi)共同完成。

六. 抽象類(lèi)與接口的區(qū)別(面試題)

抽象類(lèi)和接口都屬于常用的類(lèi)結(jié)構(gòu)設(shè)計(jì)莺褒,在開(kāi)發(fā)之中都會(huì)出現(xiàn)掩缓,不過(guò)如果按照優(yōu)先選擇來(lái)講,接口一定要比抽象類(lèi)更方便遵岩。

除了單繼承的局限之外你辣,實(shí)際上使用抽象類(lèi)和接口都是類(lèi)似的,但是在實(shí)際的開(kāi)發(fā)之中尘执,抽象類(lèi)的設(shè)計(jì)要比接口復(fù)雜舍哄。


1. 接口是Java的核心,慢慢需要學(xué)習(xí)到接口的更多使用以及設(shè)計(jì)誊锭;

2. 開(kāi)發(fā)之中優(yōu)先考慮接口表悬,以避免單繼承局限;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末丧靡,一起剝皮案震驚了整個(gè)濱河市蟆沫,隨后出現(xiàn)的幾起案子籽暇,更是在濱河造成了極大的恐慌,老刑警劉巖饭庞,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件戒悠,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡舟山,警方通過(guò)查閱死者的電腦和手機(jī)救崔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)捏顺,“玉大人六孵,你說(shuō)我怎么就攤上這事》荆” “怎么了劫窒?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)拆座。 經(jīng)常有香客問(wèn)我主巍,道長(zhǎng),這世上最難降的妖魔是什么挪凑? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任孕索,我火速辦了婚禮,結(jié)果婚禮上躏碳,老公的妹妹穿的比我還像新娘搞旭。我一直安慰自己,他們只是感情好菇绵,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布肄渗。 她就那樣靜靜地躺著,像睡著了一般咬最。 火紅的嫁衣襯著肌膚如雪翎嫡。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,185評(píng)論 1 284
  • 那天永乌,我揣著相機(jī)與錄音惑申,去河邊找鬼。 笑死翅雏,一個(gè)胖子當(dāng)著我的面吹牛圈驼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播枚荣,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼碗脊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起衙伶,我...
    開(kāi)封第一講書(shū)人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤祈坠,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后矢劲,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體赦拘,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年芬沉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了躺同。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡丸逸,死狀恐怖蹋艺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情黄刚,我是刑警寧澤捎谨,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站憔维,受9級(jí)特大地震影響涛救,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜业扒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一检吆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧程储,春花似錦蹭沛、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)交煞。三九已至咏窿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間素征,已是汗流浹背集嵌。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留御毅,地道東北人根欧。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像端蛆,于是被迫代替她去往敵國(guó)和親凤粗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

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

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法今豆,類(lèi)相關(guān)的語(yǔ)法嫌拣,內(nèi)部類(lèi)的語(yǔ)法柔袁,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法异逐,線(xiàn)程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,587評(píng)論 18 399
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理捶索,服務(wù)發(fā)現(xiàn),斷路器灰瞻,智...
    卡卡羅2017閱讀 134,601評(píng)論 18 139
  • 小編費(fèi)力收集:給你想要的面試集合 1.C++或Java中的異常處理機(jī)制的簡(jiǎn)單原理和應(yīng)用腥例。 當(dāng)JAVA程序違反了JA...
    八爺君閱讀 4,574評(píng)論 1 114
  • 【易經(jīng)原文·比卦初爻爻辭及象傳】 [爻辭]初六,有孚比之(1)酝润,無(wú)咎燎竖。有孚盈缶(2),終來(lái)有它(3)要销,吉底瓣。[象傳]...
    大珊老師閱讀 1,119評(píng)論 0 3
  • 又是一年中秋夜,依舊是皓月當(dāng)空蕉陋,看著天上的明月捐凭,心中不禁略過(guò)一絲寂寞。身在婆家的我凳鬓,雖不是背井離鄉(xiāng)茁肠,但也是...
    落英滿(mǎn)地閱讀 298評(píng)論 0 1