Skip to content
第 21 / 250 章后端⏱ 10 分钟阅读

第 21 章:接口

学习目标

  • 掌握接口的定义和实现
  • 理解接口的演变(Java 8/9 新特性)
  • 区分接口和抽象类

一、什么是接口?

接口是行为的抽象(能力的集合),用 interface 关键字定义。

java
public interface Flyable {            // ① 用 interface 定义
    public static final int MAX_HEIGHT = 10000;  // 常量(隐式 public static final)

    public abstract void fly();        // 抽象方法(隐式 public abstract)

    // Java 8+:默认方法
    public default void land() {
        System.out.println("降落");
    }

    // Java 8+:静态方法
    public static boolean canFly(Flyable f) {
        return f != null;
    }
}

二、实现接口

java
public class Bird implements Flyable {
    @Override
    public void fly() {                // ① 必须实现抽象方法
        System.out.println("鸟在飞");
    }
}

public class Airplane implements Flyable {
    @Override
    public void fly() {
        System.out.println("飞机在飞");
    }
}

多实现

java
public interface Swimmable {
    void swim();
}

public interface Runnable {
    void run();
}

// ✅ 多实现:用逗号分隔
public class Duck implements Flyable, Swimmable, Runnable {
    @Override public void fly() { }
    @Override public void swim() { }
    @Override public void run() { }
}

三、Java 8/9 接口新特性

3.1 默认方法(default)

java
public interface Iterator<E> {
    boolean hasNext();
    E next();

    // 默认方法:实现类可以重写,也可以直接用
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
}

为什么需要默认方法?

为了让接口可以"演进":新增方法时,不破坏已有实现类的兼容性。

3.2 静态方法(static)

java
public interface Collections {
    public static <T> List<T> emptyList() {  // 接口的静态方法
        return new EmptyList<>();
    }
}

// 调用
List<String> list = Collections.emptyList();

3.3 私有方法(Java 9+)

java
public interface MyInterface {
    default void publicMethod() {
        commonMethod();                  // 调用私有方法
        System.out.println("public");
    }

    private void commonMethod() {        // ① 私有方法:抽取公共逻辑
        System.out.println("common");
    }
}

四、接口的多继承

java
public interface A {
    default void hello() { System.out.println("A"); }
}

public interface B {
    default void hello() { System.out.println("B"); }
}

// ❌ 错误:接口 A 和 B 都有 hello(),冲突
// public interface C extends A, B { }

// ✅ 解决方案:自己重写
public interface C extends A, B {
    @Override
    default void hello() {               // ① 显式重写
        A.super.hello();                  // ② 选择 A 的实现
        // B.super.hello();
    }
}

五、接口 vs 抽象类

维度接口抽象类
多继承✅ 多实现❌ 单继承
字段只能是常量可以是普通字段
方法抽象 + 默认 + 静态可以有任何方法
构造器
关系has-a / can-dois-a

设计原则

  • 抽象类 → "是什么"(Animal / Dog)
  • 接口 → "能做什么"(Flyable / Swimmable)

六、函数式接口

只有一个抽象方法的接口叫函数式接口(可用于 Lambda):

java
@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2);     // 唯一的抽象方法

    default Comparator<T> reversed() { ... }    // 默认方法允许
    static <T> Comparator<T> naturalOrder() { ... }  // 静态方法允许
}

Java 内置的常用函数式接口:

接口方法用途
Runnablevoid run()无参无返回值
Supplier<T>T get()无参有返回值
Consumer<T>void accept(T)有参无返回值
Function<T,R>R apply(T)转换
Predicate<T>boolean test(T)判断

七、本章小结

要点关键
接口行为的抽象,多实现
默认方法Java 8+,接口可演进
静态方法Java 8+,工具方法放接口
接口 vs 抽象类接口是 can-do,抽象类是 is-a
函数式接口一个抽象方法 + Lambda

动手练习

练习 1:基础题

定义接口 Drawable,有方法 draw()。让 CircleRectangle 实现。

练习 2:进阶题

定义多个接口 FlyableSwimmableRunnable,让 Duck 多实现。


下一章第 22 章:内部类与枚举

本站基于 VitePress 构建 · 由 Codebook 团队维护