抽象类适用于不可单独实例化、需约束子类行为、有共用逻辑需下沉的场景;普通类适用于可直接实例化的具体实体。

抽象类和普通类不是“哪个更好”,而是“谁更适合当前场景”。设计时的关键,是看这个类在系统中该不该被直接创建对象、要不要约束子类行为、有没有共用逻辑需要下沉。
看这个类能不能独立存在
如果一个概念在业务中天然不能单独实例化,就该用抽象类。比如“支付方式”本身不是一种具体操作,但“微信支付”“支付宝支付”是;“文档”不是实体,但“PDF文档”“Word文档”是。
普通类必须能 new 出来,否则编译报错。抽象类禁止 new,强制走继承路线——这不是限制,而是设计信号:它本就不该被单独使用。
看是否需要统一子类的行为契约
当多个子类必须实现同一组方法,且每个实现逻辑不同,抽象类比普通类更可靠:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 抽象类中声明 abstract void process(),子类不重写就编译失败,杜绝遗漏
- 普通类只能提供默认实现,子类可覆盖也可不覆盖,容易导致行为不一致
- 接口也能强制,但无法自带状态(如 protected 字段)或构造逻辑
看有没有可复用的基础能力要共享
抽象类支持构造方法、成员变量、protected 方法、通用工具逻辑——这些都能被子类直接继承复用。
例如数据库访问基类 BaseDao:
- 封装了 getConnection()、close()、logSQL() 等通用流程
- 留出 abstract String getSql() 和 abstract Object mapRow(ResultSet) 由子类定制
- 普通类做不到这种“一半交出去、一半收回来”的控制力
警惕误用:别为了抽象而抽象
以下情况不适合抽象类:
- 只是工具方法集合(如 StringUtils),用普通类 + static 方法更清晰
- 子类之间几乎没有共性,硬拉一个父类反而增加耦合
- 未来可能需要多继承语义(Java 单继承限制下,此时接口更灵活)
抽象类的价值,在于把“必须做的事”和“可以复用的事”打包成一个可继承的契约。选对了,代码结构清晰、扩展可控;选错了,后期要么重构痛苦,要么变成空有 abstract 关键字的摆设。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










