子类不破坏封装性,但设计不当可能绕过数据保护;应将关键字段设为private,校验逻辑置于final或private方法中,protected仅用于可扩展行为而非字段暴露,构造时锁定不可变性。

子类本身不会“破坏”封装性,但若设计不当,可能绕过本意中的数据保护逻辑。防范的关键不是阻止继承,而是通过权限修饰符的合理组合,让子类在获得必要扩展能力的同时,无法随意篡改核心状态或跳过业务约束。
用 private 封装关键字段,不给子类直接触碰的机会
父类中真正需要保护的数据(如密码、余额、状态标志)必须声明为 private。即使子类继承了该类,也无法直接访问这些字段——它们虽被隐式继承,但不可见、不可读写。
- 错误做法:把 name、balance 等设为 protected 或 default,子类可随意赋值,绕过合法性校验
- 正确做法:字段私有化,所有修改必须走父类提供的受控方法(如
deposit(double amount)),方法内部可做校验、日志、状态联动等
把校验逻辑放在父类的 public/protected 方法里,而非子类重写点
如果允许子类重写 setter 或业务方法,又没在父类层面做强制约束,就容易出现“子类绕过检查”的情况。应把核心校验前置于不可重写的方法中,或用 final 限定关键入口。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 例如:定义
final void setAge(int age) { if (age 150) throw new IllegalArgumentException(); this.age = age; } - 或把校验抽成 private 方法,在多个 public 方法中统一调用,子类无法覆盖该逻辑
慎用 protected,明确它暴露的是“可扩展点”,不是“可修改点”
protected 允许同包类和子类访问,但它常被误当作“给子类留后门”。实际应只对真正需要由子类参与实现的行为开放 protected,比如模板方法中的钩子(protected void onInit() { }),而不是暴露字段或核心 setter。
- 避免:
protected String name;—— 子类可任意改,等于放弃控制 - 推荐:
protected void validateName(String name) { /* 子类可增强校验,但不能跳过 */ },并在父类 setter 中调用
构造阶段就锁定不可变性,减少运行时风险
很多封装问题源于对象创建后被反复修改。对不希望变化的属性,可在构造时初始化,并配合 private + 无 setter 的方式实现事实上的不可变。
- 例如:
private final String id;+ 构造器注入,子类无法更改 - 若需后期更新,提供明确语义的方法(如
updateProfile(ProfileUpdate update)),而非开放字段赋值
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










