接口
约 1218 字大约 4 分钟
2026-03-27
一、接口的概念
接口(interface)用于定义一组规范,描述“一个类应该具备什么能力”。它更关注行为约束,而不是具体实现。
例如:
- 会飞:
Flyable - 可比较:
Comparable - 可序列化:
Serializable
接口常用于解耦、扩展和多态设计,是 Java 面向对象编程中的核心机制之一。
二、接口的定义与实现
2.1 基本语法
interface Flyable {
void fly();
}
class Bird implements Flyable {
@Override
public void fly() {
System.out.println("鸟在飞");
}
}规则说明:
- 使用
interface定义接口 - 类使用
implements实现接口 - 实现类必须重写接口中的抽象方法
三、接口的特点
3.1 接口中的成员特点
接口中的成员变量默认都是:
publicstaticfinal
也就是说,接口中的变量本质上是常量。
interface Constants {
int MAX_SIZE = 100;
}等价于:
public static final int MAX_SIZE = 100;3.2 接口中的方法特点
在 Java 8 之前,接口中的方法默认是:
publicabstract
interface Usb {
void connect();
}3.3 Java 8 之后的增强
Java 8 开始,接口中可以定义:
default默认方法static静态方法
Java 9 开始,接口中还可以定义:
private私有方法
四、默认方法和静态方法
4.1 default 方法
默认方法允许接口提供方法实现,用于在不破坏旧实现类的前提下扩展接口能力。
interface Logger {
default void info(String msg) {
System.out.println("[INFO] " + msg);
}
}
class ConsoleLogger implements Logger {
}ConsoleLogger 即使没有重写 info(),也可以直接使用。
4.2 static 方法
interface MathTool {
static int add(int a, int b) {
return a + b;
}
}调用方式:
int result = MathTool.add(1, 2);注意:接口中的静态方法不能被实现类继承调用,只能通过接口名调用。
五、接口支持多实现
Java 类只能单继承,但可以实现多个接口,这是接口非常重要的价值。
interface Camera {
void takePhoto();
}
interface MusicPlayer {
void playMusic();
}
class Phone implements Camera, MusicPlayer {
@Override
public void takePhoto() {
System.out.println("拍照");
}
@Override
public void playMusic() {
System.out.println("播放音乐");
}
}这使得一个类可以同时具备多种能力。
六、接口之间可以继承
接口也可以继承接口,而且支持多继承。
interface A {
void methodA();
}
interface B {
void methodB();
}
interface C extends A, B {
void methodC();
}如果某个类实现 C,那么它必须同时实现 A、B、C 中定义的所有抽象方法。
七、默认方法冲突问题
如果一个类实现了多个接口,而这些接口中存在同名同参数的 default 方法,必须在实现类中显式重写该方法。
interface A {
default void hello() {
System.out.println("A");
}
}
interface B {
default void hello() {
System.out.println("B");
}
}
class C implements A, B {
@Override
public void hello() {
A.super.hello();
}
}这是因为编译器无法自动判断应该使用哪个接口的默认实现。
八、函数式接口
如果一个接口中只有一个抽象方法,那么它就是函数式接口,可以配合 Lambda 表达式使用。
@FunctionalInterface
interface Calculator {
int calc(int a, int b);
}
public class Demo {
public static void main(String[] args) {
Calculator add = (a, b) -> a + b;
System.out.println(add.calc(3, 5));
}
}常见的函数式接口有:
RunnableComparatorConsumerSupplierFunctionPredicate
九、接口与抽象类的区别
| 对比项 | 接口 | 抽象类 |
|---|---|---|
| 关键字 | interface | abstract class |
| 关系强调 | 行为规范 | 事物共性 |
| 一个类可使用几个 | 可以实现多个 | 只能继承一个 |
| 是否能有构造器 | 不可以 | 可以 |
| 是否能有普通成员变量 | 不可以 | 可以 |
| 是否适合代码复用 | 一般 | 更适合 |
实际开发中的判断标准:
- 要定义“能力”,优先接口
- 要提取“共性”,优先抽象类
十、接口的典型应用场景
10.1 规范统一
例如支付接口、日志接口、消息发送接口,不同实现类遵守同一套方法规范。
10.2 解耦合
面向接口编程,可以让调用方依赖抽象,而不是依赖具体实现。
interface MessageService {
void send(String msg);
}
class EmailService implements MessageService {
@Override
public void send(String msg) {
System.out.println("发送邮件:" + msg);
}
}以后如果改成短信、站内信,只需要更换实现类。
10.3 配合多态和工厂模式
很多框架会返回接口类型对象,让业务代码只关心能力,不关心底层具体实现。
十一、常见注意点
- 接口不能实例化
- 实现类重写接口方法时,访问权限不能低于
public - 接口中的常量一般通过接口名访问,不建议用实现类名访问
- 不要把接口只当作“常量容器”使用,这会破坏接口的设计意义
十二、实践建议
- 优先面向接口编程,而不是直接依赖具体类
- 接口命名要清晰表达能力,例如
Payable、Readable - 一个接口的方法数量不要过多,职责要单一
- 接口适合做扩展点,抽象类适合做基础实现层
