基本上所有的Java教程都會告訴我們Java接口的方法都是public、abstract類型的,沒有方法體的。
但是在JDK8里面,你是可以突破這個界限的哦。
假設我們現在有一個接口:TimeClient,其代碼結構如下:
import java.time.*; public interface TimeClient { void setTime(int hour, int minute, int second); void setDate(int day, int month, int year); void setDateAndTime(int day, int month, int year, int hour, int minute, int second); LocalDateTime getLocalDateTime(); }
接下來,SimpleTimeClient類實現了TimeClient接口,具體代碼如下:
package defaultmethods; import java.time.*; import java.lang.*; import java.util.*; public class SimpleTimeClient implements TimeClient { private LocalDateTime dateAndTime; public SimpleTimeClient() { dateAndTime = LocalDateTime.now(); } public void setTime(int hour, int minute, int second) { LocalDate currentDate = LocalDate.from(dateAndTime); LocalTime timeToSet = LocalTime.of(hour, minute, second); dateAndTime = LocalDateTime.of(currentDate, timeToSet); } public void setDate(int day, int month, int year) { LocalDate dateToSet = LocalDate.of(day, month, year); LocalTime currentTime = LocalTime.from(dateAndTime); dateAndTime = LocalDateTime.of(dateToSet, currentTime); } public void setDateAndTime(int day, int month, int year, int hour, int minute, int second) { LocalDate dateToSet = LocalDate.of(day, month, year); LocalTime timeToSet = LocalTime.of(hour, minute, second); dateAndTime = LocalDateTime.of(dateToSet, timeToSet); } public LocalDateTime getLocalDateTime() { return dateAndTime; } public String toString() { return dateAndTime.toString(); } public static void main(String... args) { TimeClient myTimeClient = new SimpleTimeClient(); System.out.println(myTimeClient.toString()); } }
現在假設你想在接口TimeClient中添加一個新功能,通過這個功能我們可以指定我們所在的時區。
public interface TimeClient { void setTime(int hour, int minute, int second); void setDate(int day, int month, int year); void setDateAndTime(int day, int month, int year, int hour, int minute, int second); LocalDateTime getLocalDateTime(); ZonedDateTime getZonedDateTime(String zoneString); }
隨着TimeClient的變化,你不得不修改你的SimpleTimeClient類,實現getZonedDateTime方法。一般來說,設置時區這個功能會是各個TimeClient實現類中通用的一個功能。這個時候,你通常會選擇再定義一個AbstractTimeClient類來實現getZonedDateTime方法。而在JDK8中,你可以選擇直接在接口中來實現該方法(interface已經把手伸到abstract class的地盤了)。
package defaultmethods; import java.time.*; public interface TimeClient { void setTime(int hour, int minute, int second); void setDate(int day, int month, int year); void setDateAndTime(int day, int month, int year, int hour, int minute, int second); LocalDateTime getLocalDateTime(); static ZoneId getZoneId (String zoneString) { try { return ZoneId.of(zoneString); } catch (DateTimeException e) { System.err.println("Invalid time zone: " + zoneString + "; using default time zone instead."); return ZoneId.systemDefault(); } } default ZonedDateTime getZonedDateTime(String zoneString) { return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString)); } }
從上面的例子,我們可以看到通過static和default修飾符我們可以直接在接口中實現方法體,同時不要忘記,任何在接口中方法聲明都是public類型的哦。
OK,現在我們需要一個新的接口:AnotherTimeClient,它得繼承TimeClient接口。那么,對於TimeClient接口中定義的getZonedDateTime方法,你可以做如下三種處理:
- 重新聲明getZonedDateTime方法,使它變成abstract類型。
- 重新定義getZonedDateTime方法。
- 直接繼承。
而static方法和我們在類里面定義的static方法概念一致。