抽象类是Java中不可实例化但可定义共通属性、方法及抽象方法的类,用于代码复用和契约约束;应基于“is-a”关系设计,聚焦共性逻辑与子类差异点,相比接口更适于共享实现和状态,而避免全抽象或过度继承。

抽象类在 Java 中是构建可复用、可扩展类结构的重要工具,它本身不能被实例化,但可以定义共通的属性、方法(包括具体实现和未实现的抽象方法),为子类提供统一的模板和基础能力。
抽象类的核心作用
抽象类主要解决两个问题:一是避免重复代码,把多个子类共有的字段和逻辑封装在父类中;二是强制子类遵循某种契约,通过抽象方法规定“必须做什么”,而不关心“怎么做”。比如一个图形系统中,Shape 可以是抽象类,定义 area() 和 perimeter() 为抽象方法,同时提供通用的 color 字段和 setColor() 方法。
如何合理设计抽象类
- 只在确实存在“is-a”关系且有共性逻辑时才用抽象类,避免为了抽象而抽象
- 把子类都需继承的字段、工具方法、默认行为放在抽象类里,提升复用性
- 抽象方法应聚焦于子类差异点,命名清晰、职责单一,例如 connect()、parseData()
- 构造方法可以存在(用于初始化共用状态),但仅能由子类调用,不能直接 new
抽象类 vs 接口:什么时候选哪个?
当需要共享代码实现(如日志记录、参数校验、资源初始化)或维护状态(如计数器、缓存引用)时,抽象类更合适;接口更适合定义行为契约,尤其是多继承场景(一个类可实现多个接口)。Java 8 后接口支持 default 方法,但无法定义实例字段或构造逻辑,这点仍是抽象类不可替代的优势。
常见误用提醒
- 抽象类里全是抽象方法?那基本等价于接口,建议改用 interface
- 过度深层继承(A → B → C → D),会增加维护难度,优先考虑组合或接口拆分
- 在抽象类中暴露过多 protected 方法,可能破坏封装,只开放真正需要子类定制的部分


















