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

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

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

消息传递

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

一些术语:给定foo bar: baz#bar:是一个select器 ,foo是一个名为#bar:的消息的#bar: (#表示一个符号,就像Common Lisp会说'bar (甚至更适合:bar )),而baz是一个参数参数 。 当行被执行时, foo被发送消息#:bar:带有参数baz 。 到目前为止,这是非常正常的。 在Java中它看起来像foo.bar(baz);

在Java中,运行时系统会找出foo的实际types,find最合适的方法并运行它。

事情在Smalltalk中看起来几乎一样。 向对象发送消息时,会在其方法字典中search名称与消息select器的名称匹配的方法。 如果找不到,则在其超类的方法字典中search,等等。 很正常的东西。

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

例如,您可以让一个对象响应某些消息,同时将其收到的任何其他消息转发给某个委托对象。 覆盖#doesNotUnderstand:嘿presto,你有一个代理,将不需要维护,以保持其协议与委托同步。

平凡的语法

不,我不是在开玩笑。 Smalltalk的整个语法可能有15行。 JLS是…不是。 为什么要关心 一个简单的语法可以简单地将一大块代码分开。 元编程! 重构!

没有语法:

  • 条件语句: (n < 3) ifTrue: ['yes'] ifFalse: ['no']
  • for循环: 1 to: 10 do: [:i | Transcript show: i asString] 1 to: 10 do: [:i | Transcript show: i asString]
  • try-catch: [i := i / 0] ifError: ['oops!']
  • try-finally: [i := i / 0] ensure: [stream close]

并注意所有这些使用简洁的语法的一stream的closures。

Java和Smalltalk之间的一个主要区别是,Smalltalk具有一stream的类(没有双关语意思)。

Smalltalk中的一个类是一个对象。 最接近static方法和variables的就是类方法和variables,正如弗兰克·希勒所说的那样。

但是,只要inheritance被使用,这种差异就会更加深刻。 在java类中,inheritance不存在,而在Smalltalk中是可能的。

如果类Ainheritance自B ,并且如果您有ab ,它们是AB实例,则在Smalltalk中, b classinheritance自a class 。 在Java中, a getClass()b getClass()返回Class实例并不相互关联。

现在让我们假设类A实现了单例模式:它有一个类方面的字段instance和一个getter方法instanceB类是另一个有自己的instance字段的对象。 因此, A instanceB instance将返回不同的对象。

从面向对象的angular度来看,这显然是Smalltalk和Java之间的主要区别之一。

其他的不同之处还包括元类的存在,扩展方法,鸭子打字与静态打字, doesNotUnderstand具体化以及其他一些使Smalltalk或Java完全不同的编码的东西。

当然,Smalltalk已经closures了,Java仍然缺less。

另请参见Java为什么不允许重写静态方法?

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

试图通过探索Smalltalk来拓展自己的视野

如果您正在积极尝试探索Smalltalk,那么您需要知道如何阅读Smalltalk –

“我可以读取C + +和Java,但我不能读取Smalltalk”pdf

在Smalltalk中,一切都是对象,而在Java中,像小整数这样的东西仍然不是第一类对象。 另外,为了继续使用数字,Smalltalk由于其纯粹的OO特性和强大的reflection能力,我们从不需要关心数字的大小,就像整数大小一样,当小整数溢出时会发生什么。

Java中不存在的一个Smalltalk概念是近年来越来越stream行的一个概念。 块是一种匿名函数的forms,包括它们被定义的上下文。重要的是,块也是对象。 Smalltalk实际上缺less任何types的内置if语句或for -loop或类似的东西,但是只是通过消息传递和块来设法产生相同的效果。

 object isBig ifTrue: [self runIntoObject:object] ifFalse: [self katamariBall absorbObject:object]. 1 to: 10 do: [:number | number print] 

当@JankoMivšek表示一切,他真的是一切。 🙂

即使是发送消息,你正在做的是创build一个上下文的对象。

另外,你在Smalltalk中没有的是访问修饰符(private / protected / public)。你在一些Smalltalk实现中没有包,而且在大多数Smalltalk实现包中没有与Java相同的语义。

在smalltalk中,如果尝试/抓住,你没有控制结构。很酷的事情是,你不需要它们,因为你有小块封锁。

在smalltalk中,你没有静态成员,而是你有对象的类(你可以发送消息到类,你也可以把类放入一个variables)。

在smalltalk你没有嵌套的类。