Java 接口

接口是一个完全抽象的类。在本教程中,我们将通过示例详细了解如何实现 Java 接口以及何时使用接口。

在本教程中,我们将通过示例详细了解如何实现 Java 接口以及何时使用它们。

接口是一个完全抽象的类。它包括一组抽象方法(没有主体的方法)。

我们使用 interface 关键字在 Java 中创建一个接口。例如,

interface Language {
  public void getType();

  public void getVersion();
}

这里,

  • Language 是一个接口。
  • 它包括抽象方法: getType()getVersion()

实现接口

像抽象类一样,我们不能创建接口的实例。

要使用接口,其他类必须实现此接口。我们使用 implements 关键字来实现一个接口。

示例 1:Java 接口

// 多边形
interface Polygon {
  // 计算面积
  void getArea(int length, int breadth);
}

// 矩形, 实现多边形接口
class Rectangle implements Polygon {

  // 实现接口中的抽象方法
  public void getArea(int length, int breadth) {
    System.out.println("矩形的面积是 " + (length * breadth));
  }
}

public class Main {
  public static void main(String[] args) {
    Rectangle r1 = new Rectangle();
    r1.getArea(5, 6);
  }
}

输出

矩形的面积是 30

在上面的例子中,我们创建了一个名为 Polygon 的接口,该接口包含一个抽象方法 getArea()Rectangle 类实现 Polygon 接口,并且,提供了 getArea() 方法的实现。

示例 2:Java 接口

// 接口
interface Language {
  void getName(String name);
}

// 实现类
public class ProgrammingLanguage implements Language {
  // 实现方法
  public void getName(String name) {
    System.out.println("Programming Language: " + name);
  }
}

public class Main {
  public static void main(String[] args) {
    ProgrammingLanguage language = new ProgrammingLanguage();
    language.getName("Java");
  }
}

输出

Programming Language: Java

在上面的例子中,我们创建了一个名为接口 Language, 该接口包括一个抽象方法 getName()ProgrammingLanguage 类实现接口并提供方法的实现。

实现多个接口

在 Java 中,一个类也可以实现多个接口。例如,

interface A { }

interface B { }

public class C implements A, B { }

扩展接口

与类继承类似,接口可以扩展其他接口。extends 关键字用于扩展接口。例如,

interface Line {
}

// 接口继承接口
interface Polygon extends Line {
}

在这里, Polygon 接口扩展了 Line 接口。现在,如果任何类实现 Polygon 接口,它应该同时实现 Polygon 接口和 Line 接口的所有方法。

扩展多个接口

一个接口可以扩展多个接口。例如,

interface A { }

interface B { }

interface C extends A, B { }

Java 中接口的优点

现在我们知道了接口是什么,让我们了解为什么在 Java 中使用接口。

  • 与抽象类类似,接口帮助我们在 Java 中实现抽象。

    在这里,我们知道 getArea() 计算多边形的面积,但是对于不同的多边形,计算面积的方式是不同的。因此, 的实现 getArea() 是相互独立的。

  • 接口提供了所有实现类必须遵循的规范。

    在我们之前的例子中,我们使用在接口内部定义了 getArea() 方法, 这就像设置一个规则,所有实现此接口的实现类都要能够通过 getArea() 返回面积。

  • 接口还用于在 Java 中实现多重继承。例如,

    interface Line { }
    
    interface Polygon { }
    
    class Rectangle implements Line, Polygon { }
    

    Java 不支持类的多重继承,但是接口帮我们做到了这一点。

注意:接口内的所有方法都是隐式的 public ,所有字段都是隐式的 public static final 。例如,

interface Language {

  // 默认为: public static final
  String type = "programming language";

  // 默认为: public
  void getName();
}

Java 接口中的默认方法

随着 Java 8 的发布,我们现在可以在接口内添加具有实现的方法。这些方法称为默认方法。

为了在接口内声明默认方法,我们使用 default 关键字。例如,

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

为什么是默认方法?

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

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

我们可以轻松地在我们的接口代码中添加该方法而无需实现。然而,这并没有结束。我们所有实现该接口的类都必须为该方法提供一个实现。

如果有大量的类以前已经实现这个接口,我们需要跟踪所有这些类并对其进行更改。这不仅乏味而且容易出错。

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

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

示例:Java 接口中的默认方法

interface Polygon {
  void getArea();

  // 默认方法
  default void getSides() {
    System.out.println("I can get sides of a 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);
  }

  // 覆盖方法 getSides()
  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);
  }
}

public class Main {
  public static void main(String[] args) {

    Rectangle r1 = new Rectangle();
    r1.getArea();
    r1.getSides();

    Square s1 = new Square();
    s1.getArea();
    s1.getSides();
  }
}

输出

The area of the rectangle is 30
I have 4 sides.
The area of the square is 25
I can get sides of a polygon.

在上面的例子中,我们创建了一个接口 Polygon, 它有一个默认方法 getSides() 和一个抽象方法 getArea()

在这里,我们创建了两个类 RectangleSquare 实现 Polygon 接口。

Rectangle 类实现了 getArea() 方法并覆盖 getSides() 方法。而 Square 类只实现了 getArea() 方法。所以,当 Square 类的对象调用 getSides() 方法的时候,就调用了接口的默认方法。

接口中的私有和静态方法

Java 8 还添加了另一个特性,接口中可以拥有静态方法。

与类的静态方法类似,我们可以直接使用接口名调用静态方法。例如,

// 带有静态方法的接口
interface Polygon {
  static Method(){..}
}

// 访问镜头方法
Polygon.staticMethod();

! 注意:随着 Java 9 的发布,接口中也支持私有方法。私有方法主要用作辅助方法,为接口中的其他方法提供支持。

接口实例

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

import java.lang.Math;

// 多边形
interface Polygon {
  // 计算面积
  void getArea();

  // 计算周长
  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;

  // 初始化三角形的边
  Triangle(int a, int b, int c) {
    this.a = a;
    this.b = b;
    this.c = c;
    s = 0;
  }

  // 计算面积
  public void getArea() {
    s = (double) (a + b + c)/2;
    area = Math.sqrt(s*(s-a)*(s-b)*(s-c));
    System.out.println("Area: " + area);
  }
}

public class Main {
  public static void main(String[] args) {
    Triangle t1 = new Triangle(2, 3, 4);

    t1.getArea();

    t1.getPerimeter(2, 3, 4);
  }
}

输出

Area: 2.9047375096555625
Perimeter: 9

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

我们可以以相同的方式计算所有多边形的周长,因此我们在接口 Polygon 中作为默认方法实现了 getPerimeter() 方法。 所有的多边形都可以使用 getPerimeter() 方法计算周长。

但是,对于不同的多边形,计算面积的规则是不同的。因此, 接口中并没有实现 getArea() 方法。

任何实现 Polygon 接口的类必须实现 getArea() 方法。