第 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-do | is-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 内置的常用函数式接口:
| 接口 | 方法 | 用途 |
|---|---|---|
Runnable | void 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()。让 Circle 和 Rectangle 实现。
练习 2:进阶题
定义多个接口 Flyable、Swimmable、Runnable,让 Duck 多实现。
下一章:第 22 章:内部类与枚举 →