原來(lái)我只知道一個(gè)類(lèi)可以實(shí)現(xiàn)多個(gè)接口旁涤,但只可以繼承一個(gè)抽象類(lèi)碉咆,但并不能清楚地認(rèn)識(shí)到它們的區(qū)別及使用的場(chǎng)景。
在查閱不同的博客之后我得到結(jié)論:抽象類(lèi)是對(duì)概念本質(zhì)的總結(jié)败玉,接口是對(duì)行為的規(guī)范敌土。
什么是抽象類(lèi)呢,我是這樣理解的运翼,就是從不同的東西抽象出來(lái)相同的屬性或者行為的類(lèi)返干,但這個(gè)類(lèi)并不能具體地描述一個(gè)具體類(lèi)。比如手機(jī)和座機(jī)都同屬于通訊工具血淌,通訊工具抽象出了手機(jī)和座機(jī)可以通訊等特點(diǎn)矩欠,但通訊工具并不能準(zhǔn)確地描述手機(jī)和座機(jī),因?yàn)槭謾C(jī)悠夯、座機(jī)還有其他的屬性癌淮。
接口同樣可以把手機(jī)和座機(jī)的行為抽象出來(lái),為什么不用接口呢沦补,因?yàn)槭謾C(jī)座機(jī)除了通訊的方法乳蓄,還需要其他的屬性,如型號(hào)夕膀、出廠日期等虚倒,接口只支持定義靜態(tài)不可變的屬性,這顯然不符合要求产舞。還有抽象類(lèi)中可以沒(méi)有抽象方法裹刮,意味著我們可以在這里寫(xiě)默認(rèn)的行為,被子類(lèi)繼承后庞瘸,子類(lèi)可以調(diào)用super.方法名()捧弃,這樣就不會(huì)造成代碼的重復(fù),接口要實(shí)現(xiàn)這樣的效果擦囊,需要依靠定義擁有這個(gè)方法的接口的對(duì)象作為成員變量违霞,做法請(qǐng)看對(duì)“針對(duì)接口編程”的理解。
抽象類(lèi)能夠保證實(shí)現(xiàn)的層次關(guān)系瞬场,避免代碼重復(fù)买鸽。然而,即使在使用抽象類(lèi)的場(chǎng)合贯被,也不要忽視通過(guò)接口定義行為模型的原則眼五。如果依賴(lài)于抽象類(lèi)來(lái)定義行為妆艘,往往導(dǎo)致過(guò)于復(fù)雜的繼承關(guān)系,而通過(guò)接口定義行為能夠更有效地分離行為與實(shí)現(xiàn)看幼,為代碼的維護(hù)和修改帶來(lái)方便批旺。
總結(jié):
關(guān)于實(shí)例化:
- 抽象類(lèi)和接口都不能直接實(shí)例化,如果要實(shí)例化诵姜,抽象類(lèi)變量必須指向?qū)崿F(xiàn)所有抽象方法的子類(lèi)對(duì)象汽煮,接口變量必須指向?qū)崿F(xiàn)所有接口方法的類(lèi)對(duì)象(注意:匿名類(lèi)也是具體實(shí)現(xiàn)了方法的)。
關(guān)于實(shí)現(xiàn):
抽象類(lèi)要被子類(lèi)繼承(使用extends)棚唆;
接口要被類(lèi)實(shí)現(xiàn)(使用implements)暇赤。接口可繼承接口,并可多繼承接口宵凌;
但類(lèi)只能單繼承鞋囊。
(抽象類(lèi)也同樣可以繼承一個(gè)類(lèi)和實(shí)現(xiàn)多個(gè)接口)
關(guān)于成員變量:
- 接口里定義的變量只能是公共的靜態(tài)的常量(默認(rèn)是static 和final修飾,可以不寫(xiě))瞎惫;
抽象類(lèi)中的變量是普通變量溜腐,可自定義訪問(wèn)權(quán)限。
關(guān)于方法:
抽象類(lèi)可以有構(gòu)造函數(shù)微饥;
接口不可以有構(gòu)造函數(shù)抽象類(lèi)中的方法可以被static修飾
jdk8以后接口也可以聲明static方法接口能做方法申明 (方法必須是public逗扒,如果寫(xiě)成其他的編譯時(shí)會(huì)報(bào)錯(cuò)古戴,如果不寫(xiě)欠橘,則默認(rèn)方法是public abstract),接口在jdk8之后也可以包含有完整邏輯的實(shí)例方法(使用default關(guān)鍵字现恼,若是一個(gè)類(lèi)實(shí)現(xiàn)多個(gè)接口中有同名的默認(rèn)方法肃续,那么就會(huì)沖突,解決方法是子類(lèi)重寫(xiě)這個(gè)沖突的方法)叉袍;
抽象類(lèi)中可以做方法申明(使用abstract 始锚; 訪問(wèn)修飾是public,默認(rèn)的可不寫(xiě))喳逛,也可以方法實(shí)現(xiàn)(可以被public,protected等修飾符修飾瞧捌;抽象方法只能申明,不能實(shí)現(xiàn)润文。abstract void abc();不能寫(xiě)成abstract void abc(){}姐呐。去掉abstract之后可以實(shí)現(xiàn)它,也就是非抽象函數(shù)可被實(shí)現(xiàn))典蝌,抽象類(lèi)里可以沒(méi)有抽象方法曙砂。抽象類(lèi)里的抽象方法必須全部被子類(lèi)所實(shí)現(xiàn),如果子類(lèi)不能全部實(shí)現(xiàn)父類(lèi)抽象方法骏掀,那么該子類(lèi)只能是抽象類(lèi)鸠澈,也就是說(shuō)一個(gè)類(lèi)里有抽象方法柱告,那么這個(gè)類(lèi)只能是抽象類(lèi);
一個(gè)實(shí)現(xiàn)接口的時(shí)候笑陈,如不能全部實(shí)現(xiàn)接口方法际度,那么該類(lèi)也只能為抽象類(lèi)。