封装是隔离变化、稳定接口、明确契约,通过访问控制隐藏实现细节,仅暴露语义清晰的公有接口,并辅以文档和类型提示强化行为约定。

封装不是把代码藏起来,而是让用户只关心“能做什么”,不操心“怎么做”。核心是隔离变化、稳定接口、明确契约。
用访问控制划定边界
把算法逻辑、中间状态、辅助函数设为私有,外部无法直接调用或修改:
- Java/C++ 直接用 private 修饰字段和方法
- Python 用双下划线 __sort_helper 或单下划线约定 _cache
- C 语言把结构体定义和实现函数全放在 .c 文件里,头文件只留函数声明和不透明指针(如 typedef struct SorterImpl* Sorter;)
只暴露语义清晰的公有接口
用户调用时不需要知道用了什么算法、数据存在哪、是否线程安全——只要传入合理参数,拿到预期结果即可:
- 提供像 sort(data)、validate(input) 这样职责单一的方法
- 输入接受通用类型(如 list、Iterable),内部自动适配,不强制用户做格式转换
- 返回值不暴露内部结构(例如不返回原始数组引用,而返回新列表或只读视图)
- 异常统一为业务级错误(如 InvalidInputError),不抛出底层异常(IndexError、NullPointerException)
把策略切换也藏在类内部
同一功能有多种实现时(比如快排 / 归并 / 堆排),不靠用户选方法,而是由类自己决定或配置:
- 构造时传参:Sorter(strategy='hybrid'),内部初始化对应私有排序器
- 运行时切换:sorter.setAlgorithm(Algorithm.QUICK),但对外仍是同一个 sort() 方法
- 用户始终调用 sorter.sort(data),完全感知不到底层变化
配合文档和类型提示强化契约
访问控制只是第一步,真正让封装落地的是清晰的行为说明:
- 注释中写明输入约束(如“data 非空,元素支持比较”)
- 说明输出保证(如“原数据不修改,返回新排序列表”)
- 标注复杂度(如“平均 O(n log n),最坏 O(n²)”),这是接口的一部分,不是实现细节
- 用类型系统(如 Python 的 type hints、Java 的泛型)进一步约束参数和返回值











