学径 LearnPath

编程语言基础 / Wiki

抽象

隐藏实现细节,只把「做什么」这个接口露出来;不是把事情变模糊,而是让思考停在当前这一层。

它是什么

抽象 不是把事情变模糊,而是把暂时不必关心的细节藏起来,让思考停在当前这一层。解方程时,关心的是「给定系数,得到未知数」;移项和除法可以封进一个名字。用的人只看见这个名字和它的参数。抽象的意义不在少写几行,而在让人能思考更大的问题,而不必同时盯着所有齿轮。

在 Python 里,最常见的过程抽象就是 函数:函数名代表能力,内部的判断和运算被挡住。数据抽象则常见于 类:使用者通过方法接触 对象,而不必直接翻内部的格子。模块 把一组相关的定义收成可引入的仓库,是再上一层的分界。

名字从哪来

abstraction 来自拉丁语 abstrahere,意思是「抽离、拉开」。数学里抽象出「数」和「函数」,不再盯着三头牛或五块石头。计算机科学把程序也分层:下一层尽可以复杂,上一层只保留稳定的接口。

「接口」在这里不是电线插头,而是约定:传入什么、传出什么、保证什么。细节换了,只要约定还在,上面的代码就不必重写。这个词在工程里被用得很勤,容易听成口号;它真正要求的是把边界说清楚,而不是把名字起得很短。

它怎么工作

写一个好的抽象,通常要先问三句话:变化的是什么(做成参数)?不变的步骤是什么(做成函数体)?调用者需要什么结果(做成返回值)?层次清楚时,改其中一层不会把整份程序撕开。solve 内部可以再调用更小的函数;画 分形 树时,每一层子树都复用同一套规则。

抽象也会失败:名字含糊、参数过多、有时返回数有时返回一句话,调用者就无法安心依赖它。这时不是「抽象太多」,而是边界没说清。忽略细节不等于可以忽略边界。除数为零、空列表、层数为 0,这些仍然要在接口上交代,或在内部用 异常 诚实报告。

对话式编程 尤其依赖这一层判断。语言模型可以起草实现细节;人必须能说出接口——否则无法判断草稿是否跑题,也无法判断它是否真的在为世界建模。

生活里在哪里

汽车的方向盘:驾驶时不必理解内燃机,但必须知道转向与制动的约定和极限。实验室的仪器面板:按启动,内部流程被封装,量程和误差仍写在说明书上。数学公式把一类计算收成一个符号。这些例子里,抽象从来不是「可以不再理解」,而是「在这一层只处理这一层该处理的问题」;出了错,仍要能走进下一层。

和相近概念的差别

抽象是一种思考方式。函数、类、模块是落实它的容器。注释 可以说明意图,但不能代替抽象。细节仍摊在主流程里时,读的人还是要同时消化所有步骤。

一层函数若又读文件、又画图、又解方程,调用者无法只取其中一件。职责要切开。短名字如果不说明能力,抽象是失败的:f 和 solve_linear 藏起的细节可以一样多,但后者才让人站在问题这一层思考。

常见误会

误会 1:抽象就是少写代码、把名字起得很短。

短而不说明能力,思考无法停在问题这一层。抽象成功与否,看接口是否稳定、是否可检验。

误会 2:一层函数包住所有事情,就是好抽象。

包得太多,等于没有分层。调用者无法只依赖其中一件约定。

误会 3:用了抽象,就不必理解里面发生什么。

第一次写的人必须理解。以后复用时可以暂时不看细节,但出了错仍要能走进去。生成工具不能免除这一条。

想知道更多

  • 书:布鲁克希尔《计算机科学概论》
  • 书:艾伦·唐尼《像计算机科学家一样思考Python(第2版)》
  • 书:查尔斯·佩措尔德《编码:隐匿在计算机软硬件背后的语言》
  • 书:埃里克·马瑟斯《Python编程:从入门到实践(第3版)》

未登录时不会保存学习进度