首先來看看接口的定義:接口,在JAVA編程語言中是一個(gè)抽象類型,主要是抽象方法的集合,接口中的變量定義必須為public static final類型。接口通常以interface來聲明。
抽象類: 從面向?qū)ο蟮慕嵌葋碇v,我們知道所有的對象都是通過類來描繪的,但是反過來卻不是這樣,并不是 所有的類都是用來描繪對象的,如果一個(gè)類中沒有包含足夠的信息來描繪一個(gè)具體的對象,這樣的類就可以認(rèn)為是抽象類。。抽象類除了不能實(shí)例化對象之外,類的其它功能依然存在,成員變量、成員方法和構(gòu)造方法的訪問方式和普通類一樣。由于抽象類不能實(shí)例化對象,所以抽象類必須被繼承,才能被使用。
從定義角度來看,接口和抽象類是兩個(gè)幾乎沒有太多聯(lián)系的設(shè)計(jì)。接口只是一個(gè)抽象方法的集合。而抽象類本質(zhì)上是一個(gè)類,但是它不能被實(shí)例化,但是類具備的大多特性抽象類都有。抽象類和interface在Java語言中都是用來進(jìn)行抽象的,他們除了都是一個(gè)用于抽象的東西之外幾乎沒有任何相同之處。事實(shí)上對于一個(gè)java里的類來說,無外乎由兩種成分組成,即變量和方法(靜態(tài)代碼塊可以寫在類里面但從實(shí)際效果角度并沒有影響一個(gè)類)。因此接口的功能僅僅包含其中一部分,即方法的集合以及一部分靜態(tài)成員變量。這樣來看,接口是一種非常高的抽象,里面定義的東西被認(rèn)為是不會改變的。抽象類里面就可以定義普通的成員變量,抽象類的抽象程度相對接口來說會低一點(diǎn)。
但是對于java來說個(gè)人認(rèn)為設(shè)計(jì)接口的最大原因是為了支持多繼承,從這個(gè)角度來說,抽象類和接口最重要的區(qū)別應(yīng)該是在使用的時(shí)候的區(qū)別:
類可以實(shí)現(xiàn)多個(gè)接口,但是只能繼承一個(gè)類
其他的區(qū)別就非常多了,本質(zhì)上是一些java語言規(guī)則方面的區(qū)別。例如:抽象類可以寫方法實(shí)現(xiàn),接口也可以寫方法實(shí)現(xiàn),不過需要加上default修飾,等等。
問題:什么時(shí)候用接口什么時(shí)候用抽象類?
抽象類的關(guān)鍵好處在于 能夠?qū)崿F(xiàn)面向?qū)ο笤O(shè)計(jì)的一個(gè)最核心的原則OCP(Open-ClosedPrinciple)。因此當(dāng)我有一部分內(nèi)容是不想讓子類修改的,但是子類又都通用,同時(shí)各個(gè)自樂又有自己的特點(diǎn),那么就適合使用抽象類。
在面向?qū)ο箢I(lǐng)域,抽象類主要用來進(jìn)行類型隱藏。 我們可以構(gòu)造出一個(gè)固定的一組行為的抽象描 述,但是這組行為卻能夠有任意個(gè)可能的具體實(shí)現(xiàn)方式。這個(gè)抽象描述就是抽象類,而這一組任意個(gè)可能的具體實(shí)現(xiàn)則表現(xiàn)為所有可能的派生類。模塊可以操作一個(gè) 抽象體。由于模塊依賴于一個(gè)固定的抽象體,因此它可以是不允許修改的;同時(shí),通過從這個(gè)抽象體派生,也可擴(kuò)展此模塊的行為功能。熟悉OCP的讀者一定知 道,為了能夠?qū)崿F(xiàn)面向?qū)ο笤O(shè)計(jì)的一個(gè)最核心的原則OCP(Open-Closed Principle),抽象類是其中的關(guān)鍵所在。
符合開發(fā)封閉原則,我可以對抽象出來的類進(jìn)行擴(kuò)展,但是只要是這個(gè)抽象類的子類,那么他必然能夠。
從語法層面上講,java單繼承多實(shí)現(xiàn),而接口可以多實(shí)現(xiàn)。