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

Jim*_*Jim 38 java oop programming-languages smalltalk

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

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

Fra*_*rar 40

消息传递

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循环: 1 to: 10 do: [:i | Transcript show: i asString]
  • 试着抓: [i := i / 0] ifError: ['oops!']
  • 尝试,终于: [i := i / 0] ensure: [stream close]

并注意所有那些[]- 具有干净语法的一流闭包.

  • `Smalltalk使用消息传递,而不是方法调用.我们可以说方法调用是非常有限的消息传递吗? (2认同)

Vij*_*hew 19

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

  • @Lukas:"把`#doesNotUnderstand:`抛开"可以改变一些事情.你不会说那样的话,并期望被认真对待 - 如果我们删除所有不同的东西,当然东西会变得相似.:P (3认同)

ewe*_*nli 18

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

Smalltalk中的一个类是一个对象.的最接近static方法和变量是那么类端的方法和变量,如提到的由Frank采煤机.

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

如果类A的继承B,如果你有ab它们的实例A,并B在Smalltalk中,b class从继承a class.在Java中不会出现这种情况,a getClass()b getClass()返回Class彼此无关的实例.

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

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

其他差异包括元类的存在,扩展方法,鸭子类型与静态类型,具体化doesNotUnderstand和少数其他使Smalltalk或Java编码完全不同的东西.

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

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


igo*_*ouy 12

试图通过探索Smalltalk来扩展他的视野

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

"我可以阅读C++和Java但我无法阅读Smalltalk"pdf


Chu*_*uck 8

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

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

1 to: 10 do: [:number | number print]
Run Code Online (Sandbox Code Playgroud)


Jan*_*šek 7

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


mat*_*thk 5

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

即使是消息发送,您正在做的是创建一个上下文的对象.

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

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

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

在smalltalk中,您没有嵌套类.

...

  • 没错,但这只是(优化)优化. (4认同)