日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java1.8--改进的接口

發布時間:2023/12/9 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java1.8--改进的接口 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
關于接口,每天的編碼都在寫,就不多說了。這里對比下接口,抽象類,類3者的關系:
1),接口是一種規范,就是告訴外界這個東東可以做什么。
2),抽象類是一種模板,就是告訴外界這個東西的一部分公共功能。
3),類和上面的接口,抽象類最大的區別就是類可以維護狀態信息。

  • 在以前的接口中
1,沒有構造方法,不能實例化
2,接口只能繼承接口,不能繼承類
3,接口里沒有普通方法,方法全是抽象的
4,接口里的方法默認修飾符是public abstract
5,接口里的字段全是全局常量,默認修飾符是public static final


java8中的接口在原來的基礎上增加了一些功能,主要是2個:默認方法,靜態方法。
  • 1,默認方法
首先來了解下為什么會出現默認方法這個東西。許多開發語言都將函數表達式集成到了其集合庫中,這樣子比循環方式所需的代碼更少,并且更加容易理解。比如以前我們寫循環代碼:
for(int i = 0; i<list.size();i++) {System.out.println(list.get(i)); }
現在我們使用函數函數式編程,代碼如下:
public static void main(String[] args){List<Integer> list = Lists.newArrayList(1, 2, 3);Stream<Integer> stream = list.stream();stream.forEach(System.out::println);}現在假設我們自己不用流,我們想直接在list集合上面提供一個forEach方法,用來將一個函數應用到集合的每一個元素上面。下面是使用這種方式編寫的代碼:
list.forEach(System.out::println);上面的效果很好,如果我們自己定義也就是說重新設計集合當然是沒有問題的,但是java的集合是許多年前設計的,這就會帶來一個問題,我們為List接口增加了一個方法,那么所有的實現類都要改過,這樣子代碼才不會報錯,這基本是無法想象的。所以呢,java設計者希望通過允許接口包含具體實現的方法來一勞永逸的解決這個問題。當然,為接口提供默認方法還有別的好處,我們一會會整理到。
java8中允許在接口中定義默認方法,默認方法必須使用default來修飾。先來看一個例子,熟悉下java8中默認方法的語法:
public class Test implements TestInterface {public static void main(String[] args){Test test = new Test();//使用自己類中的方法System.out.println(test.getId());//使用接口中的默認方法System.out.println(test.getName());}@Overridepublic Integer getId(){return 25;}}interface TestInterface {Integer getId();default String getName(){return "默認方法里面的輸出。。。";} }
上面的代碼使用了TestInterface接口中定義的默認方法getName(),程序執行沒一點問題。當然我們也可以自己來重寫接口中默認方法中的默認方法。
public class Test implements TestInterface {public static void main(String[] args){Test test = new Test();//使用自己類中的方法System.out.println(test.getId());//使用接口中的默認方法System.out.println(test.getName());}@Overridepublic Integer getId(){return 25;}@Overridepublic String getName(){//默認使用接口中的默認方法,注意下面的使用父類接口中方法的語法//return TestInterface.super.getName();return "自己的類中重寫了接口中的默認方法";}}interface TestInterface {Integer getId();default String getName(){return "默認方法里面的輸出。。。";} }在上面的使用過程中,我們發現了現在使用java8接口的默認方法很好的解決了前面我說的問題了,我們不必在每個實現類中都去實現接口中新加的方法了,只需要在接口中增加一個default修飾的默認方法就好了。

另外,在上面的編碼過程中,我們不難還能發現一個使用默認方法帶來的好處,我們現在可以很方便的在接口中指定本質上可選的方法,根據接口的使用方式來選擇使用的方法。舉個例子吧,比如我們定義了一個接口,里面有一個刪除元素的方法remove(),但是實際情況是這個接口應該支持可修改和不可修改2種系列,在可修改系列中沒有問題,我們直接實現remove()方法就好了,不可修改系列我們不需要這個方法,但是也只能定義一個remove()的空實現,最好拋出一個異常。現在我們使用java8中的默認方法,就避免了用于不可修改系列的類也必須定義自己的,占位符性質的多余的方法,總結一下就是說默認方法讓一些類要去實現的方法變成了可選方法。

  • 總結一下:
默認方法提供了2個優點:
1,優雅的隨時間演化接口。也就是代碼的向后兼容性
2,提供可選功能,類不必在不需要該功能的時候提供占位符實現。


  • 2,多級繼承的問題
java中的繼承是單繼承,這個不多說了。現在考慮到接口新增的默認方法,現在java是不是繞開了單繼承呢?明顯不是。接口不能維護狀態信息,但是現在默認方法可以提供一些行為上面的多繼承。比如說一個類實現2個接口,在這2個接口中定義了2個默認方法,那么這個類同時拿到了2個方法,編碼確實多了很大的靈活性。但是也會有一個很明確也是必須要解決的問題,就是沖突問題,比如說A類實現了B接口,C接口,如果B和C接口都提供了一個叫test的默認方法,那A類將實現那個接口里面的test方法呢?又比如說A類提供了自己的實現,這時候將發生什么?又比如說A同時也繼承了一個有test方法的類,那么這個時候有事什么情況呢?


不慌的,解決上面的問題很簡單,就是定義一組規則就好了,按照一個約定來定義解決上面的沖突。具體的規則如下:
1),在所有的情況,類實現的優先級高于接口的默認實現,也就是先使用自己類中定義的方法或者是父類中的方法。類優先是解決上面系列問題的最主要的規則。
2),當類同時實現了2個接口,2個接口中如果包含相同的默認方法,那么這個類中就必須重寫這個接口,不然代碼報錯。
3),如果是一個接口繼承了另外一個接口,2個接口中也包含相同的默認方法,那么繼承接口的版本具有更高的優先級。比如A擴展了B接口,那么優先使用A類里面的test方法。
4),通過使用super,可以顯式的引用被繼承接口的默認實現,語法如下:InterfaceName.super.methodName()。
相關代碼如下:
public class Test extends C {public static void main(String[] args){Test test = new Test();System.out.println(test.getName());}}class C implements A, B {@Overridepublic Integer getId(){// TODO Auto-generated method stubreturn null;}//不管接口A和接口B中的這個方法是不是默認方法,有沒有提供實現都必須重寫, 不然代碼報錯@Overridepublic String getName(){System.out.println(A.super.getName());return "自己類中必須重寫這個方法。。。";}}interface A {Integer getId();default String getName(){return "接口A。。。";} }interface B {default String getName(){return "接口B。。。";}}
  • 3,在接口中使用靜態方法
在java8中為接口新增了一項功能,定義一個或者更多個靜態方法。類似于類中的靜態方法,接口定義的靜態方法可以獨立于任何對象調用。所以,在調用靜態方法時,不需要實現接口,也不需要接口的實例,也就是說哦和調用類的靜態方法的方式類似。語法如下:
接口名字.靜態方法名。
public class Test implements A {public static void main(String[] args){System.out.println(A.getName());}}interface A {static String getName(){return "接口A。。。";} }
注意,實現接口的類或者子接口不會繼承接口中的靜態方法。static不能和default同時使用。在java8中很多接口中都增加了靜態方法,比如下面代碼:
public class Test {public static void test(List<String> list){//直接使用Comparator的靜態方法list.sort(Comparator.comparing(String::length));}public static void main(String[] args){List<String> list = Lists.newArrayList("122","2","32");test(list);for (String str : list){System.out.println(str);}}}

轉載于:https://www.cnblogs.com/LinkinPark/p/5232972.html

總結

以上是生活随笔為你收集整理的java1.8--改进的接口的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。