Java接口方法

接口方法聲明

可以在接口中聲明三種類型的方法:

  • 抽象方法
  • 靜態方法
  • 默認方法

在Java 8之前,只能在接口中聲明抽象方法。 修飾符staticdefault用於分別聲明靜態和默認方法。
不使用staticdefault修飾符就是方法抽象。

以下是具有所有三種類型方法的接口的示例:

interface AnInterface {
  // An abstract method
  int m1();

  // A static method 
  static int m2()  {
    // The method  implementation goes  here
  }

  // A default method
  default int m3() {
    // The method implementation goes here
  }
}

抽象方法聲明

接口中的所有方法聲明都是隱式抽象和公開的,除非它們聲明爲staticdefault。接口中的抽象方法沒有實現。抽象方法的主體總是由分號表示,而不是一對大括號。
下面的代碼聲明一個名爲Player的接口:

public interface Player {
  public abstract void play();

  public abstract void stop();

  public abstract void forward();

  public abstract void rewind();
}

Player 接口是音頻/視頻播放器的規範。真實的播放器,例如DVD播放器,將通過實現 Player 接口的所有四個方法來提供規範的具體實現。
在接口中使用 abstractpublic 關鍵字聲明方法中是多餘的。上面的Player接口的聲明可以改寫如下,而不改變其含義:

public interface  Player {
    void  play(); 
    void  stop(); 
    void  forward(); 
    void  rewind();
}

接口中的抽象方法聲明可以包括參數,返回類型和throws子句。

public interface NewPlayer {
  boolean play(int account) throws AccountNotFoundException;

  boolean stop(double amount);

  boolean forward(double amount) throws InsufficientBalanceException;

  double rewind();
}

接口的抽象方法由實現接口的類來實現,類重寫它們以提供方法並實現。接口中的抽象方法不能聲明爲final
類可以重寫聲明接口的方法爲final,指示子類不能覆蓋該方法。

靜態方法聲明

從Java 8,我們可以在接口中創建靜態方法。靜態方法包含靜態修飾符- static ,並且是隱式公開的。可以重新定義Walkable接口以包括letThemWalk()方法。

interface Walkable {
  // An abstract method 
  void walk();

  // A static convenience method
  public static void letThemWalk(Walkable[] list) {
    for (int i = 0; i < list.length; i++) {
      list[i].walk();
    }
  }
}

可以使用點表示法使用接口的靜態方法。如下代碼 -

<interface-name>.<static-method>

與類中的靜態方法不同,接口中的靜態方法不能通過實現類或子接口來繼承。從另一個接口繼承的接口稱爲子接口。 只有一種方法來調用接口的靜態方法:使用接口名稱。例如:
必須使用MyInterface.myStaticMethod()調用接口MyInterface的靜態方法myStaticMethod()

可以使用方法的非限定名稱myStaticMethod()來調用它,這僅在接口的主體中,或者當使用靜態import語句導入方法時可這樣使用。

默認方法聲明

接口中的默認方法使用修辭符-default來聲明。默認方法是在Java 8中添加新功能。默認方法爲實現接口的類提供了一個默認實現,但不覆蓋默認方法。
假設,有以下的一個接口。

interface Shape{
  void setX(double x);
  void setY(double y);
  double getX();
  double getY();
}

下面的代碼顯示了 Circle 類實現了 Shape 接口。

class Circle implements Movable {
  private double x;
  private double y;

  public Circle() {
  }

  public Circle(double x, double y) {
    this.x = x;
    this.y = y;
  }

  public void setX(double x) {
    this.x = x;
  }

  public void setY(double y) {
    this.y = y;
  }

  public double getX() {
    return x;
  }

  public double getY() {
    return y;
  }

  public String toString() {
    return "Circle(" + x + ", " + y + ")";
  }
}

如果向Shape添加一個新方法如下。

interface Shape {
  void setX(double x);

  void setY(double y);

  double getX();

  double getY();

  void move(double deltaX, double deltaY);
}

在Java 8之前,新方法move()是一個抽象方法。 所有實現Shape接口的類都必須提供這個新方法的實現。
實現Shape接口的Pen類將不能通過編譯,除非將新方法添加實現到這些類中。在Java 8之前,在將接口分配給公共接口之後,在中斷實現接口方法代碼的情況下,向接口添加方法是不可能的。
所以,引入了Java接口默認方法這個解決方案。可以將默認方法添加到現有接口,併爲該方法提供默認實現而不用在實現接口的類中實現這個默認方法。

所有實現接口的類都將繼承默認實現。類可以選擇覆蓋默認實現或使用方法的默認實現。

默認方法使用關鍵字default聲明。 默認方法不能聲明爲abstractstatic。 它必須提供一個實現。 否則將在編譯時發生錯誤。
以下代碼使用默認方法更改Shape接口。

interface Movable {
  void setX(double x);

  void setY(double y);

  double getX();

  double getY();

  // 一個默認的方法
  default void move(double deltaX, double deltaY) {
    double newX = getX() + deltaX;
    double newY = getY() + deltaY;
    setX(newX);
    setY(newY);
  }
}

以下項目列出了類方法和接口默認方法之間的相似點和差異。

  • 兩者都可以以相同的方式訪問關鍵字this。 關鍵字this是調用方法的對象的引用。
  • 類一個具體方法可以訪問類的實例變量。
  • 默認方法不能訪問實現接口的類的變量的實例。
  • 默認方法可以訪問接口的其他成員。
  • 兩種類型的方法都可以使用它們的參數。
  • 兩個方法都可以有一個throws子句。
  • 接口中的嵌套類型聲明定義了一個新的引用類型。
  • 可以將一個類,接口,枚舉和註釋聲明爲嵌套類型。
  • 在接口內聲明的接口/類稱爲嵌套接口/類。
  • 接口和類定義新的引用類型,因此做嵌套接口和嵌套類。
  • 嵌套接口始終通過其封裝接口訪問。
  • 可以在接口中聲明一個嵌套類。

參考以下一個具有嵌套類和常量字段的Task接口。

interface Task {
  class EmptyTask implements Task {
    private EmptyTask() {
    }
    public void runJob() {
      System.out.println("Empty...");
    }
  }
  // A constant field
  Task EMPTY_JOB = new EmptyTask();
  void runJob();
}

public class Main {
  public static void main(String[] args) {
    submitJob(Task.EMPTY_JOB);
  }
  public static void submitJob(Task job) {
    job.runJob();
  }
}

Java接口方法 # Java_interface_Methods