“簡(jiǎn)單不先于復(fù)雜嚎朽,而是在復(fù)雜之后.” —— Alan Perlis
接口
首先铺纽,理解多繼承,什么是多繼承----多繼承就是可以繼承多個(gè)父類哟忍,但是Java不能實(shí)現(xiàn)多繼承,所以 這里就要用到接口了.
接口是一種規(guī)范狡门,是一種規(guī)則,它只給出了方法的樣子锅很,規(guī)定你要實(shí)現(xiàn)哪些方法其馏,而不給出方法的實(shí)現(xiàn),讓接口的實(shí)現(xiàn)類去實(shí)現(xiàn)這些方法爆安,但是對(duì)于不同的實(shí)現(xiàn)類來(lái)說(shuō)尝偎,對(duì)方法的實(shí)現(xiàn)可以完全不同。
? 接口的實(shí)現(xiàn)類如果實(shí)現(xiàn)了某一個(gè)接口鹏控,那么必須實(shí)現(xiàn)接口中定義的所有的待實(shí)現(xiàn)的方法。如果你不想要實(shí)現(xiàn)方法肤寝,那么實(shí)現(xiàn)類必須定義為抽象類当辐,不想實(shí)現(xiàn)的方法必須定義為抽象方法。
?接口中定義的屬性和方法的默認(rèn)訪問(wèn)級(jí)別都是public,所以方法肯定不被private所修飾鲤看,所有的方法前都默認(rèn)包含了abstract 缘揪,表明它是一個(gè)抽象方法,但是可以省略义桂,而且默認(rèn)是省略的
? 接口可以看成是一個(gè)抽干了的抽象類找筝,它里面所有的方法都是抽象的,都是不能給出任何實(shí)現(xiàn)部分的
? 因?yàn)榻涌诳梢钥闯墒且环N特殊的“抽象類”慷吊,而且因?yàn)槌橄箢惪梢岳^承別的類袖裕,所以接口也可以繼承接口,也只可以繼承接口溉瓶。但是接口不可以實(shí)現(xiàn)接口急鳄。
? 一個(gè)類可以實(shí)現(xiàn)多個(gè)接口使用關(guān)鍵字implements ,一個(gè)接口可以繼承多個(gè)接口使用關(guān)鍵字extends堰酿,一個(gè)類可以同時(shí)繼承一個(gè)別的類疾宏,而且實(shí)現(xiàn)一個(gè)或多個(gè)接口,但是關(guān)鍵字extends要在前触创。
注意事項(xiàng):
1.接口可以看成是特殊抽象類坎藐,提供方法原型,沒(méi)有具體表現(xiàn)哼绑,即方法具體實(shí)施
2.子類必須提供父類中抽象方法的實(shí)現(xiàn)方式岩馍。
3.接口中只能包含抽象方法和常量碉咆,不能有,變量兼雄,初始化塊和構(gòu)造函數(shù)
接口的聲明
【修飾符】interface 接口名【extends】父類接口名 {
常量吟逝;
方法:抽象
}
注意事項(xiàng):與Java的類文件一樣,接口文件的文件名必須與接口名相同
使用接口:
接口不能單獨(dú)實(shí)例化赦肋,要想實(shí)例化接口块攒,必須接口的實(shí)現(xiàn)類來(lái)完成。接口的實(shí)現(xiàn)類佃乘,必須全部實(shí)現(xiàn)接口中所有方法囱井。
【修飾符】 class <類名> 【extends 父類名】【implements 接口列表】{
}
不嚴(yán)密理解為這樣: 接口是一個(gè)類,里面有常量和方法趣避,然后再一個(gè)類中調(diào)用庞呕,重寫(xiě)接口中的方法,但是這個(gè)調(diào)用不是與以往調(diào)用一樣程帕,是有區(qū)別的住练,要用implements這個(gè)關(guān)鍵字來(lái)操作。調(diào)用完后實(shí)例化
抽象類和方法
如果一個(gè)方法中存在不可預(yù)知的方法實(shí)現(xiàn)愁拭,那么這個(gè)方法所在的類就應(yīng)該聲明為抽象類
? 如果在兩個(gè)類當(dāng)中有同名的方法讲逛,按照正常道理來(lái)說(shuō),應(yīng)該提取到父類里岭埠,但是這個(gè)兩個(gè)方法又有明顯的方法實(shí)現(xiàn)上的不同盏混,那么在父類里的方法,就應(yīng)該定義成為抽象惜论,抽象方法许赃,只給出了方法的樣子,而不給出方法的具體實(shí)現(xiàn)馆类,具體實(shí)現(xiàn)由繼承這個(gè)類的具體的子類去實(shí)現(xiàn)
? 抽象方法混聊,必須在抽象類里,抽象類里不一定有抽象方法
? 沒(méi)有抽象方法的抽象類的存在也是有意義的乾巧。這決定了這個(gè)類是不能被直接實(shí)例化的技羔,他的作用基本上是作為一個(gè)“框框”存在的。-------------種豬
? 重寫(xiě)的前提是--- 父類里知道該方法如何去實(shí)現(xiàn)卧抗,子類不打算走原路藤滥,所以覆蓋父類里的實(shí)現(xiàn),
? 父類不給出實(shí)現(xiàn)社裆,也不知道該如何實(shí)現(xiàn)拙绊,由具體的子類自己決定如何實(shí)現(xiàn),但是給出一個(gè)定義,要求子類必須實(shí)現(xiàn)标沪。
接口和抽象類的區(qū)別
接口是用來(lái)被實(shí)現(xiàn)的(implements)榄攀,而抽象類是用類被繼承的 (extends)
? 接口可以繼承別的多個(gè)接口,組成一個(gè)新的接口
? 抽象類可以繼承一個(gè)別的類金句,或?qū)崿F(xiàn)一個(gè)或多個(gè)接口
? 接口是一個(gè)100%的抽象類檩赢,里面的方法沒(méi)有任何一個(gè)有任何的實(shí)現(xiàn)
? 抽象類可以包含非抽象的方法,也就是說(shuō)可以給出某一些方法的實(shí)現(xiàn)违寞。
? 接口一般處于代碼的最底層贞瞒,作出一些規(guī)定,而接口之上一層抽象類層趁曼,對(duì)接口進(jìn)行第一次的實(shí)現(xiàn)军浆,把不可能一次完成的方法,交由自己的子類來(lái)實(shí)現(xiàn)挡闰。
? 抽象類可以有構(gòu)造方法乒融,而接口不可以有構(gòu)造方法。 接口中定義的變量只能為公有的摄悯,靜態(tài)的赞季,終態(tài)的,而且會(huì)默認(rèn)增加奢驯。
Java 接口和Java 抽象類對(duì)比
1 )Java 接口和 Java 抽象類最大的一個(gè)區(qū)別申钩,就在于 Java 抽象類可以提供某些方法的部分實(shí)現(xiàn),而 Java 接口不可以叨橱,這大概就是 Java 抽象類唯一的優(yōu)點(diǎn)吧,但這個(gè)優(yōu)點(diǎn)非常有用断盛。如果向一個(gè)抽象類里加入一個(gè)新的具體方法時(shí)罗洗,那么它所有的子類都一下子都得到了這個(gè)新方法,而 Java 接口做不到這一點(diǎn)钢猛,如果向一個(gè) Java 接口里加入一個(gè)新方法伙菜,所有實(shí)現(xiàn)這個(gè)接口的類就無(wú)法成功通過(guò)編譯了,因?yàn)槟惚仨氉屆恳粋€(gè)類都再實(shí)現(xiàn)這個(gè)方法才行命迈,這顯然是Java 接口的缺點(diǎn)贩绕。
2 )一個(gè)抽象類的實(shí)現(xiàn)只能由這個(gè)抽象類的子類給出,也就是說(shuō)壶愤,這個(gè)實(shí)現(xiàn)處在抽象類所定義出的繼承的等級(jí)結(jié)構(gòu)中淑倾,而由于 Java 語(yǔ)言的單繼承性,所以抽象類作為類型定義工具的效能大打折扣征椒。在這一點(diǎn)上娇哆,Java 接口的優(yōu)勢(shì)就出來(lái)了,任何一個(gè)實(shí)現(xiàn)了一個(gè) Java 接口所規(guī)定的方法的類都可以具有這個(gè)接口的類型,而一個(gè)類可以實(shí)現(xiàn)任意多個(gè) Java 接口碍讨,從而這個(gè)類就有了多種類型治力。
3 )從第 2 點(diǎn)不難看出,Java 接口是定義混合類型的理想工具勃黍,混合類表明一個(gè)類不僅僅具有某個(gè)主類型的行為毁渗,而且具有其他的次要行為腌零。
4 )結(jié)合 1、2 點(diǎn)中抽象類和Java 接口的各自優(yōu)勢(shì),具經(jīng)典的設(shè)計(jì)模式就出來(lái)了:聲明類型的工作仍然由Java 接口承擔(dān)疟暖,但是同時(shí)給出一個(gè)Java 抽象類,且實(shí)現(xiàn)了這個(gè)接口俏橘,而其他同屬于這個(gè)抽象類型的具體類可以選擇實(shí)現(xiàn)這個(gè) Java 接口茂腥,也可以選擇繼承這個(gè)抽象類,也就是說(shuō)在層次結(jié)構(gòu)中疑枯,Java 接口在最上面辩块,然后緊跟著抽象類,哈荆永,這下兩個(gè)的最大優(yōu)點(diǎn)都能發(fā)揮到極至了废亭。這個(gè)模式就是“缺省適配模式”。
在Java 語(yǔ)言 API 中用了這種模式具钥,而且全都遵循一定的命名規(guī)范:Abstract +接口名豆村。 Java 接口和Java抽象類的存在就是為了用于具體類的實(shí)現(xiàn)和繼承的,如果你準(zhǔn)備寫(xiě)一個(gè)具體類去繼承另一個(gè)具體類的話骂删,那你的設(shè)計(jì)就有很大問(wèn)題了掌动。Java 抽象類就是為了繼承而存在的,它的抽象方法就是為了強(qiáng)制子類必須去實(shí)現(xiàn)的宁玫。