知识卡片

封装与继承并非面向对象编程独有的能力

普通读书笔记卡

内容

“面向对象=封装+继承+多态”是常见说法,但逐项拆解会发现前两者根本不是OOP带来的新能力。封装方面,C语言早就能实现完美封装:把数据结构和函数实现放在.c文件里,只在.h头文件里前置声明,使用者能调用函数却完全看不到内部数据成员——反倒是C++因为编译器技术限制,要求类的成员变量必须写进头文件(哪怕标了private,使用者也能”看见”它们的存在,改个变量名还得重新编译依赖它的文件),Java/C#更是彻底取消了声明与实现分离,进一步削弱了封装性;面向对象语言相对C这种”完美封装”语言,封装性其实是被削弱而非加强了,很多OOP语言甚至并不强制要求封装。继承方面,早在OOP理论提出之前,C程序员就靠”让派生结构体的前几个成员顺序和基础结构体完全一致”这种投机取巧的手段实现了单继承的效果(把NamedPoint伪装成Point来用)——虽不如现代继承语法便利、多重继承也难以这样模拟,但继承性的基本能力早已存在。综合下来:面向对象编程在封装性上得0分,在继承性上勉强0.5分(满分1分)——真正决定OOP价值的,要看第三个特性:多态。

参考来源

- 位置:《架构整洁之道》第5章《面向对象编程》"封装""继承"(源文件:_epub-src/text/part0011_split_003.html) - 结论依据:原文用C语言头文件前置声明实现完美封装、C++因编译器限制反而削弱封装、Java/C#取消声明实现分离进一步削弱封装的对比,以及C语言用结构体成员顺序一致实现类继承伪装的例子,说明这两个特性并非OOP独有,并给出"封装0分、继承0.5分"的评价,直接支撑本卡片结论。 - 原始内容:我们很难说强封装是面向对象编程的必要条件……面向对象编程在应用上确实会要求程序员尽量避免破坏数据的封装性。但实际情况是……其封装性都被削弱了,而不是加强了……面向对象编程在封装性上得0分,在继承性上勉强可以得0.5分。