贝利信息

Java接口与实现类关系的解析

日期:2026-01-06 00:00 / 作者:P粉602998670
接口不能直接new,但可通过匿名类或Lambda实例化;实现类必须implements并覆盖全部抽象方法;接口支持多继承,运行时引用类型不影响实际对象行为。

接口不能直接 new,但可以用匿名类或 Lambda 实例化

Java 中 interface 是纯抽象类型,编译器禁止写 new MyInterface()。但这不意味着它完全不能“变成对象”——只要提供所有抽象方法的实现,就能构造实例。

常见做法有两种:

Runnable r = () -> System.out.println("hello");
Comparator c = (a, b) -> a.length() - b.length();

注意:Lambda 本质是编译器生成的私有静态方法 + 内部类桥接,不是语法糖那么简单;过度嵌套或捕获大对象可能影响 GC。

实现类必须 implements 接口,且覆盖全部抽象方法

一个类要成为某接口的实现者,必须显式声明 implements InterfaceName,并在编译期满足契约:所有 public abstract 方法都有可访问的 public 实现(默认方法和静态方法不用覆写)。

容易忽略的细节:

接口之间可用 extends,但只能单继承、可多继承

接口支持用 extends 继承其他接口,语法上允许一次写多个父接口,例如:interface A extends B, C, D。这和类的 extends(只允许一个)完全不同。

这种设计让接口能组合能力,比如:

interface Readable extends AutoCloseable {
    String readLine();
}
interface Writable {
    void write(String s);
}
interface TextFile extends Readable, Writable { }

但要注意:若 B 和 C 都定义了同名同参的 default 方法,TextFile 编译不过,必须自己提供实现。

运行时无法区分「通过接口引用」还是「通过实现类引用」指向同一对象

Java 的多态发生在运行时,JVM 只看实际对象类型,不看变量声明类型。也就是说:MyInterface obj = new MyClass();MyClass obj = new MyClass(); 创建的是同一个对象,只是引用类型不同。

关键影响:

这个机制是 Spring AOP、Mockito 动态代理等工具的基础——它们返回的往往是一个实现了目标接口的代理对象,你拿它当接口用完全没问题,但底层根本不是原实现类