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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/287049.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/287049.shtml
英文地址,請注明出處:http://en.pswp.cn/news/287049.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

WPF效果第一百八十五篇之又玩TreeView

最近又有新的開發任務了,然后我提前瞄了一眼需要實現的效果;發現其中一個和我去年玩耍的有點類似;正好好久也沒玩了,那就趁著這個機會再次學習一下;閑話也不多扯了,上效果:2、來看看我的實現方式:3、①是一個分組的數據模板<HierarchicalDataTemplate x:Key"GroupDataT…

ArcGIS實驗教程——實驗二十三:專題地圖制作完整實驗步驟

ArcGIS實驗視頻教程合集:《ArcGIS實驗教程從入門到精通》(附配套實驗數據) 一、實驗描述 專題地圖是一個非常復雜的過程,地圖數據的符號化與注記標注,都是地圖編制準備基礎的地理數據。然而,要將準備好的地圖數據,通過一幅完整的地圖表達出來,還有很多工作,包括布局…

IOS 封裝輪播圖

輪播圖為一種常見的方式&#xff0c;常用于各種網站&#xff0c;或者App中&#xff0c;當然&#xff0c;作為APP的啟動視圖也是不錯的選擇。 閑時封裝了一個&#xff0c;僅供新手參考。 1.新建工程&#xff0c;建立輪播圖類 建立一個空的工程&#xff0c;新建一個類&#xff0c…

分布式事務TCC補償機制

文章目錄 概述工作流程優缺點優點&#xff1a;缺點&#xff1a; 總結Java 示例代碼 概述 TCC&#xff08;Try-Confirm-Cancel&#xff09;補償機制是一種事務處理模式&#xff0c;用于確保分布式系統中的操作成功完成或在失敗時進行補償。TCC將一個事務拆分為三個階段&#xf…

oracle的本地安裝和PUTTY+XMING遠程連接安裝和oracle翻頁功能

因為我也是一個初學者&#xff0c;所以可能有出錯的地方&#xff0c;如果有希望大家告訴我QQ:7343696.大家公共學習&#xff0c;進步。Oracle的安裝實驗的環境是vmware server 1.06 rehl 5.2最小安裝。oracle安裝的要求。1建議的內存1G&#xff08;10g&#xff09; 9i中是51…

Flutter之導url_launcher包提示 A dependency may only have one source.

1、問題 flutter項目在pubspec.yaml導入url_launcher包&#xff0c;然后點擊Pub get錯誤提示如下 F:\flutter_sdk\flutter\bin\flutter.bat --no-color pub get Running "flutter pub get" in flutter_1... Error on line 25, column 5 of …

這是我第一次使用代碼創建出一個窗口【python 游戲實戰 01】

前言 本系列文章將會以通俗易懂的對話方式進行教學&#xff0c;對話中將涵蓋了新手在學習中的一般問題。此系列將會持續更新&#xff0c;包括別的語言以及實戰都將使用對話的方式進行教學&#xff0c;基礎編程語言教學適用于零基礎小白&#xff0c;之后實戰課程也將會逐步更新…

如何html中添加動態圖片,把動態圖片添加到視頻畫面中 視頻添加自定義動態圖片 視頻加動態logo...

我前面也編寫過關于視頻添加動態圖片的教程。前面所說的給是視頻添加的動態圖片是軟件中自帶的素材&#xff0c;雖然軟件中帶的動態圖片種類繁多&#xff0c;但是不外乎有些時候軟件中并沒有我們要用的動態圖片&#xff0c;這個時候我們就需要重外部添加啦&#xff0c;好多的軟…

ASP.NET Core 集成AAD認證在Docker中運行時要注意的一個問題

最近我在準備一個分享&#xff0c;就是基于.NET 6.0的云原生開發Microsoft 365應用&#xff0c;這個看起來很高大上的東東&#xff0c;其實我理解主要就是能把應用容器化&#xff0c;便于與環境無關地進行分發和部署。如果理解有誤&#xff0c;請大家糾正我。下面是其中的一個例…

QCon上海2015精彩回顧和總結

