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

发布于 2024-09-06 21:41:55 字数 203 浏览 8 评论 0原文

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

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

What are the key differences between OO in Smalltalk and Java?

Please note that I am a Java programmer trying to expand his horizons by exploring Smalltalk. Currently I know almost nothing about Smalltalk except that it's purer than Java. Therefore I'll prefer the answer that shows how various Java concepts map to corresponding Smalltalk concepts and then introduces the Smalltalk concepts that don't exist in Java at all.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

可爱暴击 2024-09-13 21:41:55

消息传递

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

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

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

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

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

例如,您可以让一个对象响应某些消息集,同时将其收到的任何其他消息转发到某个委托对象。覆盖#doesNotUnderstand: 嘿,很快,您就拥有了一个无需维护即可保持其协议与委托同步的代理。

简单的语法

不,我不是在开玩笑。 Smalltalk 的整个语法可能有 15 行长。 JLS 是……不是。为什么要关心?简单的语法使得分解一段代码变得很容易。元编程!重构!

无语法 for:

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

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

Message passing

Smalltalk uses message passing, not method invocation. The distinction is subtle, but enormously powerful.

Some terminology: Given foo bar: baz, #bar: is a selector, foo is the receiver of a message called #bar: (the # indicates a symbol, much like Common Lisp would say 'bar (or even more appropriately, :bar)), and baz is an argument or parameter. When the line's executed, foo is sent the message #:bar: with argument baz. So far, it's pretty normal. In Java it would look like foo.bar(baz);.

In Java, the runtime system would figure out foo's actual type, find the most appropriate method, and run it.

Things look almost the same in Smalltalk. When you send an object a message, it searches in its method dictionary for a method whose name matches that of the selector of the message. If it can't find one, it searches in its superclass' method dictionary, and so on. Pretty normal stuff.

If it can't find any matching method, it sends itself the #doesNotUnderstand: message, with the original message as a parameter. (Yes, a message send is an object.) But #doesNotUnderstand: is also just a method. You can override it.

For instance, you can have an object that responds to some set of messages while forwarding any other messages it receives to some delegate object. Override #doesNotUnderstand: and hey presto, you have a proxy that will need no maintenance to keep its protocol in sync with the delegate.

Trivial syntax

No, I'm not joking. Smalltalk's entire grammar's maybe 15 lines long. The JLS is... not. Why care? A simple syntax makes it simple to tear a chunk of code apart. Metaprogramming! Refactoring!

No syntax for:

  • conditional statements: (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]

And notice all those []s - first-class closures with a clean syntax.

野生奥特曼 2024-09-13 21:41:55
  1. 对象模型。在 Smalltalk 中,一切都是对象。 Java 具有 int 和 float 等基本类型,其表示和行为与复杂对象不同。
  2. 行为调用。 Smalltalk 对象的行为是通过向其发送消息来调用的。 Java 具有方法,这些方法基本上是函数调用,目标对象是一个名为 this 的特殊第一个参数。
  3. 封装。 Smalltalk有严格的封装。对象的字段只能通过消息公开。相比之下,Java 允许公共字段。
  4. 动态。 Smalltalk 非常动态。所有类型均在运行时识别。类可以在运行时进行自省和修改(动态元编程!)。可以在运行时创建并实例化新类。 Java 具有静态类型检查和运行时多态性。有内省和反射,但不能在正在运行的程序中修改类和对象。
  5. 语法。 Smalltalk 没有语法。相反,它具有简单、一致的消息发送格式。 Java 与 C 家族的其他语言一样,具有复杂的语法。
  6. 环境。大多数 Smalltalk 实现提供了一个完整、独立、实时的计算环境,其中包含 基于图像的持久性。其中一些环境甚至可以在裸机上启动。 JVM 通常又依赖于底层操作系统来实现线程、网络等。源代码必须输入文本文件、编译并显式加载到 JVM 中以供执行。
  1. Object Model. In Smalltalk every thing, is an object. Java has primitive types like int and float whose representation and behavior are different from complex objects.
  2. Behavior invocation. Behavior of a Smalltalk object is invoked by sending it a message. Java has methods, which are basically function calls, with the destination object being a special first argument called this.
  3. Encapsulation. Smalltalk has strict encapsulation. An object's fields can be exposed only through messages. In contrast, Java allows public fields.
  4. Dynamism. Smalltalk is extremely dynamic. All types are identified at runtime. A class can be introspected and modified at runtime (dynamic meta-programming!). New classes can be created and instantiated at runtime. Java has static type checking along with runtime polymorphism. There is introspection and reflection, but classes and objects cannot be modified from within a running program.
  5. Syntax. Smalltalk do not have a syntax. Instead it has a simple, consistent format for sending messages. Java, like other languages of the C family, has a complex syntax.
  6. Environment. Most Smalltalk implementations provide a complete, standalone, live computing environment with image based persistence. Some of these environments can even be booted on bare metal. The JVM in turn is usually dependent on an underlying operating system for threading, networking etc. Source code must be entered into text files, compiled and explicitly loaded into the JVM for execution.
