[英]About the Java interface and polymorphism
我在閱讀Java doc時遇到了一個奇怪的案例。 以下是Arrays.asList方法中Oracle java文檔的鏈接, http: //docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#asList (T ...)
文檔中有一個例子
List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
我的問題是,由於List是一個接口,為什么我們可以將stooges聲明為'List',而不是實現List的具體子類(例如ArrayList或LinkedList)? 那么這是否意味着我們可以有一個接口類型的引用變量? 它看起來很奇怪,因為我一直認為接口只代表多態,我們永遠不應該真正使用接口類型變量。
有誰能請給我一些線索?
將List接口視為保證。 任何實現List的類都將保證具有接口的方法。 當Arrays.asList()返回一個List,你實際上並沒有獲得一個接口時, 你會得到一個具體的類,保證實現List接口中列出的方法 。
至於你的“我們永遠不應該真正使用接口類型變量”,你實際上是想這樣做。 它被稱為“編程到界面”。 如果你可以返回List而不是像LinkedList這樣的東西,它會更加靈活。 您的方法的調用者沒有耦合到您可能使用和返回LinkedList的特定實現內部實現。 如果在某些時候您想要返回ArrayList而不是LinkedList,則調用者不必更改任何代碼,因為他們只關心接口。
簡而言之,Serializable是一個標記界面,因此有點奇怪。 它並不保證方法存在,而是保證實現serializable的類的創建者已經考慮了與序列化類相關的許多問題(重寫readObject / writeObject,與其他序列化表單的兼容性以及其他問題http: //www.javapractices.com/topic/TopicAction.do?Id=45 )。 所以Serializable仍然提供像List一樣的保證,但它不是關於方法簽名,而是關於語言的語言特征。
使用接口作為引用類型是Java中完全有效的實踐。 例如, Serializable
接口將在它的類中執行此操作,以便可以序列化傳遞給它的任何對象。
這也是Java提供類似於多重繼承的東西的方式。 例如:
public interface A { }
public class B implements A {}
public class program {
B bClass = new B();
A aObject = (A)bClass;
}
這樣,可以使用不同的引用類型引用相同的對象,並且不會弄亂繼承鏈!
接口定義了實現的contract
或specification
。 哪種方法及其簽名。 因此,實現接口的類必須尊重該contract
。 這樣,您可以更改實現,而不會影響使用接口聲明變量的代碼。
在你提到的例子中:
除非您查看代碼,否則您不知道Arrays.asList
正在使用List
接口的實現。 那么你怎么知道使用哪一個? (有關列表界面,請參閱javadoc以了解它具有哪些實現)
實現可能會發生變化,如果Arrays.asList
決定使用其他實現呢? 你的代碼將被破壞。
方法Arrays.asList
的簽名是它返回List<T>
所以如果你想要一個具體的實現作為變量你必須Arrays.asList
那個不好的做法的返回值或創建新的 - 讓我們說ArrayList
- 和將所有元素復制到其中,這只是一個不必要的開銷。
Bloch的Effective Java是一本關於Java最佳實踐的好書。 特別是, 第52項討論了這個問題:“如果存在適當的接口類型......使用接口類型聲明。”
一般的概念是,為了獲得最大的靈活性和可理解性,您應該使用最能反映上下文的類型,通常是接口。 在這個例子中,您提供了確切的實現,或者只是它是一個List。 當然,如果代碼需要特定於ArrayList的方法,或者代碼依賴於特定於ArrayList的行為,那么請使用具體類。
偶爾有例外,例如使用GWT-RPC時 ,這是出於實現原因。
這是多態性能力的一個很好的例子,如果你喜歡你可以查看Arrays.asList()這里的Arrays.asList(T ... a)的源代碼,你會發現它需要varibale長度輸入並定義它自己的私有靜態具體類ArrayList實現List接口而不是使用眾所周知的java.util.ArrayList或其他java Collection類型,這可能是為了使它更高效或者某種東西,你想要實現自己的類並將它返回到用戶沒有通過實現細節壓倒他,因為有一個接口他可以處理你的私人課程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.