金秋十月&#xff0c;歷時三天的QCon上海2015于10月17日順利閉幕。本次大會邀請了100多位技術專家&#xff0c;為參會者奉上了100多場精彩的技術演講。\\本次QCon邀請了極客邦創始人兼CEO霍泰穩&#xff0c;攜程旅行網CTO、高級技術副總裁葉亞明&#xff0c;丁香園技術VP、EGO上…

ArcGIS中合并(merge)、聯合(union)、追加(append)、融合(dissolve)的用法區別與聯系

ArcGIS中,針對矢量數據拼接,有多個工具:合并(merge)、聯合(union)、追加(append)、融合(dissolve)等,本文以甘肅省1:100萬縣級數據詳細講解以上各個工具的用法、區別和注意事項。 有關合并(merge)、聯合(union)、追加(append)、融合(dissolve)等基礎操作內…

Singleton

問題&#xff1a;編寫一個Singleton類 簡單的方式 1 package cn.changb.singleton;2 3 /**4 * 簡單的方式:弊端是在并發執行時&#xff0c;14行處可能存在多個實例5 */6 public class SingletonDemo1 {7 private static SingletonDemo1 INSTANCE;8 9 private Singlet…

Flutter之運行提示Could not update files on device: Connection closed before full header was received

1 問題 運行flutter app提示錯誤如下 Performing hot restart... Syncing files to device MIX 3... Could not update files on device: HttpException: Connection closed before full header was received, uri http://127.0.0.1:65054/-tzvW6oGieQ/ Restarted applicati…

C++ 語法都不會怎么寫代碼? 03

作者簡介 作者名&#xff1a;1_bit 簡介&#xff1a;CSDN博客專家&#xff0c;2020年博客之星TOP5&#xff0c;藍橋簽約作者。15-16年曾在網上直播&#xff0c;帶領一批程序小白走上程序員之路。歡迎各位小白加我咨詢我相關信息&#xff0c;迷茫的你會找到答案。系列教程將會…

自定義dialog彈窗html,自定義H5頁面dialog彈窗

彈窗一&#xff1a;樣式如下&#xff1a;HTML代碼&#xff1a;//彈出窗通知取消確認//遮罩層$(.dialog .content).text(text);$(.dialog, .mark).removeClass(hide);}tipDialog("1111");$(".sure").click(function(){var type $(this).attr(type);if(typeb…

【三維激光掃描】第二章:國內外三維激光掃描設備簡介

地面三維激光掃描儀是地面激光掃描系統中最主要的硬件設備,近年來得到了快速發展,主要體現在品牌數量、性能指標、類型等方面的變化。本章主要介紹國內外主要設備的基本情況,對國內外研究現狀進行分析,最后指出目前存在的問題與未來的發展趨勢。 2.1 國外地面三維激光掃描儀…

Winform定時啟動

System.Timers.Timer t;int sum 0;int qian;int bai;int shi;int ge;public 測試定時啟動(){InitializeComponent();}//1.使用System.Timers.Timer//2.threadThread th;//定義線程private void 測試定時啟動_Load(object sender, EventArgs e){textBox1.Text "00.00&quo…

聊一聊容器暫停退出

1背景介紹 最近在寫 docker 相關教程&#xff0c;過程中發現容器暫停退出竟然有 docker kill、docker stop 和 docker pause 三種方式&#xff0c;今天就來分析下三者間的區別。2輔助指令 docker top - 查看容器進程docker event - 查看容器相關事件docker stats -…

初學者必看的文章:在VM12中安裝 RedHat RHEL7.2??系統的詳細步驟:看我如何操縱RHEL系統...

一、開始安裝 1&#xff09;新建虛擬機 RHEL7.2 2&#xff09;成功引導系統--開機出現此畫面 Install Red Hat EnterpriseLinux 7.2 安裝RHLE7.2 操作系統 Test this edia & install RedHat Enterpris…

Flutter之點擊按鈕打開百度鏈接

1 需求 點擊按鈕&#xff0c;打開百度鏈接 2 代碼實現 import package:flutter/material.dart; import package:url_launcher/url_launcher.dart;void main() {runApp(MyApp1()); }class MyApp1 extends StatelessWidget {overrideWidget build(BuildContext context) {return…