2003年,在一次面向计算机科学家的演讲中,被誉为“面向对象编程之父”的艾伦·凯(Alan Kay)再次重申了他对“面向对象编程”(OOP)这一术语原始定义的理解。这番话在当时的开发者社区引发热议,至今仍被许多研究者视为对OOP本质最精准的诠释——而它与今天大多数程序员所理解的“面向对象”相去甚远。
背景:一个被“偷换”的概念
艾伦·凯是Smalltalk语言的发明者,也是“面向对象编程”这个名词的创造者。上世纪60年代末,他在犹他大学攻读博士学位期间,受生物学和计算机图形学的启发,提出了以“细胞”为隐喻的编程模型。每个计算单元像一个活细胞,通过消息传递与其他细胞沟通,独立管理自己的内部状态。
然而,随着C++、Java等语言的流行,“面向对象”逐渐被简化为“类+继承+多态”的三件套。到了2003年,大多数程序员认为OOP就是“把数据和方法封装在对象里”,甚至将“对象”等同于“类的实例”。这与凯最初的设想存在巨大差异。
核心观点:消息传递高于对象
在那场2003年的演讲中,凯直言不讳地批评了当时的主流实践。他强调:“OOP的精髓不是对象,而是消息传递。 对象只是消息的接收者。”
他解释道,自己最初设想的是“像生物细胞一样,通过膜上的受体接受信号,然后自主决定如何响应”。这意味着对象间的耦合度应当降到最低——对象不知道其他对象的内部结构,甚至不知道它们是什么类,只需要知道能发送什么消息。这种思想的极端体现是Smalltalk中的“鸭子类型”:如果一只鸟走起来像鸭子、叫起来像鸭子,那它就是鸭子。
凯还警告说,过度强调继承会导致“脆弱的基类问题”,而将关注点放在类层次结构上,会让程序员陷入静态设计的陷阱,忽略了运行时动态性的巨大价值。他指出:“如果你把重点放在类上,你得到的是‘分类编程’;如果你把重点放在消息上,你得到的是真正的面向对象。”
与当代实践的落差
凯的观点在今天依然振聋发聩。现代主流OOP语言如Java、C++、Python,都在某种程度上偏离了消息传递的本质。以Java为例,它通过接口和抽象类实现多态,但本质上依赖静态类型检查,对象间的交互往往是通过方法调用(本质上仍是函数调用),而非真正意义上的异步消息传递。
相比之下,Erlang、Elixir等语言中使用的Actor模型,以及Go语言的goroutine+channel模式,更接近凯最初的设想:每个Actor有自己的信箱,通过异步消息通信,没有共享状态。而Smalltalk的“一切皆对象”和“运行时元编程”能力,至今仍未被主流语言完全继承。
历史地位与现实意义
为什么一位计算机科学家在20年前的观点,今天仍值得被重提?原因有二。
第一,它澄清了一个长期存在的误解。很多程序员在面试中被问“什么是OOP”,答案往往是“封装、继承、多态”。但凯本人对此明确表示:“继承是妥协的产物,多态是消息传递的自然结果。” 他的定义提醒我们:不要被语法糖迷惑,编程范式的核心是计算模型本身。
第二,在分布式系统、微服务架构盛行的今天,“消息传递”的价值被重新发现。云原生应用中的事件驱动架构、Kafka等消息中间件的广泛使用,本质上就是在践行凯的理念——让各个服务作为独立对象通过消息协作,避免紧耦合。从这个角度看,凯的预言比他所处的时代超前了整整三十年。
结语:回归初心
艾伦·凯曾有一句广为流传的名言:“预测未来最好的方法就是创造未来。”他创造的面向对象编程,本意是让软件像生命系统一样健壮、灵活、可演化。而2003年那场演讲,正是他对被扭曲的“创造物”的一次温柔纠错。对今天的程序员而言,理解凯的真实意图,或许能帮助我们跳出类继承的束缚,重新思考如何设计更符合人类认知和自然规律的软件系统。
消息传递,而非对象本身——这或许才是面向对象编程留给后世最深刻的遗产。