Java接口(Interface)与抽象类(Abstract Class)
侧边栏壁纸
  • 累计撰写 40 篇文章
  • 累计收到 1 条评论

Java接口(Interface)与抽象类(Abstract Class)

ASN__
2026-07-07 / 0 评论 / 3 阅读 / 正在检测是否收录...

这是一份为你定制的Java接口(Interface)与抽象类(Abstract Class)终极对比笔记

这份笔记整合了从Java 7到Java 17的所有语法变迁,并深入到设计哲学底层JVM机制,适合面试冲刺或作为案头速查手册。


📌 第一部分:核心定义(先定调)

  • 抽象类(Abstract Class)“不完整的实体”。它用来描述一类事物公共的“本质”(状态+行为)。它可以有构造器、有属性、有已实现的方法,但因为不够具体,所以不允许被new出来。
  • 接口(Interface)“纯粹的契约/能力”。它用来定义一种“行为规范”。它不管实现者是谁(可以是鸟、飞机、超人),只要签署了这份契约(implements),就必须具备这个能力。

📌 第二部分:终极语法速查表(Java 8+ 特别版)

对比维度抽象类(Abstract Class)接口(Interface)
关键字abstract classinterface
实例化(new)不能(无法创建对象)不能(无法创建对象)
构造方法可以有(用于子类初始化父类属性)绝对没有(因为无实例变量需初始化)
成员变量可以是任何类型private/protected/public 实例变量,可以有状态)默认且只能是 public static final(常量),变量必须显式赋初值
普通具体方法可以有(直接写带{}的方法体)Java 8+ 通过 defaultstatic 可以有;Java 9+ 通过 private 可以有
抽象方法使用 abstract 关键字,子类必须实现(除非子类也是抽象类)默认隐含 public abstract,实现类必须实现(除非实现类是抽象类)
继承/实现关系单继承(一个类只能 extends 一个父类)多继承/多实现(一个接口可以 extends 多个接口;一个类可以 implements 多个接口)
访问修饰符限制方法可以是 public/protected/private/default接口中的抽象方法隐含且只能是 public(不能是privateprotected,否则编译报错)
静态方法可以有,子类可以继承调用可以有(Java 8+),但只能通过接口名调用,实现类无法继承
final 修饰可以有 final 方法(禁止子类重写)接口中的方法不能声明为 final(因为抽象/默认方法天生需要被重写或覆盖)

📌 第三部分:方法家族全览(最易混淆点详解)

接口到底能写哪些方法?这是面试高频扣分点:

方法类型是否允许(接口)是否允许(抽象类)备注
抽象方法(无方法体)允许(隐含public abstract允许接口只干这事(Java 7之前)
实例具体方法(有方法体)不允许(直到Java 8)允许抽象类主打的功能
default 方法(Java 8+)允许用于接口版本升级,避免老实现类报错
static 方法(Java 8+)允许允许接口的static不可继承;抽象类的static可被子类继承调用
private 方法(Java 9+)允许允许接口内用于抽取default方法的公共逻辑,不对外暴露

📌 第四部分:设计哲学(本质区别,面试必答)

  • 抽象类:本质是“是什么”(Is-A)

    • 侧重于对象本身。子类和父类必须有血缘关系(例如:Dog extends Animal)。
    • 用于捕获公共的状态(属性)通用的基础逻辑
    • 例子:所有订单都有订单号金额,创建时都要打印日志。这些状态和步骤必须由抽象类来定义,接口做不到。
  • 接口:本质是“能做什么”(Can-Do / Like-A)

    • 侧重于对象拥有的能力。完全不相关的类可以通过实现同一个接口获得相同能力(例如:BirdPlaneSuperman 都能实现 Flyable)。
    • 用于定义行为契约,不关心实现者的内部状态。
    • 例子Comparable(可比较)、Runnable(可运行)、Serializable(可序列化)。

📌 第五部分:经典协作模式(源码级的黄金搭档)

在顶级框架(如Spring、JDK集合框架)中,它们从不“单打独斗”,而是按照 “接口定义标准 + 抽象类提供骨架 + 具体类实现业务” 三层结构配合:

           [List 接口]           ← 定义契约(能添加、能删除、能遍历)
              ↑ (implements)
        [AbstractList 抽象类]   ← 提供骨架(把 indexOf、equals 等通用逻辑先写一半)
              ↑ (extends)
   ┌──────────┴──────────┐
[ArrayList]          [LinkedList]  ← 具体实现(各自实现最核心的差异化逻辑)

结论:用接口应对多态和扩展,用抽象类应对代码复用和封装状态


📌 第六部分:面试高频陷阱题(查漏补缺)

  1. 抽象类能实现接口吗?
    可以。且抽象类实现接口时可以不实现接口的方法,留给具体子类去实现(这就是适配器模式的底层原理)。
  2. 接口能继承抽象类吗?
    绝对不可以。接口只能 extends 接口,不能 extends 类(语法上禁止)。
  3. 什么时候用 default 方法重写?
    一个类实现了两个接口,两个接口都有同名的 default 方法,此时实现类必须显式重写该方法,否则编译冲突。
  4. 抽象类里的 static 方法和接口里的 static 方法区别?
    抽象类的 static 方法可以通过子类名直接调用(继承);接口的 static 方法只能通过接口名调用,子类/实现类无法继承。

📌 第七部分:极简决策脑图(实用场景)

如果你的需求是:
├── 共享给子类公共的 属性(成员变量)?
│   └── 是 → 必须用 抽象类(接口存不住状态)
├── 需要 非public 的访问权限(protected/private)?
│   └── 是 → 必须用 抽象类
├── 想要为 完全无关的类 提供通用能力(如序列化)?
│   └── 是 → 必须用 接口
├── 想要利用 多重继承 的好处?
│   └── 是 → 必须用 接口
└── 想要为已有系统做功能增强(不破坏旧代码)?
    └── 是 → 用接口的 default 方法(Java 8+)

这份笔记涵盖了从语法到架构的全部精髓。如果你想基于这份笔记,手写一个“接口+抽象类”配合的实际Demo(比如模拟Spring的BeanFactory),我可以立刻给你写一份,让你彻底吃透它们的配合使用。😊

0

评论

博主关闭了所有页面的评论