Smalltalk 和 Java 中的 OO 之间的主要区别是什么?

2022-09-01 00:49:58

Smalltalk 和 Java 中的 OO 之间的主要区别是什么?

请注意,我是一名Java程序员,试图通过探索Smalltalk来扩展他的视野。目前,我对Smalltalk几乎一无所知,只知道它比Java更纯粹。因此,我更喜欢这个答案,即展示各种Java概念如何映射到相应的Smalltalk概念,然后介绍Java中根本不存在的Smalltalk概念。


答案 1

消息传递

Smalltalk使用消息传递,而不是方法调用。这种区别是微妙的,但非常强大。

一些术语:给定 ,是一个选择器,foo 是一个名为的消息的接收者(# 表示一个符号,就像 Common Lisp 会说的(或者更恰当地说,)),并且是一个参数参数。当行执行时,将发送带有参数的消息。到目前为止,这很正常。在Java中,它看起来像。foo bar: baz#bar:#bar:'bar:barbazfoo#:bar:bazfoo.bar(baz);

在Java中,运行时系统会找出实际类型,找到最合适的方法,然后运行它。foo

Smalltalk中,事情看起来几乎一样。向对象发送消息时,它会在其方法字典中搜索其名称与消息选择器的名称匹配的方法。如果它找不到,它会在其超类的方法字典中搜索,依此类推。很正常的东西。

如果它找不到任何匹配的方法,它会向自己发送消息,并将原始消息作为参数。(是的,消息发送是一个对象。但也只是一种方法。您可以覆盖它。#doesNotUnderstand:#doesNotUnderstand:

例如,您可以有一个对象,该对象响应某组消息,同时将它收到的任何其他消息转发到某个委托对象。覆盖和嘿,presto,您有一个代理,无需维护即可使其协议与委托保持同步。#doesNotUnderstand:

简单语法

不,我不是在开玩笑。Smalltalk的整个语法可能有15行长。JLS是...为什么不呢。为什么要在乎呢?简单的语法使拆解一块代码变得简单。元编程!重构!

没有以下各项的语法:

  • 条件语句:(n < 3) ifTrue: ['yes'] ifFalse: ['no']
  • 对于循环:1 to: 10 do: [:i | Transcript show: i asString]
  • 尝试捕获:[i := i / 0] ifError: ['oops!']
  • 最后尝试:[i := i / 0] ensure: [stream close]

请注意所有这些 s - 具有干净语法的一等闭包。[]


答案 2
  1. 对象模型。在Smalltalk中,每件事物都是一个对象。Java具有int和float等基元类型,其表示和行为与复杂对象不同。
  2. 行为调用。通过向 Smalltalk 对象发送消息来调用该对象的行为。Java有方法,基本上是函数调用,目标对象是一个特殊的第一个参数,称为。this
  3. 封装。Smalltalk具有严格的封装。对象的字段只能通过消息公开。相比之下,Java允许公共字段。
  4. 活力。Smalltalk非常有活力。所有类型都在运行时标识。类可以在运行时进行内省和修改(动态元编程!可以在运行时创建新类并实例化。Java具有静态类型检查以及运行时多态性。有内省和反射,但类和对象不能从正在运行的程序中修改。
  5. 语法。Smalltalk 没有语法。相反,它具有用于发送消息的简单,一致的格式。与C家族的其他语言一样,Java具有复杂的语法。
  6. 环境。大多数 Smalltalk 实现都提供完整、独立、实时的计算环境,具有基于图像的持久性。其中一些环境甚至可以在裸机上启动。反过来,JVM通常依赖于底层操作系统进行线程化,网络化等。源代码必须输入到文本文件中,编译并显式加载到JVM中才能执行。