標籤:
在【0.3.1 Java簡介】中,有這麼一段話:“請注意:Java並非作為教學語言設計的。世界各地的大學在講授Java的過程中均遇到一些教學上的困難(如Java語言和API的快速升級),這些困難是電腦科學教育中一般性的挑戰。”
Java8中引入的預設方法,充分展示了Java平台概念的一致性與JDK向前相容之間的矛盾,而且以犧牲概念的一致性而滿足JDK向前相容。
1.理想與現實
【曾經】Java介面純粹是契約的集合,是一種程式設計的表達方式。從資料抽象的角度看,能夠在不定義class的同時又可以定義type,將是程式設計中強大而有用的機制。Java介面就是這些純粹的介面組成的資料抽象。Java介面只能夠擁有抽象方法,它不涉及任何實現,也不能建立其對象(這一點和抽象類別一致)。
多重繼承模型導致額外的複雜性,其中最著名的是鑽石問題或者叫“討嫌的菱形派生”(Dreadful Diamond onDerivation、DDD)。為什麼Java介面能夠避免多繼承的複雜性,關鍵在於它僅僅包含abstract方法。然而從設計的角度看,Java介面放棄了多繼承的內在/固有目標,而顯得是一個權宜之計。
【現在】Java8之前,介面不能升級。因為在介面中添加一個方法,會導致老版本介面的所有實作類別的中斷。λ運算式作為核心出現,為了配合λ運算式,JDK中Collection庫需要添加新的方法,如forEach(),stream()等,於是引入了預設方法(defender methods,Virtual extension methods)。它是庫/架構設計的程式員的後悔藥。對於以前的遺留代碼,大家都不知道有這個新方法,既不會調用,也不會去實現,如同不存在;編寫新代碼的程式員可以將它視為保底的方法體。類型層次中任何符合override規則的方法,優先於預設方法,因為遺留代碼可能正好有同樣的方法存在。
預設方法,理論上抹殺了Java介面與抽象類別的本質區別——前者是契約的集合,後者是介面與實現的結合體。當然,文法上兩者的差別和以前一樣。這就需要程式員來自覺維護兩者的本質區別,把預設方法作為庫、架構向前相容的手段。
預設方法的一個好處:多繼承的著名的是鑽石問題(The Diamond Problem )再次需要關注。因而使以前某些人認為的“為瞭解決多繼承問題而引入介面機制”的說法變成明顯的錯誤——以前也是錯誤的認識。
有關java1.8 的詳細說明參考 http://lucida.me/blog/java-8-lambdas-insideout-language-features/
java中的預設方法