java中接口什么时候用_我什么时候应该在java中使用接口?
在Java中精確使用接口的一個很好的例子將是理想的,適用于任何特定的規則。
看看丹以前所有的問題,他似乎只是逐字逐句地張貼家庭作業/考試問題。
令人驚訝的是,這些不是考試題或其他…今天才找到這個網站,所以我想我會在腦子里想辦法得到一些答案。謝謝你的回復,每個人都非常有助于我找到正確的方向。
已經有很多問題了。你找到了搜索框,以防有人以前問過類似的問題?
值得一看的是集合框架。
java.util.List //interface
java.util.ArrayList //Concrete class
java.util.LinkedList //Concrete class
所以你可以這樣寫代碼:
List l = new ArrayList();
l.add(..)
//do something else.
如果將來您希望使用上述LinkedList或您自己的AwesomeList which implements List接口更改實現,那么您所要做的就是將第一行更改為:
List l = new MyAwesomeList();
or
List l = new LinkedList();
其余的代碼將繼續執行。
我知道這是一條舊線,但這一點讓我非常清楚。+ 1
這是理解接口的簡單和最佳方法。
使用接口定義"第三方"供應商必須完全遵守和實施的應用程序編程合同(藍圖、接口)。這樣,最終用戶就可以根據API契約進行編碼,并且可以輕松地在不更改代碼的情況下切換具體實現"在引擎蓋下"。
JDBCAPI是一個很好的例子。它幾乎只存在接口。具體實現作為"JDBC驅動程序"提供。這使您能夠獨立于數據庫(DB)供應商編寫所有JDBC代碼。只要您想切換DB供應商,就可以更改JDBC驅動程序而不更改任何Java代碼行(除了任何硬編碼的特定于B的SQL代碼)。
另一個例子是JavaEE API,它也包含相當多的接口和抽象類。具體的實現提供為"JavaEE應用服務器"、"ServelPosits"等,如Sun GalasFISH、Apache Tomcat等。這使得您可以將WebApvices(WAR)部署到任何您喜歡的Java Web服務器。
JDBCAPI是過時設計的一個例子,這不是真的嗎?里面有很多沒有人使用的接口。DB供應商通常提供javax.sql的一些實現,但實現連接池的庫幾乎從不使用它們,通常只需要Driver實現。現在真的有必要有Statement和PreparedStatement嗎?應該有一種更好的方法來設計一個ResultSet接口,也許可以通過使用泛型來減少getXX()和updateXXX()方法的數量。
在程序中預期波動的地方、預期變化的地方、設計需要彎曲的地方都需要接口。
從這個意義上說,實現是脆弱的:它很容易中斷。這就是為什么子類化并不總是最好的解決方案,正如實現一些復雜行為的長循環方法通常是一個壞主意一樣。
接口更加靈活,可以處理比實現更大的程序設計壓力。
通過在程序中引入接口,您實際上引入了一些變化點,在這些變化點上您可以為該接口插入不同的實現。接口的主要目的是抽象,將"什么"與"如何"分離開來。
一個重要的規則要記住,這樣做是安全的利斯科夫替代原則[Unbebob,維基百科]。雖然像Java這樣的語言編譯器會確保語法上一切都是有序的(正確的參數、類型、……),LSP處理語義。簡而言之,LSP說接口的每一個實現都必須(也)正確地表現自己,才能像上面描述的那樣真正具有可替換性。
謝謝你的回答!對于其他任何閱讀這篇文章的人來說:Unbebob鏈接已經死了,因為他有了一個新的網站/域。不過,這篇文章仍在他的谷歌硬盤上。通過搜索他的文章頁面找到它
從Oracle文檔頁
如果出現以下情況,請考慮使用接口:
您期望不相關的類實現您的接口。例如,許多不相關的對象可以實現可序列化的接口。
您希望指定特定數據類型的行為,但不關心誰實現了它的行為。
您希望利用類型的多重繼承。
用已經有很好答案的代碼示例來看看相關的SE問題。
一個接口是否比正確的方法更重要?
接口和抽象類有什么區別?
我應該如何解釋接口和抽象類之間的區別?
試著理解戰略設計模式
或者命令模式
在鏈接文本中查看JDK集合教程。想想收藏品。你怎么想的?可以訂購,也可以不訂購,也可以有副本。
所以集合是一個具有列表(有序)和設置(無序)為子接口的接口。現在有很多關于列表的問題,如果它是同步的/或不同步的,如果它是鏈接的列表或不同步的,等等。每個"行為"都有自己的接口/抽象類。
當需要在集合中指定"某些"行為時,需要使用抽象類。例如,所有集合(集合/列表等)都可以有一個"ToString"表示,它只是迭代元素(有序/非有序)并將它們串接。這種行為可以出現在"抽象集合"等中。
如果您遵循JDK集合的層次結構,那么它是了解接口和抽象類的一個很好的地方:)
這個答案基本上和最酷的大腦是一樣的,只是在傳達有用性時更明確一點。
正如最酷的頭所解釋的,當您將來可能想要切換程序的可能子組件時,接口是有用的。它們還允許您更容易地分離程序結構各個部分的關注點,因為通過接口,您可以確保某些非相關類等對程序的其他部分不可見。
例如,假設您希望讀取任意數據并打印它,如下所示:
SomeReader someReader = new SomeReader();
String data = someReader.readLine();
System.out.println(data);
這里沒什么特別之處,對吧?但是,雖然這個例子很簡單,但它已經綁定到SomeReader類,這意味著對該類所做的所有更改都必須傳播到您使用該類的類中,特別是在重構某些內部部分時!相反,你想這樣做
IMyReader reader = new SomeReader();
System.out.println(reader.readLine());
現在打印代碼不再關心具體的實現,只關心接口所暴露的部分。這通常就足夠了,因為現在您只需切換一條new語句,就可以得到新的實現,以及任何仍按預期工作的實現(只要接口的契約在實現類中得到尊重!)。當您最終多次使用某個特定對象時,這特別方便-這里我只使用一次,但實際上,如果您使用的是例如列表,那么通常要執行多少個相同的列表操作?
所以,為了真正地打破這個例子的比例,下面是您的代碼最終可能會變成的樣子
public class RowPrinter {
private final IMyReader reader;
public RowPrinter(IMyReader reader) {
this.reader = reader;
}
public void print() {
IMyReader reader = getReader();
System.out.println(reader.readLine());
}
protected IMyReader getReader() {
return reader;
}
}
注意到這個部分和構造函數有關嗎?這是控制反轉,讓我告訴你,這是一個很酷的軟件工程。我可以根據經驗說,它可以幫助您解決很多麻煩,無論是從數據庫產品切換到另一個產品,還是使代碼的某些部分線程安全。或者,您可能只想向某個類添加一個日志記錄層,使用包裝修飾器很容易實現,而包裝修飾器恰好實現了與包裝類相同的接口。這只是開始。
界面帶來了很多好處,從簡單的例子中通常不那么明顯,盡管簡單的例子確實能讓你正常地工作。雖然Java中的接口是一種語言構造,但實際上它們更像是一種編程范式,而不僅僅是單個語言的特性,在某些語言中,如果正確地理解接口,那么仿真接口真的是有益的。
基本上,當需要"忽略"一些實現細節時,可以在接口和抽象類之間進行選擇。接口通常是更好的選擇,因為客戶機類可以實現任意數量的接口,但它們只能有一個超類("繼承是一種稀缺的資源",正如他們所說)。
為什么要抽象類或接口?因為有時候,當你寫一個算法的時候,你并不關心它的一個子步驟是如何完成的,只是它是根據某種契約完成的。集合API就是一個例子,其中list是一個接口——通常,當您使用List時,您不會真正關心它是在數組中保存東西,還是在節點的鏈接列表中保存東西,或者以其他方式保存東西。只要它把你放在里面的東西按你放在那里的順序放好,你就會很高興。
然后我們有了AbstractList:一個實現List的抽象類,它提供了幾乎所有成熟List需要的實現,要創建自己的List實現,您所要做的就是擴展AbstractList并填充一些方法。這是一個很好的例子,當抽象類是一個很好的選擇時——當你想要提供一個幾乎完全的實現,這只是缺少一些需要由客戶機代碼填充的空白。
提示:如果您創建一個只包含抽象方法的抽象類,那么您可能應該創建它的接口。
當您需要相同行為的多個實現時,將使用接口。下面是一個接口示例,對象可以實現該接口,以顯示它們都可以序列化為XML。
public interface Xmlizable
{
public String toXML();
}
然后您可以將"可xmlizable"接口傳遞給只關心該接口的方法。
在這個例子中,在將toXML傳遞給公共代碼之前,您可以再次調用它。
遠程通信接口:
接口還可以用來定義一個商定的"協議",用于在系統的不同部分之間通信,可能通過遠程調用。因此,接口只定義可以調用的內容、參數以及調用后返回的內容。例如,客戶機使用接口,服務器實現具體的實際代碼。
邊注:
在爪哇中,只能從一個類中繼承(擴展),但可以實現多個接口,因此有時需要使用多個繼承的接口,并且在決定不使用構造函數繼承時使用接口。
OOP的一個基本原則是信息隱藏:隱藏實現細節,只向調用者顯示基本服務的描述。
Java必須為這個目標構建:接口和抽象類。您可以通過調用接口中定義的"可用方法",定義接口并編寫代碼,使其僅依賴于接口。
信息隱藏既可用于讀取外部類(從某種意義上說是外部的,它在您正在編寫的模塊之外),這樣您就可以定義您需要的方法,而無需推斷其具體的實現類型,或者在定義可在類外使用的數據類型時,這是一個典型的示例,例如C像前面提到的那樣,集合API或J2EE。
接口和抽象類都提供了這些細節——但是有兩個主要的區別:接口支持多個繼承,而抽象類可以保存基本實現。為了最大限度地提高效率,在定義接口時,還應該使用有意義的默認實現定義一個抽象類。如果接口的用戶不需要擴展任何其他類,那么它可以擴展這個抽象類,否則它需要從接口實現所有方法。另一方面,確保不要直接讀取這個抽象類,接口應該足夠抽象。
每當您計劃在某個開發點用另一個類替換一個實現類時,都要使用接口。
我還建議至少在更嚴肅的項目中使用繼承接口中的所有類的接口后端:不幸的是,我不再有鏈接,但是語言Java的開發者曾經說過,包括類繼承是設計語言時最大的錯誤。
這些參數非常好:使用適當的設計,總是可以用接口繼承來替換類繼承,并且在代碼維護方面獲得了很多好處。與類繼承相比,保存自然類型關系(例如,從幾何圖形("正方形是矩形")更容易。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的java中接口什么时候用_我什么时候应该在java中使用接口?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java数据类型代表价格_解读Java数
- 下一篇: java returnaddress_J