Java中重写非抽象方法是否属最佳实践?两类重写的概念差异
回答
针对你的场景,直接在目标子类中重写非抽象父类方法绝对是最优解,完全符合Java的面向对象设计原则,而方案1把父类方法设为抽象让其他子类重复写代码的做法,简直是维护灾难——完全违反了DRY(Don't Repeat Yourself)原则,以后通用逻辑要修改的话,你得挨个改所有子类,既耗时又容易出错。
接下来聊聊重写非抽象方法和抽象方法的核心区别:
1. 父类方法的基础状态不同
- 重写非抽象方法:父类已经提供了一个可用的、经过验证的通用实现,子类重写是为了替换或扩展这个默认逻辑。大部分子类可以直接继承父类的代码,不需要做任何修改,就像你场景里的非目标子类,直接用父类逻辑就行。
- 重写抽象方法:父类只有方法签名,没有任何具体实现(或者说实现是
throw new UnsupportedOperationException()这类占位逻辑),子类必须强制重写来提供自己的具体实现——如果子类不重写,那它自己也得被标记为抽象类。这是父类给子类定下的“必须完成的契约”。
2. 设计意图的本质差异
- 非抽象方法重写:父类的设计是提供通用行为,子类重写是处理例外情况。比如你这个场景,只有一个子类需要特殊逻辑,其他都遵循通用规则,这种用重写非抽象方法的方式,完美贴合“大部分复用、少数定制”的需求。
- 抽象方法重写:父类无法给出一个适合所有子类的通用实现,只能定义“必须做什么”,把“怎么做”交给每个子类。比如
Animal类的makeSound(),猫、狗、鸟的叫声完全不同,父类根本没法写通用实现,只能设为抽象方法让子类各自实现。
3. 代码冗余度的区别
- 重写非抽象方法:完全避免冗余,通用逻辑只在父类写一次,子类只需要编写自己特殊的部分。甚至还可以通过
super.doSomething()调用父类的通用逻辑,再叠加自己的定制代码,实现逻辑扩展。 - 重写抽象方法:如果多个子类的实现逻辑相同,就会出现大量重复代码——这时候反而应该把通用逻辑抽到父类,改成非抽象方法,只让有特殊需求的子类重写。
给你举个简单的代码示例,对应你的场景:
// 父类:提供通用逻辑 class BaseService { public void processRequest() { // 所有子类通用的前置校验、日志记录等逻辑 System.out.println("通用请求预处理"); // 核心业务逻辑(这里是通用版) System.out.println("通用业务处理"); } } // 普通子类:直接继承父类逻辑,无需修改 class UserService extends BaseService { // 空实现,直接用父类的processRequest } // 普通子类:同样复用父类逻辑 class OrderService extends BaseService { // 空实现,直接用父类的processRequest } // 特殊子类:重写方法实现专属逻辑 class AdminService extends BaseService { @Override public void processRequest() { // 可以选择先调用父类的通用预处理 super.processRequest(); // 再添加管理员专属的特殊逻辑 System.out.println("管理员专属权限校验与日志审计"); } }
内容的提问来源于stack exchange,提问作者Learner
相关产品推荐
相关产品推荐

