Java8接口之默認(rèn)方法與靜態(tài)方法詳解
前言
在Java8之前,java中的接口只能有抽象方法。默認(rèn)情況下,接口的所有方法都是公共和抽象的。Java8允許接口具有默認(rèn)和靜態(tài)方法。我們在接口中使用默認(rèn)方法的原因是,允許開發(fā)人員向接口添加新方法,而不會影響實(shí)現(xiàn)這些接口的類。
為什么選擇默認(rèn)方法?
例如,如果A、B、C和D等幾個類實(shí)現(xiàn)了一個接口XYZInterface,那么如果我們向XYZInterface添加一個新方法,我們必須更改實(shí)現(xiàn)該接口的所有類(A、B、C和D)中的代碼。在本例中,我們只有四個類實(shí)現(xiàn)了我們想要更改的接口,但是想象一下,如果有數(shù)百個類實(shí)現(xiàn)了一個接口,那么幾乎不可能更改所有這些類中的代碼。這就是為什么在Java8中,我們有了一個新概念“默認(rèn)方法”。這些方法可以添加到任何現(xiàn)有接口中,我們不需要強(qiáng)制在實(shí)現(xiàn)類中實(shí)現(xiàn)這些方法,因此我們可以在不破壞代碼的情況下將這些默認(rèn)方法添加到現(xiàn)有接口中。
我們可以說,java 8中引入了默認(rèn)方法的概念,以便在現(xiàn)有接口中添加新方法,從而使它們向后兼容。向后兼容性是在不破壞舊代碼的情況下添加新功能。
接口中的靜態(tài)方法與默認(rèn)方法類似,只是我們不能在實(shí)現(xiàn)這些接口的類中重寫這些方法。
Java 8示例:接口中的默認(rèn)方法
MyInterface中的方法newMethod()是默認(rèn)方法,這意味著我們不需要在實(shí)現(xiàn)類示例中實(shí)現(xiàn)該方法。通過這種方式,我們可以將默認(rèn)方法添加到現(xiàn)有接口中,而不必?fù)?dān)心實(shí)現(xiàn)這些接口的類。
interface MyInterface{ /* This is a default method so we need not * to implement this method in the implementation * classes */ default void newMethod(){ System.out.println("Newly added default method"); } /* Already existing public and abstract method * We must need to implement this method in * implementation classes. */ void existingMethod(String str); } public class Example implements MyInterface{ // implementing abstract method public void existingMethod(String str){ System.out.println("String is: "+str); } public static void main(String[] args) { Example obj = new Example(); //calling the default method of interface obj.newMethod(); //calling the abstract method of interface obj.existingMethod("Java 8 is easy to learn"); } }
輸出:
Newly added default method
String is: Java 8 is easy to learn
Java 8示例:接口中的靜態(tài)方法
如上所述,接口中的靜態(tài)方法與默認(rèn)方法類似,因此我們不需要在實(shí)現(xiàn)類中實(shí)現(xiàn)它們。我們可以安全地將它們添加到現(xiàn)有接口中,而無需更改實(shí)現(xiàn)類中的代碼。由于這些方法是靜態(tài)的,我們不能在實(shí)現(xiàn)類中重寫它們。
interface MyInterface{ /* This is a default method so we need not * to implement this method in the implementation * classes */ default void newMethod(){ System.out.println("Newly added default method"); } /* This is a static method. Static method in interface is * similar to default method except that we cannot override * them in the implementation classes. * Similar to default methods, we need to implement these methods * in implementation classes so we can safely add them to the * existing interfaces. */ static void anotherNewMethod(){ System.out.println("Newly added static method"); } /* Already existing public and abstract method * We must need to implement this method in * implementation classes. */ void existingMethod(String str); } public class Example implements MyInterface{ // implementing abstract method public void existingMethod(String str){ System.out.println("String is: "+str); } public static void main(String[] args) { Example obj = new Example(); //calling the default method of interface obj.newMethod(); //calling the static method of interface MyInterface.anotherNewMethod(); //calling the abstract method of interface obj.existingMethod("Java 8 is easy to learn"); } }
輸出:
Newly added default method
Newly added static method
String is: Java 8 is easy to learn
Java 8 - 抽象類與接口
隨著接口中默認(rèn)方法的引入,抽象類似乎與Java8中的接口相同。然而,這并不是完全正確的,盡管我們現(xiàn)在可以像抽象類一樣在接口中有具體的方法(帶主體的方法),但這并不意味著它們是相同的。它們之間仍然沒有什么區(qū)別,其中之一是抽象類可以有構(gòu)造函數(shù),而在接口中我們不能有構(gòu)造函數(shù)。
接口的目的是提供完全抽象,而抽象類的目的是提供部分抽象。這仍然適用。界面就像是類的藍(lán)圖,通過引入默認(rèn)方法,您可以簡單地說,我們可以在界面中添加附加功能,而不會影響最終用戶類。
默認(rèn)方法和多重繼承
當(dāng)我們有兩個具有相同簽名的默認(rèn)方法的接口時,可能會出現(xiàn)多重繼承問題。讓我們舉個例子。
interface MyInterface{ default void newMethod(){ System.out.println("Newly added default method"); } void existingMethod(String str); } interface MyInterface2{ default void newMethod(){ System.out.println("Newly added default method"); } void disp(String str); } public class Example implements MyInterface, MyInterface2{ // implementing abstract methods public void existingMethod(String str){ System.out.println("String is: "+str); } public void disp(String str){ System.out.println("String is: "+str); } public static void main(String[] args) { Example obj = new Example(); //calling the default method of interface obj.newMethod(); } }
輸出:
Error: Duplicate default methods named newMethod with the parameters () and () are inherited from the types MyInterface2 and MyInterface
這是因?yàn)槲覀冊诮涌谥卸加邢嗤姆椒?,而編譯器不確定要調(diào)用哪個方法。
如何解決這個問題?
為了解決這個問題,我們可以在實(shí)現(xiàn)類中實(shí)現(xiàn)這個方法,如下所示:
interface MyInterface{ default void newMethod(){ System.out.println("Newly added default method"); } void existingMethod(String str); } interface MyInterface2{ default void newMethod(){ System.out.println("Newly added default method"); } void disp(String str); } public class Example implements MyInterface, MyInterface2{ // implementing abstract methods public void existingMethod(String str){ System.out.println("String is: "+str); } public void disp(String str){ System.out.println("String is: "+str); } //Implementation of duplicate default method public void newMethod(){ System.out.println("Implementation of default method"); } public static void main(String[] args) { Example obj = new Example(); //calling the default method of interface obj.newMethod(); } }
輸出:
Implementation of default method
首先我們要總體說一下,為什么要有這兩個方法存在:
(1)原先的jdk7之類的,它們接口中的方法都是抽象方法,沒有具體的實(shí)現(xiàn),就相當(dāng)于定義好了這個接口有哪些功能,卻沒有具體定義功能是怎么實(shí)現(xiàn)的,通常由接口的實(shí)現(xiàn)類來做具體功能實(shí)現(xiàn)。那么,如果面向接口編程,大家已經(jīng)根據(jù)自己需要通過繼承接口的方式來實(shí)現(xiàn)了自己的功能,突然有一天,產(chǎn)品提需求了,你需要給所有接口的實(shí)現(xiàn)類都添加一個新的功能即一個新的方法實(shí)現(xiàn),而且這個方法可能大家都是一樣的,那咋辦?
jdk8以前的做法肯定是現(xiàn)在接口中定義這個抽象方法,然后所有實(shí)現(xiàn)類必須實(shí)現(xiàn)這個方法(不然接口中多出一個抽象方法,其他類都沒有實(shí)現(xiàn),編譯是會報錯的),如果實(shí)現(xiàn)類比較多,那改起來會很麻煩,這種情況下是不利于維護(hù)的。
那么我們在jdk8中就有了好的解決方式,就是在接口中加一個默認(rèn)方法,這個默認(rèn)方法有具體實(shí)現(xiàn),這樣就不用去修改實(shí)現(xiàn)類啦,很省事。
總結(jié)
到此這篇關(guān)于Java8接口之默認(rèn)方法與靜態(tài)方法的文章就介紹到這了,更多相關(guān)Java8默認(rèn)方法與靜態(tài)方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot項(xiàng)目中如何實(shí)現(xiàn)MySQL讀寫分離詳解
在高并發(fā)下需要對應(yīng)用進(jìn)行讀寫分離,配置多數(shù)據(jù)源,即寫操作走主庫,讀操作則走從庫,主從數(shù)據(jù)庫負(fù)責(zé)各自的讀和寫,緩解了鎖的爭用,提高了讀取性能,這篇文章主要給大家介紹了關(guān)于SpringBoot項(xiàng)目中如何實(shí)現(xiàn)MySQL讀寫分離的相關(guān)資料,需要的朋友可以參考下2022-07-07Java使用jacob將微軟office中word、excel、ppt轉(zhuǎn)成pdf
這篇文章主要為大家詳細(xì)介紹了Java使用jacob將微軟office中word、excel、ppt轉(zhuǎn)成pdf,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-12-12java 結(jié)合jQuery實(shí)現(xiàn)跨域名獲取數(shù)據(jù)的方法
下面小編就為大家?guī)硪黄猨ava 結(jié)合jQuery實(shí)現(xiàn)跨域名獲取數(shù)據(jù)的方法。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-05-05Struts2中ognl遍歷數(shù)組,list和map方法詳解
這篇文章主要介紹了Struts2中ognl遍歷數(shù)組,list和map方法詳解,需要的朋友可以參考下。2017-09-09基于JAVA文件中獲取路徑及WEB應(yīng)用程序獲取路徑的方法
下面小編就為大家?guī)硪黄贘AVA文件中獲取路徑及WEB應(yīng)用程序獲取路徑的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11IDEA2020.1個性化設(shè)置的實(shí)現(xiàn)
這篇文章主要介紹了IDEA2020.1個性化設(shè)置的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08一文帶你看懂Android動畫的實(shí)現(xiàn)原理
動畫是 Android 應(yīng)用程序中重要的交互特性,ndroid 提供了多種動畫效果,包括平移、縮放、旋轉(zhuǎn)和透明度等,它們可以通過代碼或 XML 來實(shí)現(xiàn),本文將介紹 Android 動畫的原理和實(shí)現(xiàn)方法,并提供一些示例,需要的朋友可以參考下2023-07-07使用maven實(shí)現(xiàn)有關(guān)Jsoup簡單爬蟲的步驟
這篇文章主要介紹了使用maven實(shí)現(xiàn)有關(guān)Jsoup簡單爬蟲的步驟,文中附含詳細(xì)示例代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-09-09