风吹过旳痕迹 2024-09-13 21:41:55

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

Smalltalk 中的类是一个对象。与 static 方法和变量最接近的是类端方法和变量,如 弗兰克·希勒 (Frank Shearer) 提及

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

如果类 A 继承自 B,并且如果您有 ab ,它们是 A 的实例B,在Smalltalk中,b类继承自a类。在 Java 中,情况并非如此,其中 a getClass()b getClass() 返回 Class 的实例,它们与每个实例无关其他。

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

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

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

当然,Smalltalk 具有 Java 所缺乏的封闭性。

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

A key difference between Java and Smalltalk is that Smalltalk has first-class class (no pun intended).

A class in Smalltalk is an object. The closest thing to static method and variable is then class-side method and variable, as mentioned by Frank Shearer.

But this difference is more profound as soon as inheritance is used. In java class-side inheritance does not exists, while it is possible in Smalltalk.

If class A inherits from B, and if you have a and b which are instances of A and B, in Smalltalk, b class inherits from a class. This would not be the case in Java where a getClass() and b getClass() return instances of Class, which are not related with each other.

Let's say now that class A implements the singleton pattern: it has a class-side field instance and an getter method instance. Class B is another object with its own instance field. As a consequence, A instance and B instance will return different object.

This is clearly one of the major difference between Smalltalk and Java from a OO standpoint.

Other difference include the existence of metaclasses, extension methods, duck typing vs static typing, reification of doesNotUnderstand and few other things that make coding in Smalltalk or Java completely different.

And of course, Smalltalk has closure which Java still lacks.

See also Why doesn’t Java allow overriding of static methods ?

心房敞 2024-09-13 21:41:55

尝试通过以下方式拓展自己的视野
探索 Smalltalk

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

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

trying to expand his horizons by
exploring Smalltalk

If you are actively trying to explore Smalltalk then you need to know how to read Smalltalk -

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

叹倦 2024-09-13 21:41:55

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

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

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

One Smalltalk concept that doesn't exist in Java but has become increasingly popular in recent years is blocks. Blocks are a form of anonymous functions that include the context they were defined in. Importantly, blocks are also objects. Smalltalk actually lacked any kind of built-in if-statement or for-loop or anything like that, but managed to create the same effect just with message-passing and blocks.

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

1 to: 10 do: [:number | number print]
玩心态 2024-09-13 21:41:55

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

In Smalltalk everything is the object while in Java things like small integers are still not the first class objects. Also, to continue with numbers, in Smalltalk due to its pure OO nature and strong reflective capabilities we never need to care about the number size, like if an integer is small or large and what happens when small integer overflows to large.

游魂 2024-09-13 21:41:55

当@Janko Mivšek 意味着一切时,他真的意味着一切。 :)

即使在消息发送之前,您所做的也是创建一个作为上下文的对象。

另外,smalltalk 中没有访问修饰符(私有/受保护/公共)
在某些 Smalltalk 实现中没有包,并且在大多数 Smalltalk 实现中包不具有与 Java 相同的语义。

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

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

在smalltalk中,你没有嵌套类。

...

When @Janko Mivšek mean everything he really mean everything. :)

Even up to message send, what your are doing is creating an object that is the context.

Also what you don't have in smalltalk is access modifier (private/ protected / public)
You don't have package in some Smalltalk implementation and in most Smalltalk implementation package don't have the same semantic than Java.

In smalltalk you don't have control structure like for, if, try/catch... The cool things is that you don't need them because you have block closure in smalltalk.

In smalltalk you don't have static member instead you have Class that are object(you can send message to class, you also can hold class in a variable).

In smalltalk you don't have nested class.

...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文