Objects Without Methods

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,它的两个具体参数是 5y。这个语句创建了一个新的原子,使用现有的原子并指定其参数。正在创建的新原子的名称是 x。一旦我们要求这个新创建的原子做任何事情,它会获取 y 中的内容,加上 5,然后开始像它们的总结一样行动。在此之前,它保持安静。EO 是一种声明性语言。

原子由 EO 运行时提供。例如,addsubmuldiv 用于算术运算;iffor 用于分支和迭代;lessandeqor 用于逻辑运算,等等。原子可能类似于带有参数的低级函数。然而,它们不会立即计算结果,而是在需要时才计算。说 add(5, file) 不会立即导致读取文件的内容并将其加上 5。只有在处理创建的原子时,文件读取才会发生。

接下来,程序员可以在这些原子的基础上创建对象。例如,这是一个表示圆的对象:

第一行创建了一个名为circle的“抽象”对象。它是抽象的,因为它的属性之一r是“自由的”。在这个对象中没有指定它,这就是为什么不能直接使用该对象,必须使用指定了r值的副本。例如,这是一个半径为30的圆c

对象 circle 有三个属性。第一个属性是 r,它是自由的。另外两个属性是 perimeterarea。它们是“有界”的,因为它们的原子已经定义了:在两种情况下都是 mul。要获得圆 c 的面积,我们这样做:

看起来像是一个方法调用,但实际上并不是。我们不调用一个方法,我们只是从对象c中获取一个area对象。在我们执行c.area的那一刻,它并不是为我们创建的!它已经存在了,静静地等待我们来获取它。它是在对象c被构建时就已经创建好了。

这就是Java中的方法和EO中的属性的区别。在Java中,每个方法都是在被调用时立即执行的过程。这种方法调用(或根据早期面向对象编程的专家的说法,消息发送)机制是从C函数中继承而来的,而C函数本身则是从ALGOL过程中继承而来的,我相信。EO则采用了不同的方式。它没有方法调用。它只是从对象中取出属性并将它们传递给其他对象,直到控制权传递给它们并降至原子级别。

在上面的例子中,对象a不是一个计算得出的数字。它是一个封装了3.1430(半径)的原子mul。计算结果尚未知道。如果我们对a什么都不做,CPU将永远不会进行计算。然而,如果我们决定将数字打印到控制台上,计算将会发生:

在这里,原子sprintf构造了一个字符串,其中封装了三个属性:文本,ra。顺便说一下,可以使用垂直或水平符号来构造对象。上面的代码可以这样写:

stdout原子封装了由sprintf构建的字符串并保持沉默。它不打印任何东西!只有当某人在某个时刻尝试“触碰”此对象,取出其中的一个属性时,stdout原子才会将该行内容输出到控制台。

stdoutsprintfmul和大多数其他原子中都没有属性,除了一个:𝜑。任何对象或原子都具有这个特定属性,也称为对象的“主体”。一旦有人尝试触碰stdout.𝜑,控制台将显示该字符串。

因此,我们有对象,但我们没有方法。只有表示其他对象的属性。

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-12-27 at 13:49

sixnines availability badge   GitHub stars