Smalltalk和Java中的OO有哪些主要区别?

时间:2010-06-23 14:47:14

标签: java oop programming-languages smalltalk

Smalltalk和Java中的OO有哪些主要区别?

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

7 个答案:

答案 0 :(得分:39)

消息传递

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

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

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

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

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

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

琐碎的语法

不,我不是在开玩笑。 Smalltalk的整个语法可能长达15行。 JLS是......不是。为何关心?一个简单的语法使得分解大量代码变得简单。元编程!重构!

没有语法:

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

注意所有那些[] s - 具有干净语法的第一类闭包。

答案 1 :(得分:19)

  1. 对象模型。在Smalltalk的每一件事,都是一个对象。 Java具有基本类型,如int和float,其表示和行为与复杂对象不同。
  2. 行为调用。通过向其发送消息来调用Smalltalk对象的行为。 Java有一些方法,它们基本上是函数调用,目标对象是一个名为this的特殊第一个参数。
  3. 封装。 Smalltalk具有严格的封装。对象的字段只能通过消息公开。相比之下,Java允许使用公共字段。
  4. 动态。 Smalltalk非常动态。所有类型都在运行时标识。可以在运行时对类进行内省和修改(动态元编程!)。可以在运行时创建和实例化新类。 Java具有静态类型检查以及运行时多态性。有内省和反思,但不能在正在运行的程序中修改类和对象。
  5. 语法。 Smalltalk没有语法。相反,它具有简单,一致的发送消息格式。与C系列的其他语言一样,Java具有复杂的语法。
  6. 环境。大多数Smalltalk实施提供了一个完整,独立的实时计算环境image based persistence。其中一些环境can even be booted on bare metal。反过来,JVM通常依赖于底层操作系统进行线程,网络等。源代码必须输入到文本文件中,编译并显式加载到JVM中以便执行。

答案 2 :(得分:18)

Java和Smalltalk之间的一个关键区别是Smalltalk拥有一流的类(没有双关语)。

Smalltalk中的一个类是一个对象。与static方法和变量最接近的是类方法和变量,如Frank Shearer的mentioned

但是一旦使用继承,这种差异就会更加深刻。在java类中,继承不存在,而在Smalltalk中则有可能。

如果班级A继承自B,并且ab属于AB的实例,则Smalltalk,b class继承自a class。在a getClass()b getClass()返回Class的实例的情况下,情况并非如此,这些实例彼此无关。

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

从OO的角度来看,这显然是Smalltalk与Java之间的主要区别之一。

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

当然,Smalltalk已经关闭了Java仍然缺乏。

另见Why doesn’t Java allow overriding of static methods ?

答案 3 :(得分:12)

  

试图扩大他的视野   探索Smalltalk

如果您主动尝试探索Smalltalk,那么您需要知道如何阅读Smalltalk -

"I Can Read C++ and Java But I Can’t Read Smalltalk" pdf

答案 4 :(得分:8)

Java中不存在但近年来越来越受欢迎的一个Smalltalk概念是块。块是匿名函数的一种形式,包括它们所定义的上下文。重要的是,块也是对象。 Smalltalk实际上缺少任何类型的内置if - 语句或for - 循环或类似的东西,但设法创建与消息传递和阻止相同的效果。

object isBig ifTrue: [self runIntoObject:object] 
            ifFalse: [self katamariBall absorbObject:object].

1 to: 10 do: [:number | number print]

答案 5 :(得分:7)

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

答案 6 :(得分:5)

当@JankoMivšek意味着一切时,他真正意味着一切。 :)

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

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

在smalltalk中你没有像if,try,try这样的控制结构......很酷的事情就是你不需要它们,因为你在smalltalk中有块闭包。

在smalltalk中你没有静态成员而是你有Class作为对象(你可以向类发送消息,你也可以在变量中保存类)。

在smalltalk中,你没有嵌套类。

...