類累颂、抽象類滞详、接口之間的區(qū)別
從含義上講區(qū)別
-
類:可以理解為一個(gè)模具,它定義了一個(gè)具體對(duì)象應(yīng)該具有的屬性和行為紊馏,利用類可以創(chuàng)建具有相同屬性和行為的多個(gè)對(duì)象料饥。
如:“老虎”就是一個(gè)類,它的皮毛是黃黑相間的(屬性)朱监,它捕食食草動(dòng)物(行為)岸啡。
-
抽象類:抽象類是對(duì)多個(gè)類具有的共同的屬性和行為的提煉,因此抽象類中包含了子類共有的成員變量和方法赫编。抽象類中包含的方法分為兩類:
- 子類共有的方法巡蘸。每個(gè)子類對(duì)這些方法的實(shí)現(xiàn)是相同的奋隶,因此抽象類中給出了這些方法的具體的實(shí)現(xiàn),一旦定義好悦荒,所有子類均共享該方法唯欣。
- 各子類需要具體實(shí)現(xiàn)的抽象方法。每個(gè)子類對(duì)這些方法實(shí)現(xiàn)的方式各不相同搬味,但具有相同的特征(觸發(fā)條件和結(jié)果——即輸入和輸出)境氢,因而這些方法在抽象類中僅有聲明、而沒有具體實(shí)現(xiàn)碰纬,由各子類完成具體的實(shí)現(xiàn)萍聊。
如:“貓科動(dòng)物”就是一個(gè)抽象類,該類定義了此類動(dòng)物擅長(zhǎng)攀爬和跳躍悦析、喜歡獨(dú)居等屬性寿桨,并具有食肉、捕殺等行為强戴;該類對(duì)多種動(dòng)物的特征進(jìn)行的抽象總結(jié)牛隅,需要通過“老虎”、“貓”酌泰、“獵豹”等子類來實(shí)現(xiàn)媒佣,且每個(gè)子類具有其特有的屬性、并對(duì)對(duì)上述行為的實(shí)現(xiàn)方式各不相同陵刹。
-
接口:接口可以理解為一種協(xié)議(或者說規(guī)則)默伍,不同于類和抽象類關(guān)注類別、接口關(guān)注的是行為衰琐,它定義了一類行為的規(guī)則(即輸入和輸出)也糊。不同的類可以對(duì)接口中定義的行為有不同的實(shí)現(xiàn)方式、同一個(gè)類也可以實(shí)現(xiàn)多個(gè)接口羡宙。
如:當(dāng)一個(gè)軟件被劃分為多個(gè)模塊由不同小組來開發(fā)時(shí)狸剃,每個(gè)小組只需要提供自己負(fù)責(zé)的模塊的接口以規(guī)定其余模塊與自己模塊間的交互方式,每個(gè)小組也不需要關(guān)注其他模塊的內(nèi)部實(shí)現(xiàn)狗热。
從語(yǔ)法上講區(qū)別
-
類:使用
class
關(guān)鍵字標(biāo)識(shí)public class A { private static member; // 成員變量 ... public A() {} // 構(gòu)造函數(shù) public void method() {} // 方法 ... }
-
抽象類:使用
abstract
關(guān)鍵字標(biāo)識(shí)抽象類钞馁,使用extends
關(guān)鍵字繼承抽象類public abstract class A { private static member; // 成員變量 ... public A() {} // 構(gòu)造函數(shù) public void method1() {} // 普通方法 ... public abtract void method2(); // 抽象方法,無函數(shù)體 ... } public class B extends A { public void method2() {} // 抽象方法的實(shí)現(xiàn) }
-
接口:使用
interface
關(guān)鍵字標(biāo)識(shí)接口匿刮,使用implements
關(guān)鍵字實(shí)現(xiàn)接口public interface A { int member; // 成員變量必須為public static final僧凰,可以省略 // 無構(gòu)造函數(shù) int method1(); // 接口中方法的聲明默認(rèn)訪問方式為public,可以省略熟丸,無函數(shù)體 int method2(); ... } public class B implements A { public int method1() {} // 接口的實(shí)現(xiàn) public int method2() {} ... }
-
** 接口和抽象類的區(qū)別 **
- 一個(gè)類只能繼承一個(gè)抽象類训措,而一個(gè)類卻可以實(shí)現(xiàn)多個(gè)接口。
- 抽象類中的成員變量可以是各種類型的,而接口中的成員變量只能是 public static final 類型的绩鸣;且必須給其初值怀大,所以實(shí)現(xiàn)類中不能重新定義,也不能改變其值呀闻;抽象類中的變量默認(rèn)是 default 型叉寂,其值可以在子類中重新定義,也可以重新賦值总珠。
- 抽象類中可以有非抽象方法屏鳍,接口中則不能有非抽象方法。
- 接口可以省略 abstract 關(guān)鍵字局服,抽象類不能钓瞭。
- 接口中不能含有靜態(tài)代碼塊以及靜態(tài)方法,而抽象類可以有靜態(tài)代碼塊和靜態(tài)方法淫奔;
從使用上講區(qū)別
- 接口/類可以繼承多個(gè)接口以組成新接口山涡、但抽象類只能繼承一個(gè)抽象類。
- Java 的單繼承性決定了類只能繼承一個(gè)類唆迁、但可以實(shí)現(xiàn)多個(gè)接口鸭丛。因此接口可以使一個(gè)類除繼承的主類的行為外、還能具有一些其他類具有的行為唐责,實(shí)現(xiàn)了類型的多重繼承鳞溉。
- 抽象類里可以有普通方法,因此在抽象類中添加一個(gè)方法鼠哥,其所有子類均具有了該方法熟菲;而若在接口里添加一個(gè)新方法,其所有子類需要首先先實(shí)現(xiàn)該方法朴恳。
如何使用
- 在下列情況下抄罕,請(qǐng)考慮使用抽象類:
- 希望在幾個(gè)相關(guān)的類之間共享代碼。
- 希望繼承抽象類的子類們具有許多通用的方法或字段于颖,或者需要除
public
之外的訪問修飾符(例如protected
和private
)呆贿。- 希望聲明
non-static
或non-final
的字段,以便定義可以改變具有這些屬性的對(duì)象的狀態(tài)的方法森渐。- 在下列情況下做入,請(qǐng)考慮使用接口:
- 希望不相關(guān)的類實(shí)現(xiàn)相同的方法。 例如章母,Comparable和Cloneable接口由許多不相關(guān)的類實(shí)現(xiàn)母蛛。
- 希望指定特定數(shù)據(jù)類型的行為,但不關(guān)心誰實(shí)現(xiàn)其行為乳怎。
- 希望利用類型的多重繼承。
經(jīng)典設(shè)計(jì)模式
缺省適配模式:
graph LR
A[接口] --> B[抽象類]
B --> C[普通類]