如何从头开始制作 Squeak class?

How to make a Squeak class from scratch?

我想在 Squeak 中编写一个简单的程序来计算几个点之间的距离,但我不想使用已经定义的 class 点。到目前为止,我有以下内容:

已自动生成 x 和 y 的 getter 和 setter 方法:

x ^ x

x: 一个对象 x := 一个对象。

我编写的距离方法如下:

distance:aPoint
    "comment stating purpose of message"

    |dx dy |
    dx:=aPoint x - x.
    dy:=aPoint y - y.
    ^ (dx*dx+dy*dy) sqrt.

现在我打开一个工作区并尝试打印出结果:

obj1:=PointS new.
obj1 x:3 y:4.
obj2:=PointS new.
obj2 x:5 y:6.
d:=obj1 distance obj2
UIManager default inform: 'Converted amount: ',d.

但我得到的结果如下:

我错过了什么?

尝试替换以下内容:

obj1 x:3 y:4.

有了这个:

obj1 x:3; y:4.

基本上,您正在发送消息 #x:y:,但您没有使用该名称的方法。相反,您有一个方法 #x: 和另一个方法 #y:,因此您需要对同一对象进行两次单独的调用(这是通过 cascade 运算符完成的( #;).

观看优先

在您的方法中 distance: aPoint 您正在计算毕达哥拉斯距离

(dx*dx + dy*dy) sqrt

虽然这个公式在通常的数学符号和大多数编程语言中都是正确的,但在 Smalltalk 中它会以不同的方式工作。事实上它会产生与

相同的结果
((dx*dx + dy)*dy) sqrt,

这不是你想要的。这样做的原因是在 Smalltalk 中 #*#+ 都是具有相同优先级的二元运算符。因此,你应该写

((dx*dx) + (dy*dy)) sqrt

相反,或等效地

(dx*dx + (dy*dy)) sqrt

因为你只需要确保 dy*dy#+ 的参数。

更优雅的实现方式是

(dx squared + dy squared) sqrt.

此外,如果您查看 Point class,您会发现 #r 极坐标方法,如果您编写

(dx @ dy) r.