# Java 接口

> 原文： [https://www.programiz.com/java-programming/interfaces](https://www.programiz.com/java-programming/interfaces)

#### 在本教程中，我们将学习 Java 接口。 我们将借助示例学习如何实现接口以及何时使用它们。

在 Java 中，接口定义了其他类必须实现的一组规范。 例如，

```java
interface Polygon {
   public void getArea();
} 
```

在此，`Polygon`是一个接口。 我们已经使用`interface`关键字来声明一个接口。

`getArea()`方法是在`Polygon`接口中定义的规范。 使用此接口的所有类都必须实现`getArea()`方法。

接口可以包含抽象方法和常量。 例如，

```java
interface Polygon {
   public static final String color = "blue";

   public  void getArea();
} 
```

在上面的示例中，我们创建了一个接口`Polygon`。 它包括一个常量变量`color`和一个抽象方法`getArea()`。

重要的是要注意，接口内的所有方法都是隐式`public`，而所有字段都是隐式`public static final`。 因此，没有必要在接口内部指定访问说明符。 例如，我们可以将上面的代码编写为

```java
interface Polygon {
   String color = "blue";

    void getArea();
} 
```

* * *

## 接口中的`implements`关键字

像抽象类一样，我们无法创建接口的对象。 但是，我们可以在其他类中实现接口。 在 Java 中，我们使用`implements`关键字实现接口。 例如，

```java
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);
    }
} 
```

**输出**

```java
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 获得多重继承的功能。 例如，

    ```java
    interface Line {
       ...
    }
    interface Polygon {
       ...
    }
    class Rectangle implements Line, Polygon{
       ...
    } 
    ```

    在此，`Rectangle`必须提供`Line`和`Polygon`的所有方法的实现。

* * *

## 接口中的私有方法和静态方法

随着 Java 8 的发布，接口现在可以包含静态方法。

与类相似，我们可以使用其引用访问接口的静态方法。 例如，

```java
Polygon.staticMethod(); 
```

此外，接口在 Java 9 发行版中支持私有方法。现在，您可以在接口中使用**私有方法**和**私有静态方法**。

由于无法实例化接口，因此将私有方法用作辅助方法，以为接口中的其他方法提供支持。

* * *

## 接口中的默认方法

随着 Java 8 的发布，在接口内部引入了带有实现的方法（默认方法）。 在此之前，所有方法都是 Java 中的抽象方法。

要在接口内部声明默认方法，我们使用`default`关键字。 例如，

```java
public default void getSides() {
   // body of getSides()
} 
```

### 为什么使用默认方法？

让我们以一个场景来理解为什么 Java 中引入了默认方法。

假设我们需要在接口中添加一个新方法。

我们可以轻松地在接口中添加方法，而无需执行。 但是，这还不是故事的结局。 我们实现该接口的所有类都必须提供该方法的实现。

如果大量类正在实现此接口，则我们需要跟踪所有这些类并对其进行更改。 这不仅繁琐，而且容易出错。

为了解决这个问题，Java 引入了默认方法。 默认方法像普通方法一样继承。

让我们以一个例子来更好地了解默认方法。

### 示例 2：默认方法

```java
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();
   }
} 
```

**输出**：

```java
The area of the rectangle is 30
I have 4 sides
The area of the square is 25 
```

在上面的示例中，我们创建了一个接口`Polygon`。`Polygon`具有默认方法`getSides()`和抽象方法`getArea()`。

然后，类`Rectangle`实现`Polygon`。`Rectangle`提供了抽象方法`getArea()`的实现，并覆盖了默认方法`getSides()`。

我们创建了另一个`Square`类，它也实现了`Polygon`。 在此，`Square`仅提供抽象方法`getArea()`的实现。

* * *

### 接口的实际示例

让我们来看一个更实用的 Java 接口示例。

```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);
   }
} 
```

**输出**：

```java
Area: 2.9047375096555625
Perimeter: 9 
```

在上面的程序中，我们创建了一个接口`Polygon`。 它包括默认方法`getParameter()`和抽象方法`getArea()`。

我们可以用相同的方式计算所有多边形的周长，因此我们在`Polygon`中实现了`getPerimeter()`的主体。 现在，所有实现`Polygon`的多边形都可以使用`getPerimeter()`计算周长。

但是，面积的计算对于不同的多边形是不同的，因为计算面积的规则对于不同的多边形是不同的。 因此，在没有实现的情况下，将`getArea()`包括在`Polygon`中。 并且，任何实现`Polygon`接口的类都必须提供`getArea()`的实现。

* * *

## 接口中的`extends`关键字

与类相似，接口可以扩展其他接口。`extends`关键字用于扩展接口。 例如，

```java
interface Line {
   //members of Line interface
}

interface Polygon extends Line {
   //members of Polygon interface and Line interface
} 
```

在上面的示例中，接口`Polygon`扩展了`Line`接口。 现在，如果一个类实现了`Polygon`，则它应该为`Line`和`Polygon`的所有抽象类提供实现。

注意，一个接口可以扩展多个接口，类似于实现多个接口的类。 例如，

```java
interface A {
   ...
}
interface B {
   ... 
}

Interface C extends A, B {
   ...
} 
```