Python 使用稍微不同的术语。它被称为“调用方法”。但这是同一回事。 (C++ 称之为“调用虚函数”。同样的区别。)
就我个人而言,我不喜欢这个术语,它过于关注实现细节,失去了“消息发送”术语的很多隐喻能力。
与 Python 还存在其他差异,其中一些最重要的差异是:
- 面向对象的数据抽象是通过约定实现的,而不是作为内置语言功能(例如 Smalltalk、Ruby)或设计模式(Scheme、ECMAScript)
- 并非所有子例程都是方法
OO 的基本思想是消息传递:您向对象发送消息,对象会做出响应。就像在现实生活中一样,您不知道对象对消息做了什么。你能看到的只是回复。对象可能自己处理消息,可能会借助他人的帮助,可能会盲目地转发消息,而实际上自己没有做任何工作。
由于您不知道对象对消息做了什么,并且您只能观察到对象的响应,因此您对对象的所有了解都是它的协议(它理解的消息以及它是如何理解的)回应他们)。你不知道它的实现,你不知道它的表示。 OO就是这样实现数据抽象、信息隐藏、数据隐藏、封装的。
此外,由于每个对象独立决定如何响应消息,因此您会得到多态性。
一种响应消息的典型方式是执行与该消息对应的方法。但这是一种实现机制,这就是我不喜欢这个术语的原因。作为一个比喻,它没有我上面提到的任何内涵。
Alan Kay has said that OO is about three things, Messaging, Data Abstraction, and Polymorphism:
对我来说,OOP 仅意味着消息传递、本地保留、保护和隐藏状态过程,以及所有事物的极端后期绑定。
他后来澄清the Big Thing is Messaging:
只是一个温和的提醒,我在上一届 OOPSLA 上努力提醒大家,Smalltalk 不仅不是它的语法或类库,它甚至与类无关。很抱歉,我很久以前就为这个主题创造了“对象”一词,因为它让很多人专注于次要的想法。
最重要的想法是“消息传递”——这就是 Smalltalk/Squeak 的核心内容(在我们的 Xerox PARC 阶段,它从未完全完成)。日本人有一个小词——ma——代表“介于两者之间的东西”——也许最接近的英语等价物是“interstitial”。制作出色且可扩展的系统的关键在于设计其模块的通信方式,而不是设计其内部属性和行为应该是什么。想想互联网——为了生存,它 (a) 必须允许许多不同类型的想法和实现超出任何单一标准,并且 (b) 允许这些想法之间不同程度的安全互操作性。
事实上,正如我上面所说的,在我看来,另外两个只是消息传递的结果。
当 Alan Kay 提出“面向对象”一词时,他深受后来成为 ARPANet 和互联网的启发:具有自己私有内存(“实例变量”)的独立机器(“对象”)通过发送消息相互通信。
William R. Cook 和他的Proposal for Simplified, Modern Definitions of "Object" and "Object Oriented" 在On Understanding Data Abstraction, Revisited 中也提出了类似的观点。
操作的动态分派是对象的基本特征。这意味着要调用的操作是对象本身的动态属性。操作不能被静态识别,并且通常没有办法确切地知道响应给定请求将执行什么操作,除非通过运行它。这与始终动态调度的一流函数完全相同。
Python 的对象系统与其他语言有点不同。 Python 最初是一种过程语言,后来添加了对象系统,目的是尽可能减少对语言的更改。 Python 中的主要数据结构是dicts(映射/哈希表),所有行为都在函数中。甚至在 Python 的 OO 功能之前,这种极简主义就已经显现出来,例如局部变量和全局变量实际上只是 dict 中的键。因此,很自然地将对象和类制作成类似于dicts 并重用该概念,对象本质上是dict 的值,而类是dict 的函数。 “方法”没有单独的概念,相反,您有将接收者作为第一个参数的函数。 (在大多数其他 OO 语言中,接收者是一个“隐藏的”第零个参数,并且可以使用特殊关键字(例如 self、this 或 me。)