之前面試時(shí)被過關(guān)于java8中接口的新特性問題,當(dāng)時(shí)沒有回答好,后查找資料,在這里做下筆記。
java8之前接口中的方法默認(rèn)類型都是public abstract,也就是抽象方法,具體實(shí)現(xiàn)都交給實(shí)現(xiàn)類。而java8對(duì)接口功能做了增強(qiáng),增加了default方法和static方法,也就是說從java8開始接口中的方法不再只能是抽象的,也可以有實(shí)現(xiàn)。
其應(yīng)用也非常簡(jiǎn)單,如下面的例子所示,在接口中定義default和static方法:
public interface DefaultInterface {
// default方法
default void defaultFunction(){
System.out.println("this is a default function");
}
// static方法
static void staticFunction(){
System.out.println("this is a static funcion");
}
}
在實(shí)現(xiàn)類中可以直接調(diào)用接口的default方法,通過接口名.方法名調(diào)用static方法:
public class DefaultInterfaceImpl implements DefaultInterface{
public static void main(String[] args){
// 調(diào)用default方法
new DefaultInterfaceImpl().defaultFunction();
// 調(diào)用static方法
DefaultInterface.staticFunction();
}
}
運(yùn)行結(jié)果如下:
注意點(diǎn):
- 實(shí)現(xiàn)類可以重寫default方法,不能重寫static方法
- 如果一個(gè)類實(shí)現(xiàn)了兩個(gè)接口,而這兩個(gè)接口擁有相同方法簽名(相同的方法名、參數(shù))、返回類型的default方法時(shí),實(shí)現(xiàn)類就必須重寫該default方法,否則編譯器會(huì)因?yàn)椴恢缿?yīng)該調(diào)用哪一個(gè)接口中的default方法而報(bào)錯(cuò)。重寫接口中default方法后,編譯器會(huì)執(zhí)行重寫后的方法。不過好的編程習(xí)慣是明智的選擇方法名,避免和其它接口產(chǎn)生沖突。
- 如果一個(gè)類同時(shí)繼承了一個(gè)類和實(shí)現(xiàn)了一個(gè)或多個(gè)接口,而父類中擁有和接口中default方法相同的簽名、返回值的方法時(shí),當(dāng)該類未重寫該方法,直接調(diào)用時(shí),將會(huì)調(diào)用父類中的方法。
新特性帶來的好處:
- 增加default方法,可以在不破壞java現(xiàn)有實(shí)現(xiàn)架構(gòu)的情況下能往接口里增加新方法。
盡管如此,還是不推薦過度使用,如果你大量使用default方法在你的應(yīng)用接口中,你將很快意識(shí)到他沒有真正精簡(jiǎn)代碼。因?yàn)槟悴荒茉诮涌谥刑釤抎efault里重復(fù)的代碼到一個(gè)新的普通方法,這與以精簡(jiǎn)代碼為目的的default關(guān)鍵字相沖突。不過這個(gè)問題在java9中通過在接口中支持private interface methods得到解決。不過一般公司項(xiàng)目在jdk版本的使用上并不會(huì)太激進(jìn)。
具體參考鏈接:https://www.cnblogs.com/wanshiming/p/9011879.html - 而static方法除了調(diào)用比較方便外還有一個(gè)有趣的意義,程序入口main方法也是static,現(xiàn)在在接口也可以運(yùn)行了。
接口和抽象類:
如此看來接口是不是和類越來越接近了?那么回歸到一道基礎(chǔ)的面試題:現(xiàn)在接口和抽象類有什么區(qū)別呢?
- 一個(gè)類只能繼承一個(gè)抽象類,卻可以實(shí)現(xiàn)多個(gè)接口。
- 雖然接口和抽象類都不能被實(shí)例化,但是抽象類可以有構(gòu)造器,接口沒有構(gòu)造器。
- 抽象類中方法可以有public、protected、默認(rèn)(包)甚至private范圍的方法,接口只能有public范圍的方法(即使是default也是public范圍的,當(dāng)然從java9開始接口也可以有private方法 。