【Java8】默認方法

摘抄自 《Java8實戰》

Java 8中加入默認方法主要是爲了支持庫設計師,讓他們能夠寫出更容易改進的接口。這一方法很重要,因爲你會在接口中遇到越來越多的默認方法,但由於真正需要編寫默認方法的程序員相對較少,而且它們只是有助於程序改進,而不是用於編寫任何具體的程序,我們這裏還是不要囉嗦了,舉個例子吧。

List<Apple> heavyApples1 = inventory.stream().filter((Apple a) -> a.getWeight() > 150).collect(toList());

List<Apple> heavyApples2 = inventory.parallelStream().filter((Apple a) -> a.getWeight() > 150).collect(toList());

但這裏有個問題:在Java 8之前, List 並沒有 stream 或 parallelStream 方法,它實現 Collection 接口也沒有,因爲當初還沒有想到這些方法嘛!可沒有這些方法,這些代碼就不能編譯。換作你自己的接口的話,最簡單的解決方案就是讓Java 8的設計者把 stream 方法加入 Collection 接口並加入 ArrayList 類的實現。

可要是這樣做,對用戶來說就是噩夢了。有很多的替代集合框架都用Collection API實現了接口。但給接口加入一個新方法,意味着所有的實體類都必須爲其提供一個實現。語言設計者沒法控制 Collections 所有現有的實現,這下你就進退兩難了:你如何改變已發佈的接口而不破壞已有的實現呢?Java 8的解決方法就是打破最後一環——接口如今可以包含實現類沒有提供實現的方法簽名了!那誰來實現它呢?缺失的方法主體隨接口提供了(因此就有了默認實現),而不是由實現類提供。這就給接口設計者提供了一個擴充接口的方式,而不會破壞現有的代碼。Java 8在接口聲明中使用新的 default 關鍵字來表示這一點。

例如,在Java 8裏,你現在可以直接對 List 調用 sort 方法。它是用Java 8 List 接口中如下所示的默認方法實現的,它會調用 Collections.sort 靜態方法:

default void sort(Comparator<? super E> c) {
	Collections.sort(this, c);
}

這意味着 List 的任何實體類都不需要顯式實現 sort ,而在以前的Java版本中,除非提供了sort 的實現,否則這些實體類在重新編譯時都會失敗。不過慢着,一個類可以實現多個接口,不是嗎?那麼,如果在好幾個接口裏有多個默認實現,是否意味着Java中有了某種形式的多重繼承?是的,在某種程度上是這樣。Java 8用一些限制來避免出現類似於C++中臭名昭著的菱形繼承問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章