1.抽象類與接口的區別?
抽象類是用來捕捉子類的通用特性的 ,它不能被實例化,只能被用作子類的超類。抽象類是被用來創建繼承層級裏子類的模板。
接口是抽象方法的集合。如果一個類實現了某個接口,那麼它就繼承了這個接口的抽象方法。這就像契約模式,如果實現了這個接口,那麼就必須確保使用這些方法。接口只是一種形式,接口自身不能做任何事情。
簡單來說,
接口是公開的,裏面不能有私有的方法或變量,是用於讓別人使用的,而抽象類是可以有私有方法或私有變量的,
另外,實現接口的一定要實現接口裏定義的所有方法,而實現抽象類可以有選擇地重寫需要用到的方法,一般的應用裏,最頂級的是接口,然後是抽象類實現接口,最後纔到具體類實現。
還有,接口可以實現多重繼承,而一個類只能繼承一個超類,但可以通過繼承多個接口實現多重繼承,接口還有標識(裏面沒有任何方法,如Remote接口)和數據共享(裏面的變量全是常量)的作用.
2.接口與函數接口的區別?
函數接口是Java8提出的新概念,原來的接口裏只能有方法的聲明不能有方法的實現,Java8以後接口方法的申明有也可以有方法的實現,但是隻能有兩種方法可以在接口中存在,那就是靜態方法和默認方法。如:
interface Converter<F, T> {
static Integer getC(int c) {
return null;
}
default Integer rename(){
return 1;
}
}
函數接口又是什麼?
函數接口是更嚴格的接口定義,主要食用與java8語法的lambda表達式,普通接口可以有多個方法的聲明,但是函數接口只能有一個方法的聲明,如:
@FunctionalInterface
interface Converter<F, T> {
T convert(F from);
static Integer getC(int c) {
return null;
}
default Integer rename(){
return 1;
}
}
但是如果你這樣:
我們看到這就是不符合規範的,因爲我們存在了兩個方法的聲明。
但是:
這樣又是可以的,又是爲什麼呢?
重寫 Object 類裏的方法不會導致函數式接口失效:
如果一個接口聲明瞭抽象方法,但該抽象方法重寫了 Object 類裏的一個公有方法,那麼對於 Java 編譯器來說,它並不會認爲該方法符合函數式接口的抽象方法(即不把該方法當作函數式接口的抽象方法)。因爲接口的實現類都會直接或間接繼承 Object 這個根類,所以在函數式接口中定義與 Object 類中籤名一樣的方法是不會導致函數式接口失效的。(參考:https://www.cnblogs.com/weixuqin/p/11494894.html)
3.注意:
如果某個接口只有一個抽象方法,但我們並沒有給該接口聲明 @FunctionalInterface
註解,那麼編譯器依舊會將該接口看作是函數式接口