山東安康建設(shè)項(xiàng)目管理有限公司網(wǎng)站北京谷歌優(yōu)化
文章目錄
- 基礎(chǔ)介紹
- 接口的定義
- 關(guān)于接口字段和方法的說(shuō)明
- 使用接口
- 抽象類(lèi)和接口
- 接口方法沖突的一些說(shuō)明
- 方法相同名稱和參數(shù),返回值相同
- 方法名稱相同,參數(shù)不同,返回值相同
- 方法返回值不同,名稱參數(shù)相同
- 方法完全相同,一個(gè)有默認(rèn)實(shí)現(xiàn)
- 接口和類(lèi)中方法沖突
- 總結(jié)
基礎(chǔ)介紹
接口用來(lái)描述類(lèi)應(yīng)該做什么,而不是指定它們具體應(yīng)該怎么做。
在java中,接口不是類(lèi),而是對(duì)希望符合這個(gè)接口的類(lèi)的一組需求。java只能繼承一個(gè)類(lèi),但是可以實(shí)現(xiàn)多個(gè)接口。
接口的定義
接口的定義如下
interface sports {}
接口定義其實(shí)就是和類(lèi)定義相似的。只不過(guò)把class換成了interface
我們?cè)趇nterface可以定義方法,就像抽象類(lèi)那樣定義未實(shí)現(xiàn)的方法即可。類(lèi)實(shí)現(xiàn)接口時(shí)就必須重寫(xiě)方法或者自己成為抽象類(lèi)
interface Sports {void run();
}
在接口里面可以定義方法的默認(rèn)實(shí)現(xiàn),使用default關(guān)鍵字,如果類(lèi)實(shí)現(xiàn)接口時(shí)沒(méi)有重寫(xiě)該方法,那么該方法就會(huì)使用默認(rèn)實(shí)現(xiàn)
interface Sports {void run();default void jump(){}
}
現(xiàn)在,我們可以暫時(shí)將接口看做為沒(méi)有實(shí)例字段的抽象類(lèi)。
關(guān)于接口字段和方法的說(shuō)明
在接口中,我們不能定義實(shí)例字段,但是可以定義靜態(tài)字段。
interface A {public static final int a = 1;
}
但是上面這樣寫(xiě)IDEA會(huì)有提示
表示字段冗余,其實(shí),在接口中我們定義的字段只能使用public static final進(jìn)行修飾
我們?cè)诮涌谥锌梢远x靜態(tài)方法
interface A {public static void t() {}
}
對(duì)于接口里面的內(nèi)容,其實(shí)我們public修飾符可以不用寫(xiě),因?yàn)榻涌诶锩孀侄魏头椒ǖ脑L問(wèn)修飾符只能是public。
使用接口
我們先定義一個(gè)接口,內(nèi)容如下
interface Sports {void run();
}
我們創(chuàng)建一個(gè)類(lèi)來(lái)實(shí)現(xiàn)接口
class Cat implements Sports {@Overridepublic void run() {System.out.println("cat--run");}
}
這個(gè)其實(shí)和繼承基本類(lèi)似的,只是將關(guān)鍵字從extends換成了implements
關(guān)于接口,我們不能夠使用new來(lái)實(shí)例化一個(gè)接口
Sports sports = new Sports(); // ERROR
但是可以聲明接口變量,然后引用實(shí)現(xiàn)了這個(gè)接口的類(lèi)對(duì)象即可
Sports cat = new Cat(); // OK
對(duì)于接口,我們將其看作實(shí)現(xiàn)接口類(lèi)的父類(lèi)就很好理解了
抽象類(lèi)和接口
對(duì)于一個(gè)類(lèi),我們只能繼承一個(gè)類(lèi),但是可以實(shí)現(xiàn)多個(gè)接口。我們就可以將接口看做沒(méi)有實(shí)例字段,并且可以被多繼承的抽象類(lèi)
interface A {}interface B {}class C implements A, B {}
接口方法沖突的一些說(shuō)明
方法相同名稱和參數(shù),返回值相同
我們知道,一個(gè)類(lèi)可以實(shí)現(xiàn)多個(gè)接口,如果接口有相同的方法名稱和參數(shù)會(huì)怎么樣呢?如果有相同的名稱和參數(shù),并且返回值相同,那么我們只需要實(shí)現(xiàn)一個(gè)t方法即可
interface A {void t1();
}interface B {void t1();
}class C implements A, B {@Overridepublic void t1() {}
}
方法名稱相同,參數(shù)不同,返回值相同
如果方法只有參數(shù)不同,那么我們需要實(shí)現(xiàn)2個(gè)方法,也就是會(huì)進(jìn)行重載
interface A {void t1();
}interface B {void t1(int a);
}class C implements A, B {@Overridepublic void t1() {}@Overridepublic void t1(int a) {}
}
方法返回值不同,名稱參數(shù)相同
如果方法名稱相同,參數(shù)相同,而返回值不同,那么就會(huì)報(bào)錯(cuò),我們無(wú)法同時(shí)實(shí)現(xiàn)2個(gè)名稱相同,參數(shù)也相同但是返回值不同的方法。
interface A {int t1();
}interface B {void t1();
}
一個(gè)類(lèi)無(wú)法同時(shí)實(shí)現(xiàn)A接口和B接口
方法完全相同,一個(gè)有默認(rèn)實(shí)現(xiàn)
如果2個(gè)接口一個(gè)有默認(rèn)實(shí)現(xiàn),一個(gè)沒(méi)有默認(rèn)實(shí)現(xiàn),對(duì)于這種情況,我們也必須實(shí)現(xiàn)該方法
interface A {default void t1() {}
}interface B {void t1();
}class C implements A, B {@Overridepublic void t1() {A.super.t1();}
}
但是我們可以通過(guò) 接口名.super.方法名調(diào)用默認(rèn)實(shí)現(xiàn)的方法
接口和類(lèi)中方法沖突
對(duì)于接口和類(lèi)沖突的,都以類(lèi)為準(zhǔn),也就是類(lèi)優(yōu)先原則,不管接口是否有默認(rèn)實(shí)現(xiàn)都會(huì)被超類(lèi)中的方法覆蓋
interface A {default void t1() {System.out.println("interface");}
}interface B {void t1();
}class C {public void t1() {System.out.println("class");}
}class D extends C implements A, B {}
我們使用D來(lái)調(diào)用t1方法將會(huì)輸出class
D d = new D();d.t1(); // 輸出class
總結(jié)
對(duì)于接口,我們將其看作可以被多繼承的,并且不能有實(shí)例字段的抽象類(lèi)就行了。對(duì)于接口和接口發(fā)生沖突時(shí),只要返回類(lèi)型相同我們就可以處理,如果返回類(lèi)型不同那就不能同時(shí)實(shí)現(xiàn)有沖突的接口了。如果接口和超類(lèi)發(fā)生沖突,那么就是以類(lèi)優(yōu)先原則來(lái)進(jìn)行解決的。