在本教程中,我們將學(xué)習(xí)Java接口。我們將借助示例學(xué)習(xí)如何實(shí)現(xiàn)接口以及何時(shí)使用它們。
在Java中,接口定義了其他類必須實(shí)現(xiàn)的一組規(guī)范。例如,
interface Polygon { public void getArea(); }
這里Polygon是一個(gè)接口。我們使用了interface關(guān)鍵字來聲明一個(gè)接口。
getArea()方法是在Polygon接口中定義的規(guī)范,所有使用此接口的類都必須實(shí)現(xiàn)getArea()方法。
接口可以包含抽象方法和常量。例如,
interface Polygon { public static final String color = "blue"; public void getArea(); }
在上面的示例中,我們創(chuàng)建了一個(gè)接口Polygon。它包括一個(gè)常量變量color和一個(gè)抽象方法getArea()。
重要的是要注意,接口內(nèi)的所有方法都是隱式的public,所有字段都是隱式的public static final。因此,不必在接口內(nèi)部指定訪問說明符。例如,我們可以將上面的代碼編寫為
interface Polygon { String color = "blue"; void getArea(); }
像抽象類一樣,我們無法創(chuàng)建接口的對(duì)象。但是,我們可以在其他類中實(shí)現(xiàn)接口。在Java中,我們使用 implements關(guān)鍵字來實(shí)現(xiàn)接口。例如,
interface Polygon { void getArea(int length, int breadth); } class Rectangle implements Polygon { public void getArea(int length, int breadth) { System.out.println("矩形的面積是 " + (length * breadth)); } } class Main { public static void main(String[] args) { Rectangle r1 = new Rectangle(); r1.getArea(5, 6); } }
輸出結(jié)果
矩形的面積是 30
在上面的程序中,我們創(chuàng)建了一個(gè)接口Polygon。Polygon接口具有抽象方法getArea()。
這意味著任何實(shí)現(xiàn)Polygon的類都必須為getArea()方法提供實(shí)現(xiàn)。
注意,Rectangle類(實(shí)現(xiàn)Polygon接口)具有帶有實(shí)現(xiàn)的方法getArea()。
現(xiàn)在我們知道了接口是什么,讓我們了解為什么在Java中使用接口。
接口提供了類(實(shí)現(xiàn)它)必須遵循的規(guī)范。
在上面的示例中,我們已使用getArea()作為接口Polygon中的規(guī)范。 這就像設(shè)置一個(gè)規(guī)則,即我們應(yīng)該能夠獲取每個(gè)多邊形的面積。 因此,任何實(shí)現(xiàn)Polygon接口的類都必須提供getArea()方法的實(shí)現(xiàn)。
與抽象類相似,接口可以幫助我們實(shí)現(xiàn)Java抽象。在這里,我們知道getArea()計(jì)算多邊形的面積,但是對(duì)于不同的多邊形,計(jì)算面積的方式是不同的。因此,getArea()的實(shí)現(xiàn)彼此獨(dú)立。
接口還用于在Java中實(shí)現(xiàn)多重繼承。如果子類是從兩個(gè)或多個(gè)類繼承的,則它是多重繼承。
在Java中,無法通過繼承類來實(shí)現(xiàn)多重繼承。但是,一個(gè)類可以實(shí)現(xiàn)多個(gè)接口。這使我們可以獲得Java中多重繼承的功能。例如,
interface Line { ... } interface Polygon { ... } class Rectangle implements Line, Polygon{ ... }
在此,Rectangle必須提供Line和Polygon的所有方法的實(shí)現(xiàn)。
Java 8中,接口現(xiàn)在可以包含靜態(tài)方法。
與類相似,我們可以使用其引用訪問接口的靜態(tài)方法。 例如,
Polygon.staticMethod();
另外,接口在Java 9發(fā)行版中支持私有方法?,F(xiàn)在,您可以在接口中使用私有方法和私有靜態(tài)方法。
由于無法實(shí)例化接口,因此將私有方法用作輔助方法,以為接口中的其他方法提供支持。
Java 8中,在接口內(nèi)部引入了帶有實(shí)現(xiàn)的方法(默認(rèn)方法)。而在此之前,所有方法都是Java中的抽象方法。
要在接口內(nèi)部聲明默認(rèn)方法,我們使用default關(guān)鍵字。例如,
public default void getSides() { //getSides()的主體 }
讓我們以一個(gè)場(chǎng)景來理解為什么Java中引入了默認(rèn)方法。
假設(shè)我們需要在接口中添加一個(gè)新方法。
我們可以輕松地在接口中添加該方法,而無需執(zhí)行。但是,這還不是故事的結(jié)局。我們實(shí)現(xiàn)該接口的所有類都必須提供該方法的實(shí)現(xiàn)。
如果大量類正在實(shí)現(xiàn)此接口,則我們需要跟蹤所有這些類并對(duì)其進(jìn)行更改。這不僅繁瑣,而且容易出錯(cuò)。
為了解決這個(gè)問題,Java引入了默認(rèn)方法。默認(rèn)方法像普通方法一樣繼承。
讓我們以一個(gè)實(shí)例來更好地理解默認(rèn)方法。
interface Polygon { void getArea(); default void getSides() { System.out.println("我可以得到多邊形的邊。"); } } class Rectangle implements Polygon { public void getArea() { int length = 6; int breadth = 5; int area = length * breadth; System.out.println("矩形的面積是 "+area); } public void getSides() { System.out.println("我有四條邊。"); } } class Square implements Polygon { public void getArea() { int length = 5; int area = length * length; System.out.println("正方形的面積是 "+area); } } class Main { public static void main(String[] args) { Rectangle r1 = new Rectangle(); r1.getArea(); r1.getSides(); Square s1 = new Square(); s1.getArea(); } }
輸出結(jié)果
矩形的面積是 30 我有四條邊。 正方形的面積是 25
在上面的示例中,我們創(chuàng)建了一個(gè)Polygon接口。Polygon有一個(gè)默認(rèn)方法getSides()和一個(gè)抽象方法getArea()。
然后,Rectangle類實(shí)現(xiàn)Polygon,Rectangle提供了抽象方法getArea()的實(shí)現(xiàn),并覆蓋了默認(rèn)方法getSides()。
我們創(chuàng)建了另一個(gè)Square類,它也實(shí)現(xiàn)了Polygon。 在這里,Square僅提供抽象方法getArea()的實(shí)現(xiàn)。
讓我們看一個(gè)更實(shí)用的Java接口示例。
//使用sqrt函數(shù) import java.lang.Math; interface Polygon { void getArea(); //計(jì)算多邊形的周長 default void getPerimeter(int... sides) { int perimeter = 0; for (int side: sides) { perimeter += side; } System.out.println("周長: " + perimeter); } } class Triangle implements Polygon { private int a, b, c; private double s, area; //初始化三角形的邊 Triangle(int a, int b, int c) { this.a = a; this.b = b; this.c = c; s = 0; } //計(jì)算三角形的面積 public void getArea() { s = (double) (a + b + c)/2; area = Math.sqrt(s*(s-a)*(s-b)*(s-c)); System.out.println("面積: " + area); } } class Main { public static void main(String[] args) { Triangle t1 = new Triangle(2, 3, 4); //調(diào)用Triangle類的方法 t1.getArea(); //調(diào)用Polygon類的方法 t1.getPerimeter(2, 3, 4); } }
輸出結(jié)果
面積: 2.9047375096555625 周長: 9
在上面的程序中,我們創(chuàng)建了一個(gè)接口Polygon。它包括默認(rèn)方法getParameter()和抽象方法getArea()。
我們可以用相同的方式計(jì)算所有多邊形的周長,因此我們?cè)赑olygon中實(shí)現(xiàn)了getPerimeter()的主體。 現(xiàn)在,所有實(shí)現(xiàn)Polygon的多邊形都可以使用getPerimeter()來計(jì)算周長。
但是,面積的計(jì)算方式,對(duì)于不同的多邊形是不同的,因?yàn)橛?jì)算面積的規(guī)則對(duì)于不同的多邊形是不同的。
因此,沒有在Polygon中實(shí)現(xiàn)而包含了getArea()。 并且,任何實(shí)現(xiàn)Polygon接口的類都必須提供getArea()的實(shí)現(xiàn)。
與類相似,接口可以繼承其他接口,extends關(guān)鍵字被用于繼承接口。例如,
interface Line { //Line接口的成員 } interface Polygon extends Line { //Polygon接口和Line接口的成員 }
在上面的示例中,接口Polygon擴(kuò)展了Line接口。 現(xiàn)在,如果一個(gè)類實(shí)現(xiàn)了Polygon,則它應(yīng)該為Line和Polygon的所有抽象類提供實(shí)現(xiàn)。
注意,一個(gè)接口可以繼承多個(gè)接口,類似于實(shí)現(xiàn)多個(gè)接口的類。例如,
interface A { ... } interface B { ... } Interface C extends A, B { ... }