在最新版本Java1.8中的變化里, Stephen Colebourne 告訴Hartmut Schlosser看彼,“我認(rèn)為最重要的語言上的改變不是Lambdas表達(dá)式,而是在接口上的靜態(tài)和默認(rèn)方法”糠涛。ColeBoune補(bǔ)充道殴边,“默認(rèn)方法功能的增加減少了許多使用抽象類的原因”憎茂。當(dāng)我讀到這里時(shí),我意識(shí)到Colebourne是正確的锤岸,而且我通常用抽象類的許多場(chǎng)景可以通過JDK1.8的默認(rèn)方法(default method)替換為JDK1.8接口竖幔。
在網(wǎng)上論壇和博客中討論Java接口和抽象類異同的例子不勝枚舉。這些討論包括但不限于是偷, JavaWorld 's Abstract classes vs. interfaces , StackOverflow 's When do I have to use interfaces instead of abstract classes? , Difference Between Interface and Abstract Class , 10 Abstract Class and Interface Interview Questions Answers in Java , 作為曾經(jīng)有用的信息拳氢,許多現(xiàn)在已經(jīng)過時(shí)了,可能會(huì)成為讓Java體驗(yàn)更加混亂的部分蛋铆。
在我思考Java1.8中接口和抽象類尚存在的不同馋评,我決定去看看Java Tutorial關(guān)于這部分說過的信息。這個(gè)引導(dǎo)(Tutorial)已經(jīng)更新到JDK 8 而且關(guān)于抽象方法和類的討論有一個(gè)章節(jié)戒职,稱作 抽象類 vs 接口栗恩。這個(gè)章節(jié)指出在JDK 8 中接口和抽象類的異同點(diǎn)。著重強(qiáng)調(diào)的不同點(diǎn)是數(shù)據(jù)成員和方法的作用域(訪問權(quán)限):
- 抽象類允許非靜態(tài)和非final的域洪燥,允許方法成為public,static和final
- 所有的接口方法本質(zhì)為public的磕秤。
在Java Tutorial接著列出了許多應(yīng)該考慮抽象類的場(chǎng)景,和許多應(yīng)該考慮接口的場(chǎng)景捧韵。不出意料市咆,這些源于前面提到的不同、分歧再来,主要處理你是否需要域和方法成為private,protected,non-static,或者 not-final(偏向抽象類)蒙兰,或者你需要把重點(diǎn)放在類型而不是考慮實(shí)現(xiàn)的能力(偏向接口)。
因?yàn)镴ava語序一個(gè)類實(shí)現(xiàn)多個(gè)接口但只能繼承一個(gè)類芒篷,接口可能被視為有利于多繼承的實(shí)現(xiàn)搜变。多虧JDK 8 的默認(rèn)方法,這些接口甚至能提供默認(rèn)的實(shí)現(xiàn)针炉。
那么挠他,一個(gè)很自然的問題是:當(dāng)一個(gè)類實(shí)現(xiàn)了兩個(gè)接口,而這兩個(gè)接口描述了一個(gè)具有相同特點(diǎn)的默認(rèn)方法篡帕,Java怎么處理殖侵。答案是,這會(huì)報(bào)一個(gè)編譯錯(cuò)誤镰烧。這是一個(gè)屏幕截圖拢军,NetBeans8上運(yùn)行報(bào)的這個(gè)錯(cuò)誤。
結(jié)論
JDK 8 爭(zhēng)議性的把抽象類的優(yōu)點(diǎn)帶給接口怔鳖。造成的影響是今天有大量的抽象類通過默認(rèn)方法可能被替換為接口茉唉。