Java接口用interface定义,不能实例化,只声明能力;方法默认public abstract,字段默认public static final;Java 8+支持default和static方法;接口强调契约与多实现,抽象类强调模板与单继承。
Java接口用 interface 关键字定义,不是类,不能被实例化,只描述“能做什么”,不关心“怎么做”。接口中默认所有方法都是 public abstract,所有字段都是 public static final —— 即使你不写这些修饰符,编译器也会自动补上。
常见错误是试图在接口里写普通方法体或非静态非final字段:
public interface Logger {
String VERSION = "1.0"; // ✅ 等价于 public static final String VERSION = "1.0";
void log(String msg); // ✅ 等价于 public abstract void log(String msg);
void debug(String msg) { } // ❌ 编译报错:interface method cannot have body
private int count; // ❌ 编译报错:field in interface must be public static final}
Java 8+ 接口可以包含 default 和 static 方法
从 Java 8 开始,接口支持 default 方法(提供默认实现)和 static 方法(直接通过接口名调用)。这是为了解决接口升级时避免破坏已有实现类。
default 方法可被实现类继承、重写,但不能是 private 或 final
static 方法不能被重写,只能通过 InterfaceName.method() 调用default 方法,该类必须显式重写这个方法,否则编译失败public interface Drawable {
default void draw() {
System.out.println("Drawing with default behavior");
}
static void info() {
System.out.println("This is a drawable object");
}}
// 使用示例:
Drawable.info(); // ✅ 直接调用
new Circle() {}.draw(); // ✅ 调用默认实现
接口与抽象类的关键区别在哪
选接口还是抽象类,关键看设计意图:
Runnable、Comparable),支持多实现;抽象类强调“共性模板”,只能单继承protected 或包私有方法(Java 9+ 支持 private 方法,仅用于辅助 default 方法)接口名通常用形容词或名词,如 Serializable、Collection、CharSequence,避免加 I 前缀(那是 C# 风格,Java 社区不推荐)。
容易被忽略的点:
default 方法看似方便,但如果逻辑复杂或依赖实现类状态,反而会模糊职责边界,建议只做简单兜底UserService 对应的 UserServiceInterface 是冗余的,除非你真有多个实现要切换接口不是越多越好,而是要在“解耦”和“可维护性”之间找平衡点。尤其在模块边界、SPI 扩展点、测试替身这些真实场景下,才真正体现它的价值。