CodeGym /课程 /JAVA 25 SELF /接口的概念与声明语法

接口的概念与声明语法

JAVA 25 SELF
第 20 级 , 课程 0
可用

1. 什么是接口?

如果抽象类——是房子的蓝图,那么接口——更像是一份“合同”,约定要完成的工作。例如,你叫来一位水管工,你期望他能“修好水龙头”和“消除漏水”。至于他具体怎么做——你并不关心,重要的是结果。在 Java 中,接口正是这样的契约:它说明必须实现哪些方法,但不说明,如何实现。

要点速览:

接口 是 Java 中的一种特殊类型,它定义了一组方法,签署该接口的类必须实现这些方法。

  • 接口只描述“做什么”,而不描述“怎么做”。
  • 在 Java 8 之前,接口不包含方法的实现。
  • 接口是纯契约:类一旦实现接口,就必须实现其所有方法。

为什么它很有用?

  • 可以给一个类“挂载”多个接口——也就是赋予它多种“角色”。
  • 有助于构建灵活且可扩展的架构,使类能够实现不同的能力。
  • 接口在 Java 标准库中被广泛使用(例如,ComparableSerializableRunnable 等)。

2. 接口的声明语法

在 Java 中声明接口非常简单。使用关键字 interface 即可。直到 Java 8,接口中的方法默认被视为 public abstract,即使没有显式写出。这意味着:实现该接口的类必须实现这些方法。

接口示例


public interface Movable {
    void move(int x, int y);
}
  • 这里我们声明了接口 Movable(可理解为“可移动/会移动”)。
  • 内部声明了方法 move(int x, int y)。没有方法体——只有签名。这就是“契约”:“如果你实现了 Movable,就请实现 move”。

语法要点

  • 接口中的方法(在 Java 8 之前)不包含方法体
  • 接口中的所有方法默认都是 public abstract(可以不显式写出)。
  • 接口只能包含常量(public static final),不能有普通字段。

包含常量的示例

public interface Constants {
    int MAX_SPEED = 100; // 默认是 public static final
}

3. 接口与类的区别

接口不是类!我们来看看它们的区别。

类(包括抽象类) 接口
可以包含字段(状态) 不能包含字段(只能有常量)
可以包含方法的实现 在 Java 8 之前接口不能包含实现,只能有方法签名
可以通过 new 创建(如果不是抽象类) 不能直接创建
只允许单继承(extends 类可以实现多个接口(implements
用于描述“它是什么” 用于描述“能做什么”

类通过 implements 来实现接口

public class Robot implements Movable {
    @Override
    public void move(int x, int y) {
        System.out.println("机器人移动到点 (" + x + ", " + y + ")");
    }
}
  • Robot 实现了接口 Movable
  • 关键字 implements 表示“实现”。
  • 必须实现接口的全部方法(否则会编译错误)。
  • 别忘了注解 @Override——它不是必须的,但能帮助编译器和你避免出错。

4. 接口的使用示例

我们写一个简单的例子,看看它在实际中如何工作。假设我们有接口 Movable,并希望不同的类都能“移动”:机器人、汽车、动物……

步骤 1:声明接口

public interface Movable {
    void move(int x, int y);
}

步骤 2:在类中实现接口

public class Robot implements Movable {
    @Override
    public void move(int x, int y) {
        System.out.println("机器人移动到点 (" + x + ", " + y + ")");
    }
}

步骤 3:使用接口

public class Main {
    public static void main(String[] args) {
        Movable m = new Robot(); // 接口类型的变量!
        m.move(10, 20); // 输出:机器人移动到点 (10, 20)
    }
}

请注意

  • 我们可以声明一个接口类型的变量(Movable m),并将实现该接口的类的对象(new Robot())赋给它。
  • 这使我们能编写泛化的代码:无需知道具体的类,只要它是“可移动”的对象即可。

未实现方法时的编译错误

Error: Class 'Robot' must either be declared abstract or implement abstract method 'move(int, int)' in 'Movable'

这正是接口的力量——它保证所有实现类都具备所需的方法。

5. Java 标准库中的接口

接口并不只是“课本上的概念”。它们在整个 Java 标准库中都被广泛使用。以下是几个示例:

  • Comparable<T>——用于比较对象的接口(例如在排序时)。
  • Runnable——用于启动线程的接口。
  • Serializable——标记接口,表示对象可以被序列化。
  • ListSetMap——集合接口。

示例:Comparable

public class Person implements Comparable<Person> {
    String name;
    int age;

    // 构造函数及其他方法...

    @Override
    public int compareTo(Person other) {
        return this.age - other.age;
    }
}

现在 Person 对象可以被排序,因为它实现了 Comparable 接口。

6. 可视化示意:接口如何工作

+-------------------+         +-------------------+
|   interface       |         |    class          |
|   Movable         |<--------|    Robot          |
|-------------------|         |-------------------|
| +move(int, int)   |         | +move(int, int)   |
+-------------------+         +-------------------+
  • 箭头表示类 Robot 实现了接口 Movable
  • 接口只规定“应该有什么”,类负责“怎样实现”。

生活中的类比

Java 中的接口就像驾驶证。如果你有驾驶证(你实现了“司机”这个接口),说明你驾驶汽车。你具体如何驾驶——这是实施细节:有人开得稳,有人开得快,但关键是你承诺你会做这件事。

7. 实战示例:继续完善我们的应用

public interface Movable {
    void move(int x, int y);
}

public class Animal implements Movable {
    protected String name;

    public Animal(String name) {
        this.name = name;
    }

    @Override
    public void move(int x, int y) {
        System.out.println(name + " 移动到点 (" + x + ", " + y + ")");
    }
}

public class Robot implements Movable {
    private String model;

    public Robot(String model) {
        this.model = model;
    }

    @Override
    public void move(int x, int y) {
        System.out.println("机器人 " + model + " 前往坐标 (" + x + ", " + y + ")");
    }
}

public class Main {
    public static void main(String[] args) {
        Movable[] movables = {
            new Animal("Spot"),
            new Robot("R2D2")
        };

        for (Movable m : movables) {
            m.move(5, 10);
        }
    }
}

运行结果:

Spot 移动到点 (5, 10)
机器人 R2D2 前往坐标 (5, 10)

我们创建了一个 Movable 类型对象的数组。里面可以放任何实现该接口的对象!循环中的代码并不知道它面对的是动物还是机器人——但知道它们都会 move

8. 使用接口时的常见错误

错误 1:试图直接创建接口的对象。 接口是契约,而不是具体对象。不能写 new Movable()——这会导致编译错误。应该创建实现该接口的类的对象。

错误 2:没有实现接口的所有方法。 如果类实现了接口却没有实现其所有方法,编译器会报错:“Class must either be declared abstract or implement abstract method ...”。如果你不想实现所有方法——就把类声明为 abstract

错误 3:忽略访问修饰符。 接口方法始终是 public(即使没有显式写出)。在实现类中不能降低可见性级别,因此方法也必须是 public

错误 4:在接口中添加普通字段。 接口中只能声明常量(public static final)。不能添加普通(非静态)字段。

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION