接口不能直接new,但可通过匿名类或Lambda实例化;实现类必须implements并覆盖全部抽象方法;接口支持多继承,运行时引用类型不影响实际对象行为。
Java 中 interface 是纯抽象类型,编译器禁止写 new MyInterface()。但这不意味着它完全不能“变成对象”——只要提供所有抽象方法的实现,就能构造实例。
常见做法有两种:
Runnable、Comparator、自定义的 @FunctionalInterface
Runnable r = () -> System.out.println("hello");
Comparator c = (a, b) -> a.length() - b.length(); 注意:Lambda 本质是编译器生成的私有静态方法 + 内部类桥接,不是语法糖那么简单;过度嵌套或捕获大对象可能影响 GC。
implements 接口,且覆盖全部抽象方法一个类要成为某接口的实现者,必须显式声明 implements InterfaceName,并在编译期满足契约:所有 public abstract 方法都有可访问的 public 实现(默认方法和静态方法不用覆写)。
容易忽略的细节:
abstract,可以不实现部分抽象方法default 方法可被重写,但子类若想调用父接口的默认实现,需用 InterfaceName.super.method()
default 方法时,实现类必须显式重写,否则编译报错:class inherits unrelated defaults for method from types
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(); 创建的是同一个对象,只是引用类型不同。
关键影响:
public static final 常量)(MyClass) obj)必须确保实际类型匹配,否则抛 ClassCastException
这个机制是 Spring AOP、Mockito 动态代理等工具的基础——它们返回的往往是一个实现了目标接口的代理对象,你拿它当接口用完全没问题,但底层根本不是原实现类
