可以在介面中宣告三種型別的方法:
在Java 8之前,只能在介面中宣告抽象方法。 修飾符static
和default
用於分別宣告靜態和預設方法。
不使用static
和default
修飾符就是方法抽象。
以下是具有所有三種型別方法的介面的範例:
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
}
}
介面中的所有方法宣告都是隱式抽象和公開的,除非它們宣告為static
或default
。介面中的抽象方法沒有實現。抽象方法的主體總是由分號表示,而不是一對大括號。
下面的程式碼宣告一個名為Player
的介面:
public interface Player {
public abstract void play();
public abstract void stop();
public abstract void forward();
public abstract void rewind();
}
Player
介面是音訊/視訊播放器的規範。真實的播放器,例如DVD
播放器,將通過實現 Player
介面的所有四個方法來提供規範的具體實現。
在介面中使用 abstract
和 public
關鍵字宣告方法中是多餘的。上面的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
宣告。 預設方法不能宣告為abstract
或static
。 它必須提供一個實現。 否則將在編譯時發生錯誤。
以下程式碼使用預設方法更改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