跳到主要内容

Java 接口

提示
  1. Java 接口基础:接口是完全抽象的类,包含一组抽象方法,使用 interface 关键字创建。接口不能直接实例化,需要被其他类实现。
  2. 实现和扩展接口:类使用 implements 关键字实现接口。接口可扩展其他接口,使用 extends 关键字,支持多重继承。
  3. 接口的特性和用途:接口定义了规范,实现类必须遵守。它们支持多重继承和代码抽象。Java 8 引入了默认方法和静态方法,增强了接口的功能。

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

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

interface Language {
public void getType();

public void getVersion();
}

这里,

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

实现一个接口

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

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

示例 1:Java 接口

interface Polygon {
void getArea(int length, int breadth);
}

// 实现 Polygon 接口
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);
}
}

输出

矩形的面积是 30

在上面的示例中,我们创建了一个名为 Polygon 的接口。该接口包含一个抽象方法 getArea()

这里,Rectangle 类实现了 Polygon。并提供了 getArea() 方法的实现。

示例 2:Java 接口

// 创建一个接口
interface Language {
void getName(String name);
}

// 类实现接口
class ProgrammingLanguage implements Language {

// 抽象方法的实现
public void getName(String name) {
System.out.println("编程语言: " + name);
}
}

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

输出

编程语言: Java

在上面的示例中,我们创建了一个名为 Language 的接口。该接口包括一个抽象方法 getName()

这里,ProgrammingLanguage 类实现了接口并提供了该方法的实现。

实现多个接口

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

interface A {
// A 的成员
}

interface B {
// B 的成员
}

class C implements A, B {
// A 的抽象成员
// B 的抽象成员
}

扩展一个接口

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

interface Line {
// Line 接口的成员
}

// 扩展接口
interface Polygon extends Line {
// Polygon 接口的成员
// Line 接口的成员
}

在这里,Polygon 接口扩展了 Line 接口。现在,如果任何类实现了 Polygon,它就必须为 LinePolygon 的所有抽象方法提供实现。

扩展多个接口

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

interface A {
...
}
interface B {
...
}

interface C extends A, B {
...
}

Java 中接口的优势

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

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

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

  • 接口 提供规范,实现它的类必须遵循。

    在我们之前的示例中,我们在接口 Polygon 中使用了 getArea() 作为规范。这就像设定了一个规则,我们应该能够计算每个多边形的面积。

    现在任何实现了 Polygon 接口的类都必须为 getArea() 方法提供实现。

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

interface Line {

}

interface Polygon {

}

class Rectangle implements Line, Polygon {

}

这里,Rectangle 类实现了两个不同的接口。这就是我们在 Java 中实现多重继承的方式。

注意:接口中的所有方法默认都是 public 的,所有字段默认都是 public static final 的。例如,

interface Language {

// 默认为 public static final
String type = "编程语言";

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

Java 接口中的默认方法

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

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

public default void getSides() {
// getSides() 的实现体
}

为什么引入默认方法?

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

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

我们可以在接口中轻松添加没有实现的方法。然而,这并不是故事的终点。所有实现了该接口的类都必须为该方法提供实现。

如果有大量类实现了这个接口,我们需要追踪所有这些类并对它们进行更改。这不仅繁琐,也容易出错。

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

让我们通过一个示例更好地理解默认方法。

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

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

// 重写 getSides()
public void getSides() {
System.out.println("我有 4 边。");
}
}

// 实现接口
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 对象


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

// 创建一个 Square 对象
Square s1 = new Square();
s1.getArea();
s1.getSides();
}
}

输出

矩形的面积是 30
我有 4 边。
正方形的面积是 25
我可以获取多边形的边数。

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

这里,我们创建了两个实现了 Polygon 的类 RectangleSquare

Rectangle 类提供了 getArea() 方法的实现,并重写了 getSides() 方法。然而,Square 类只提供了 getArea() 方法的实现。

现在,当使用 Rectangle 对象调用 getSides() 方法时,调用的是重写的方法。然而,在 Square 对象的情况下,调用的是默认方法。

接口中的私有和静态方法

Java 8 也添加了在接口中包含静态方法的功能。

类似于类,我们可以使用接口的引用来访问接口中的静态方法。例如,

// 创建一个接口
interface Polygon {
staticMethod(){..}
}

// 访问静态方法
Polygon.staticMethod();

注意:随着 Java 9 的发布,接口中也支持私有方法。

我们不能创建接口的对象。因此,私有方法用作辅助方法,为接口中的其他方法提供支持。

接口的实际示例

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

// 使用 sqrt 函数
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);
}
}

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

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

// 调用 Triangle 类的方法
t1.getArea();

// 调用 Polygon 的方法
t1.getPerimeter(2, 3, 4);
}
}

输出

面积: 2.9047375096555625
周长: 9

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

我们可以以相同的方式计算所有多边形的周长,所以我们在 Polygon 中实现了 getPerimeter() 的方法体。

现在,所有实现了 Polygon 的多边形都可以使用 getPerimeter() 来计算周长。

然而,不同多边形计算面积的规则是不同的。因此,getArea() 是没有实现的。

任何实现了 Polygon 的类都必须提供 getArea() 的实现。