抽象类的非抽象方法可直接访问实例变量并参与初始化,接口默认方法不能访问实现类字段且无构造器支持。

能访问对象状态
抽象类的非抽象方法可以直接读写实例变量,因为它属于类的继承体系,拥有完整的对象上下文。比如一个 AbstractLogger 类里有 level 字段,它的非抽象方法 isValid() 就能直接用 this.level 做判断。
接口默认方法做不到这一点——它无法访问实现类的任何实例字段。哪怕实现类定义了 private String mode,默认方法也拿不到。它只能调用该接口中其他方法(包括抽象方法),或依赖传入参数、静态常量、局部变量来完成逻辑。
设计意图不同
抽象类的非抽象方法是模板的一部分,用于提供可复用的、与类状态强相关的通用行为。它天然适合做“父类封装逻辑”。
接口默认方法是演进而来的补丁机制,核心目标是:在不破坏已有实现类的前提下,为接口新增能力。它不承担状态管理职责,也不鼓励在其中处理复杂业务状态流转。
访问控制和复用方式
抽象类中的非抽象方法可以是 public、protected,甚至 private(Java 9+ 支持私有方法),子类是否可见、能否重写,都由修饰符精确控制。
接口默认方法只能是 public,且不能设为 private 或 protected。所有实现类自动获得该方法,但也可选择重写——这带来灵活性,也带来潜在覆盖风险。
构造与初始化支持
抽象类可以定义构造方法,配合非抽象方法完成对象初始化阶段的校验或预处理。例如在构造器里调用 initConfig(),而这个方法就是非抽象的。
接口没有构造器,也没有实例初始化过程。默认方法无法参与对象创建流程,也不能假设调用时对象已处于某种稳定状态。











