一、簡(jiǎn)介
描述:
- 普通類只有具體實(shí)現(xiàn),抽象類具體實(shí)現(xiàn)和規(guī)范都有,接口只有規(guī)范!
- 接口就是比抽象類還抽象的抽象類,可以更加規(guī)范的對(duì)子類進(jìn)行約束,全面專業(yè)地實(shí)現(xiàn)了規(guī)范和具體實(shí)現(xiàn)的分離。
- 抽象類還提供某些具體實(shí)現(xiàn),接口不提供任何實(shí)現(xiàn),接口中所有方法都是抽象方法。
- 接口是完全面向規(guī)范的,規(guī)定了一批類具有的公共方法規(guī)范。
- 從接口的實(shí)現(xiàn)者角度看,接口定義了可以向外部提供的服務(wù)。
- 從接口的調(diào)用者角度看,接口定義了實(shí)現(xiàn)者能提供哪些服務(wù)。
- 接口是兩個(gè)模塊之間通信的標(biāo)準(zhǔn),通信的規(guī)范。如果能把你要設(shè)計(jì)的系統(tǒng)之間模塊之間的接口定義好,就相當(dāng)于完成了系統(tǒng)的設(shè)計(jì)大綱,剩下的就是添磚加瓦的具體實(shí)現(xiàn)了。做系統(tǒng)設(shè)計(jì)時(shí)往往就是使用面向接口的思想來(lái)設(shè)計(jì)系統(tǒng)。
本質(zhì):
- 接口就是規(guī)范,定義的是一組規(guī)則,體現(xiàn)了現(xiàn)實(shí)世界中“如果你是…則必須能…”的思想。如果你是天使,則必須能飛。如果你是汽車(chē),則必須能跑。如果你好人,則必須干掉壞人。如果你是壞人,則必須欺負(fù)好人。
- 接口的本質(zhì)是契約,就像我們?nèi)碎g的法律一樣,制定好后大家都遵守。
- 面向?qū)ο蟮木?,是?duì)對(duì)象的抽象,最能體現(xiàn)這一點(diǎn)的就是接口。為什么我們討論設(shè)計(jì)模式都只針對(duì)具備了抽象能力的語(yǔ)言(比如c++、java、c#等),就是因?yàn)樵O(shè)計(jì)模式所研究的,實(shí)際上就是如何合理的去抽象。
作用:
- 接口的最主要的作用是達(dá)到統(tǒng)一訪問(wèn),因?yàn)閷?shí)現(xiàn)接口的類的方法名相同,但是實(shí)現(xiàn)內(nèi)容不同。
- 在創(chuàng)建對(duì)象的時(shí)候用接口類型作為引用的類型,想用哪個(gè)實(shí)現(xiàn)類去做方法的內(nèi)部實(shí)現(xiàn),就new該實(shí)現(xiàn)類的對(duì)象,調(diào)用方法的時(shí)候就可以直接用接口類型的引用來(lái)調(diào)用。
二、接口與抽象類的區(qū)別
抽象類:
- 抽象類也是類,除了可以寫(xiě)抽象方法以及不能直接new對(duì)象之外,其他的和普通類沒(méi)有什么不一樣的。
- 聲明類的關(guān)鍵字是'class'。
- 抽象類是用來(lái)被繼承的,Java中的類是單繼承,繼承的關(guān)鍵字是'extends'。
- 抽象類的多態(tài)表現(xiàn):一個(gè)抽象類的引用,可以指向這個(gè)抽象類的任意子類對(duì)象。
接口:
- 接口已經(jīng)另一種類型了,和類是有本質(zhì)的區(qū)別的,所以不能用類的標(biāo)準(zhǔn)去衡量接口。
- 聲明接口的關(guān)鍵字是'interface'。
- 接口是用來(lái)被類實(shí)現(xiàn)的,Java中的接口可以被多實(shí)現(xiàn),實(shí)現(xiàn)的關(guān)鍵字是'implements'。
- 接口的多態(tài)表現(xiàn):一個(gè)接口的引用,可以指向這個(gè)接口的任意實(shí)現(xiàn)類對(duì)象。
三、語(yǔ)法
描述:
- 接口中可以不寫(xiě)任何方法,但如果寫(xiě)方法了,該方法必須是'public abstract'修飾的抽象方法。
- 接口中定義抽象方法可以不用顯式地聲明'public abstract',不寫(xiě)默認(rèn)就是'public abstract'修飾的。
- 接口中可以不寫(xiě)任何屬性,但如果寫(xiě)屬性了,該屬性必須是'public static final'修飾的靜態(tài)常量,且聲明的同時(shí)就必須賦值,因?yàn)榻涌谥胁荒芫帉?xiě)靜態(tài)代碼塊。
- 接口中定義靜態(tài)常量可以不用顯式地聲明'public static final',不寫(xiě)默認(rèn)就是'public static final'修飾的。
- 接口中沒(méi)有構(gòu)造方法,不能被實(shí)例化,但允許定義接口類型的引用變量,該引用變量引用實(shí)現(xiàn)了這個(gè)接口的類的實(shí)例。
- 一個(gè)類可以實(shí)現(xiàn)多個(gè)接口;一個(gè)接口不能實(shí)現(xiàn)接口,但可以繼承多個(gè)父接口。
注意:
- 接口必須通過(guò)類來(lái)實(shí)現(xiàn)它的抽象方法。
- 類實(shí)現(xiàn)接口時(shí)需要實(shí)現(xiàn)接口的所有抽象方法,若有抽象方法沒(méi)實(shí)現(xiàn),這個(gè)類就必須聲明為抽象類。
- 一個(gè)引用所指向的對(duì)象,是有可能實(shí)現(xiàn)任何一個(gè)接口的。所以使用'instanceof'關(guān)鍵字判斷一個(gè)接口類型引用時(shí),只要'instanceof'關(guān)鍵字右邊的類或接口不是'final'修飾的,就能編譯通過(guò)。運(yùn)行結(jié)果看引用指向的對(duì)象類型是否為右邊的類的子類或?qū)崿F(xiàn)類。
示例:
interface A {
int NUM = 1;
void testA();
}
interface B {
void testB();
}
interface C extends A, B {
void testC();
}
class Student implements C {
public void testA() {
}
public void testB() {
}
public void testC() {
}
public void testD() {
}
}
class Teacher {
}
public class Test {
public static void main(String[] args) {
/* c只能調(diào)用接口C中聲明和繼承的方法 */
C c = new Student();
System.out.println(c instanceof A);//true
System.out.println(c instanceof B);//true
System.out.println(c instanceof C);//true
System.out.println(c instanceof Student);//true
System.out.println(c instanceof Object);//true
System.out.println(c instanceof Teacher);//false
/*
以下代碼編譯報(bào)錯(cuò)
System.out.println(o instanceof String);
*/
}
}
|