The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:
你认为面向对象编程中的对象是什么?无论你使用什么编程语言,你很可能会同意Bruce Eckel的观点,他是《Thinking in Java》的作者,他说”每个对象都有一个状态和可以要求它执行的操作”,或者Benjamin Evans的观点,他是《Java in a Nutshell》的作者,他认为对象是”一组保存值的数据字段和对这些值进行操作的方法”。然而,请稍等…如果我告诉你一个对象可能没有”操作”,但仍然是一个完美的”构成宇宙的量子的等价物”,正如David West在他的伟大著作《Object Thinking》中所提出的那样,你会怎么想呢?
在我们的实验性编程语言EO中,我们试图重新定义面向对象编程及其对象。EO中有两种类型的”事物”:原子和对象。原子是最低级别的语言原语,不能由其他原子表示。例如,两个其他对象的算术相加就是一个原子(跟我一起,这是EO的语法,你会习惯的):
在更传统的类似Java的中缀表示法,这段代码将如下所示:
原子是 add
,它的两个具体参数是 5
和 y
。这个语句创建了一个新的原子,使用现有的原子并指定其参数。正在创建的新原子的名称是 x
。一旦我们要求这个新创建的原子做任何事情,它会获取 y
中的内容,加上 5
,然后开始像它们的总结一样行动。在此之前,它保持安静。EO 是一种声明性语言。
原子由 EO 运行时提供。例如,add
、sub
、mul
和 div
用于算术运算;if
和 for
用于分支和迭代;less
、and
、eq
、or
用于逻辑运算,等等。原子可能类似于带有参数的低级函数。然而,它们不会立即计算结果,而是在需要时才计算。说 add(5, file)
不会立即导致读取文件的内容并将其加上 5。只有在处理创建的原子时,文件读取才会发生。
接下来,程序员可以在这些原子的基础上创建对象。例如,这是一个表示圆的对象:
第一行创建了一个名为circle
的“抽象”对象。它是抽象的,因为它的属性之一r
是“自由的”。在这个对象中没有指定它,这就是为什么不能直接使用该对象,必须使用指定了r
值的副本。例如,这是一个半径为30的圆c
。
对象 circle
有三个属性。第一个属性是 r
,它是自由的。另外两个属性是 perimeter
和 area
。它们是“有界”的,因为它们的原子已经定义了:在两种情况下都是 mul
。要获得圆 c
的面积,我们这样做:
看起来像是一个方法调用,但实际上并不是。我们不调用一个方法,我们只是从对象c
中获取一个area
对象。在我们执行c.area
的那一刻,它并不是为我们创建的!它已经存在了,静静地等待我们来获取它。它是在对象c
被构建时就已经创建好了。
这就是Java中的方法和EO中的属性的区别。在Java中,每个方法都是在被调用时立即执行的过程。这种方法调用(或根据早期面向对象编程的专家的说法,消息发送)机制是从C函数中继承而来的,而C函数本身则是从ALGOL过程中继承而来的,我相信。EO则采用了不同的方式。它没有方法调用。它只是从对象中取出属性并将它们传递给其他对象,直到控制权传递给它们并降至原子级别。
在上面的例子中,对象a
不是一个计算得出的数字。它是一个封装了3.14
和30
(半径)的原子mul
。计算结果尚未知道。如果我们对a
什么都不做,CPU将永远不会进行计算。然而,如果我们决定将数字打印到控制台上,计算将会发生:
在这里,原子sprintf
构造了一个字符串,其中封装了三个属性:文本,r
和a
。顺便说一下,可以使用垂直或水平符号来构造对象。上面的代码可以这样写:
stdout
原子封装了由sprintf
构建的字符串并保持沉默。它不打印任何东西!只有当某人在某个时刻尝试“触碰”此对象,取出其中的一个属性时,stdout
原子才会将该行内容输出到控制台。
stdout
、sprintf
、mul
和大多数其他原子中都没有属性,除了一个:𝜑。任何对象或原子都具有这个特定属性,也称为对象的“主体”。一旦有人尝试触碰stdout.𝜑
,控制台将显示该字符串。
因此,我们有对象,但我们没有方法。只有表示其他对象的属性。
Translated by ChatGPT gpt-3.5-turbo/42 on 2023-12-27 at 13:49