教你在Java介面中定義方法

K太狼發表於2016-03-20

基本上所有的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方法,你可以做如下三種處理:

  1. 重新宣告getZonedDateTime方法,使它變成abstract型別。
  2. 重新定義getZonedDateTime方法。
  3. 直接繼承。

而static方法和我們在類裡面定義的static方法概念一致。

相關文章