Java 接口
- Java 接口基础:接口是完全抽象的类,包含一组抽象方法,使用
interface
关键字创建。接口不能直接实例化,需要被其他类实现。 - 实现和扩展接口:类使用
implements
关键字实现接口。接口可扩展其他接口,使用extends
关键字,支持多重继承。 - 接口的特性和用途:接口定义了规范,实现类必须遵守。它们支持多重继承和代码抽象。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
,它就必须为 Line
和 Polygon
的所有抽象方法提供实现。
扩展多个接口
一个接口可以扩展多个接口。例如,
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
的类 Rectangle
和 Square
。
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()
的实现。