Java8接口之默認方法與靜態(tài)方法詳解
前言
在Java8之前,java中的接口只能有抽象方法。默認情況下,接口的所有方法都是公共和抽象的。Java8允許接口具有默認和靜態(tài)方法。我們在接口中使用默認方法的原因是,允許開發(fā)人員向接口添加新方法,而不會影響實現(xiàn)這些接口的類。
為什么選擇默認方法?
例如,如果A、B、C和D等幾個類實現(xiàn)了一個接口XYZInterface,那么如果我們向XYZInterface添加一個新方法,我們必須更改實現(xiàn)該接口的所有類(A、B、C和D)中的代碼。在本例中,我們只有四個類實現(xiàn)了我們想要更改的接口,但是想象一下,如果有數(shù)百個類實現(xiàn)了一個接口,那么幾乎不可能更改所有這些類中的代碼。這就是為什么在Java8中,我們有了一個新概念“默認方法”。這些方法可以添加到任何現(xiàn)有接口中,我們不需要強制在實現(xiàn)類中實現(xiàn)這些方法,因此我們可以在不破壞代碼的情況下將這些默認方法添加到現(xiàn)有接口中。
我們可以說,java 8中引入了默認方法的概念,以便在現(xiàn)有接口中添加新方法,從而使它們向后兼容。向后兼容性是在不破壞舊代碼的情況下添加新功能。
接口中的靜態(tài)方法與默認方法類似,只是我們不能在實現(xiàn)這些接口的類中重寫這些方法。
Java 8示例:接口中的默認方法
MyInterface中的方法newMethod()是默認方法,這意味著我們不需要在實現(xiàn)類示例中實現(xiàn)該方法。通過這種方式,我們可以將默認方法添加到現(xiàn)有接口中,而不必擔心實現(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)方法與默認方法類似,因此我們不需要在實現(xiàn)類中實現(xiàn)它們。我們可以安全地將它們添加到現(xiàn)有接口中,而無需更改實現(xiàn)類中的代碼。由于這些方法是靜態(tài)的,我們不能在實現(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 - 抽象類與接口
隨著接口中默認方法的引入,抽象類似乎與Java8中的接口相同。然而,這并不是完全正確的,盡管我們現(xiàn)在可以像抽象類一樣在接口中有具體的方法(帶主體的方法),但這并不意味著它們是相同的。它們之間仍然沒有什么區(qū)別,其中之一是抽象類可以有構造函數(shù),而在接口中我們不能有構造函數(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); } 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
這是因為我們在接口中都有相同的方法,而編譯器不確定要調用哪個方法。
如何解決這個問題?
為了解決這個問題,我們可以在實現(xià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); } //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之類的,它們接口中的方法都是抽象方法,沒有具體的實現(xiàn),就相當于定義好了這個接口有哪些功能,卻沒有具體定義功能是怎么實現(xiàn)的,通常由接口的實現(xiàn)類來做具體功能實現(xiàn)。那么,如果面向接口編程,大家已經根據自己需要通過繼承接口的方式來實現(xiàn)了自己的功能,突然有一天,產品提需求了,你需要給所有接口的實現(xiàn)類都添加一個新的功能即一個新的方法實現(xiàn),而且這個方法可能大家都是一樣的,那咋辦?
jdk8以前的做法肯定是現(xiàn)在接口中定義這個抽象方法,然后所有實現(xiàn)類必須實現(xiàn)這個方法(不然接口中多出一個抽象方法,其他類都沒有實現(xiàn),編譯是會報錯的),如果實現(xiàn)類比較多,那改起來會很麻煩,這種情況下是不利于維護的。
那么我們在jdk8中就有了好的解決方式,就是在接口中加一個默認方法,這個默認方法有具體實現(xiàn),這樣就不用去修改實現(xiàn)類啦,很省事。
總結
到此這篇關于Java8接口之默認方法與靜態(tài)方法的文章就介紹到這了,更多相關Java8默認方法與靜態(tài)方法內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot項目中如何實現(xiàn)MySQL讀寫分離詳解
在高并發(fā)下需要對應用進行讀寫分離,配置多數(shù)據源,即寫操作走主庫,讀操作則走從庫,主從數(shù)據庫負責各自的讀和寫,緩解了鎖的爭用,提高了讀取性能,這篇文章主要給大家介紹了關于SpringBoot項目中如何實現(xiàn)MySQL讀寫分離的相關資料,需要的朋友可以參考下2022-07-07Java使用jacob將微軟office中word、excel、ppt轉成pdf
這篇文章主要為大家詳細介紹了Java使用jacob將微軟office中word、excel、ppt轉成pdf,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-12-12java 結合jQuery實現(xiàn)跨域名獲取數(shù)據的方法
下面小編就為大家?guī)硪黄猨ava 結合jQuery實現(xiàn)跨域名獲取數(shù)據的方法。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-05-05Struts2中ognl遍歷數(shù)組,list和map方法詳解
這篇文章主要介紹了Struts2中ognl遍歷數(shù)組,list和map方法詳解,需要的朋友可以參考下。2017-09-09