面试知识库
基础

接口与抽象类区别#

一句话答案#

接口定义能力规范支持多实现,抽象类定义模板只能单继承;JDK8 后接口可有 default 方法,两者边界模糊。

核心要点
维度接口抽象类
继承多实现单继承
方法抽象+default抽象+具体
变量只能static final可以有实例变量
构造器
面试回答(2分钟版)

接口和抽象类在语法和设计语义上有明确区别。语法层面,接口支持多实现一个类可以实现多个接口,抽象类只能单继承;接口中的变量只能是 static final 的常量,抽象类可以有实例变量;接口没有构造器,抽象类有构造器可供子类调用。JDK 8 之后接口可以有 default 方法和 static 方法,这让接口也能提供默认实现,两者的边界变得模糊了一些。设计语义层面,接口定义的是能力规范,表示一个类能做什么,比如 Comparable 表示可比较、Serializable 表示可序列化;抽象类定义的是模板和继承体系,表示一个类是什么,比如 AbstractList 是列表的骨架实现。选择原则是:定义跨继承体系的能力契约用接口,定义同族类的公共模板和状态用抽象类。JDK 8 的 default 方法带来了菱形继承冲突问题,当一个类实现的两个接口有同签名 default 方法时必须手动重写解决冲突。函数式接口是只有一个抽象方法的接口,可以用 Lambda 表达式简洁实现。

追问与易错

追问方向:

  • “JDK8 的 default 方法带来了什么问题?”→ 菱形继承冲突:当一个类实现的两个接口有同签名 default 方法时,编译器报错,必须手动重写该方法明确选择哪个实现
  • “什么时候用接口什么时候用抽象类?”→ 定义跨继承体系的能力契约用接口(如 Comparable、Serializable);定义同族类的公共模板和共享状态用抽象类(如 AbstractList)
  • “函数式接口是什么?”→ 只有一个抽象方法的接口(可用 @FunctionalInterface 注解标注),可以用 Lambda 表达式简洁实现,如 Runnable、Comparator、Function

易错点:

  • ❌ “接口不能有实现”——JDK8+ 可以有 default/static 方法
  • ❌ “抽象类必须有抽象方法”——不是必须的,可以全是具体方法