在Java中,接口定义了其他类必须实现的一组规范。例如,
interface Polygon {
public void getArea();
}
在这里, 多边形是一个接口。我们使用interface
关键字来声明一个接口。
getArea()
方法是在Polygon接口中定义的规范。使用此接口的所有类都必须实现getArea()
方法。
接口可以包含抽象方法和常量。例如,
interface Polygon {
public static final String color = "blue";
public void getArea();
}
在上面的示例中,我们创建了一个Polygon接口。它包括一个常量变量颜色和一个抽象方法getArea()
。
重要的是要注意,接口内的所有方法都是隐式public
而所有字段都是隐式public static final
。因此,没有必要在接口内部指定访问说明符。例如,我们可以将上面的代码编写为
interface Polygon {
String color = "blue";
void getArea();
}
在接口中实现关键字
像抽象类一样,我们不能创建接口的对象。但是,我们可以在其他类中实现接口。在Java中,我们使用implements
关键字来实现接口。例如,
interface Polygon {
void getArea(int length, int breadth);
}
class Rectangle implements Polygon {
public void getArea(int length, int breadth) {
System.out.println("The area of the rectangle is " + (length * breadth));
}
}
class Main {
public static void main(String[] args) {
Rectangle r1 = new Rectangle();
r1.getArea(5, 6);
}
}
输出
The area of the rectangle is 30
在上面的程序中,我们创建了一个Polygon接口。 Polygon接口具有抽象方法getArea()
。
这意味着任何实现Polygon的类都必须提供getArea()
方法的实现。
注意, Rectangle类(实现Polygon接口)具有带有实现的方法getArea()
。
为什么要使用接口?
现在我们知道了接口是什么,让我们了解为什么在Java中使用接口。
-
接口提供了类(实现它)必须遵循的规范。
在上面的示例中,我们已使用
getArea()
作为接口Polygon中的规范。这就像设置一个规则,即我们应该能够获取每个多边形的面积。因此,任何实现Polygon接口的类都必须提供getArea()
方法的实现。 -
与抽象类相似,接口可帮助我们实现Java抽象。在这里,我们知道
getArea()
计算多边形的面积,但是对于不同的多边形,计算面积的方式是不同的。因此,getArea()
的实现彼此独立。 -
接口还用于在Java中实现多重继承。如果子类是从两个或多个类继承的,则它是多重继承。
在Java中,不能通过扩展类来实现多重继承。但是,一个类可以实现多个接口。这使我们可以获得Java中多重继承的功能。例如,
interface Line { ... } interface Polygon { ... } class Rectangle implements Line, Polygon{ ... }
在这里, Rectangle必须提供Line和Polygon的所有方法的实现。
接口中的私有方法和静态方法
随着Java 8的发布,接口现在可以包含静态方法。
与类相似,我们可以使用其引用访问接口的静态方法。例如,
Polygon.staticMethod();
此外,接口在Java 9发行版中支持私有方法。现在,您可以在接口中使用私有方法和私有静态方法 。
由于无法实例化接口,因此将私有方法用作辅助方法,以为接口中的其他方法提供支持。
接口中的默认方法
随着Java 8的发布,在接口内部引入了带有实现的方法(默认方法)。在此之前,所有方法都是Java中的抽象方法。
要在接口内部声明默认方法,我们使用default
关键字。例如,
public default void getSides() {
// body of getSides()
}
为什么使用默认方法?
让我们以一个场景来理解为什么Java中引入了默认方法。
假设我们需要在接口中添加一个新方法。
我们可以轻松地在接口中添加该方法,而无需执行。但是,这还不是故事的结局。我们所有实现该接口的类都必须提供该方法的实现。
如果大量类正在实现此接口,则我们需要跟踪所有这些类并对其进行更改。这不仅繁琐,而且容易出错。
为了解决这个问题,Java引入了默认方法。默认方法像普通方法一样继承。
让我们以一个例子来更好地理解默认方法。
示例2:默认方法
interface Polygon {
void getArea();
default void getSides() {
System.out.println("I can get sides of polygon.");
}
}
class Rectangle implements Polygon {
public void getArea() {
int length = 6;
int breadth = 5;
int area = length * breadth;
System.out.println("The area of the rectangle is "+area);
}
public void getSides() {
System.out.println("I have 4 sides.");
}
}
class Square implements Polygon {
public void getArea() {
int length = 5;
int area = length * length;
System.out.println("The area of the square is "+area);
}
}
class Main {
public static void main(String[] args) {
Rectangle r1 = new Rectangle();
r1.getArea();
r1.getSides();
Square s1 = new Square();
s1.getArea();
}
}
输出
The area of the rectangle is 30
I have 4 sides
The area of the square is 25
在上面的示例中,我们创建了一个Polygon接口。 多边形具有默认方法getSides()
和抽象方法getArea()
。
然后, Rectangle类实现Polygon 。 Rectangle提供了抽象方法getArea()
的实现,并覆盖了默认方法getSides()
。
我们创建了另一个类Square ,它也实现了Polygon 。在这里, Square仅提供抽象方法getArea()
。
接口的实际示例
让我们看一个更实用的Java接口示例。
// To use the sqrt function
import java.lang.Math;
interface Polygon {
void getArea();
// calculate the perimeter of a Polygon
default void getPerimeter(int... sides) {
int perimeter = 0;
for (int side: sides) {
perimeter += side;
}
System.out.println("Perimeter: " + perimeter);
}
}
class Triangle implements Polygon {
private int a, b, c;
private double s, area;
// initializing sides of a triangle
Triangle(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
s = 0;
}
// calculate the area of a triangle
public void getArea() {
s = (double) (a + b + c)/2;
area = Math.sqrt(s*(s-a)*(s-b)*(s-c));
System.out.println("Area: " + area);
}
}
class Main {
public static void main(String[] args) {
Triangle t1 = new Triangle(2, 3, 4);
// calls the method of the Triangle class
t1.getArea();
// calls the method of Polygon
t1.getPerimeter(2, 3, 4);
}
}
输出
Area: 2.9047375096555625
Perimeter: 9
在上面的程序中,我们创建了一个Polygon接口。它包括一个默认方法getPerimeter()
和一个抽象方法getArea()
。
我们可以用相同的方式计算所有多边形的周长,因此我们在Polygon中实现了getPerimeter()
的主体。现在,所有实现Polygon的多边形都可以使用getPerimeter()
来计算周长。
但是,面积的计算对于不同的多边形是不同的,因为计算面积的规则对于不同的多边形是不同的。因此,没有在Polygon中实现而包含了getArea()
。并且,任何实现Polygon接口的类都必须提供getArea()
的实现。
扩展接口中的关键字
与类相似,接口可以扩展其他接口。 extends
关键字用于扩展接口。例如,
interface Line {
//members of Line interface
}
interface Polygon extends Line {
//members of Polygon interface and Line interface
}
在上面的示例中,接口Polygon扩展了Line接口。现在,如果一个类实现了Polygon ,则它应该为Line和Polygon的所有抽象类提供实现。
注意,一个接口可以扩展多个接口,类似于实现多个接口的类。例如,
interface A {
...
}
interface B {
...
}
Interface C extends A, B {
...
}