smalltalk - 如何在 GNU Smalltalk 中添加具有 2 个不同名称的相同方法?

标签 smalltalk gnu-smalltalk

如何让一个类公开具有 2 个不同名称的相同方法?

例如asDescripton 函数执行相同的操作/重新导出 asString 函数,而无需简单地复制粘贴代码。

Object subclass: Element [
  | width height |

  Element class >> new [
    ^super new init.
  ]

  init [
    width := 0.
    height := 0.
  ]

  asString [
    ^ 'Element with width ', width, ' and height ', height.
  ]

  asDescription [ "???" ]
]

最佳答案

在 Smalltalk 中,您通常实现 #printOn: 并从其继承版本中获取 #asString,其内容如下

Object >> asString
  | stream |
  stream := '' writeStream.
  self printOn: stream.
  ^stream contents

此方法的实际实现可能在您的环境中略有不同,但想法保持不变。

鉴于此,实现 #printOn: 而不是 #asString 通常是一个好主意。在您的情况下,您会将其实现为

Element >> printOn: aStream
  aStream
    nextPutAll: 'Element with width ';
    nextPutAll: width asString;
    nextPutAll: ' and height ';
    nextPutAll: height asString

然后,正如 JayK 和 luker 所指出的,

Element >> asDescription
  ^self asString

换句话说,您(通常)不想实现#asString,而是实现#printOn:。这种方法更好,因为它利用继承并确保 #printOn:#asString 之间的一致性,这通常是预期的。此外,它还将让您有机会开始熟悉 Streams,它在 Smalltalk 中发挥着核心作用。

顺便请注意,在我的实现中,我使用了 width asStringheigh asString。您的代码尝试将 StringNumber 连接(两次):

'Element with width ', width, ' and height ', height.

这不起作用,因为您只能将 String 实例与 #, 连接起来。

但是,在大多数方言中,您可以使用 #print: 而不是 #nextPutAll: 来避免发送 #asString,例如像:

Element >> printOn: aStream
  aStream
    nextPutAll: 'Element with width ';
    print: width;
    nextPutAll: ' and height ';
    print: height

这有点不那么冗长,因此是首选。

最后一件事。我建议将上面的第一行更改为:

    nextPutAll: self class name;
    nextPutAll: ' with width ';

而不是硬编码类名。如果将来您对 Element 进行子类化,这将被证明是有用的,因为您无需调整 #printOn: 及其任何派生项(例如 # asDescription)。

最终想法:我会将选择器 #asDescription 重命名为 #description。介词 as 旨在将一个对象转换为另一个不同类的对象(这就是为什么 #asString 可以)。但这里的情况似乎并非如此。

附录:为什么?

#asString 是按照 #printOn: 实现的,而不是相反:一般性。虽然工作量(代码复杂性)相同,但 #printOn: 显然是赢家,因为它可以与任何字符Stream配合使用。特别是,它无需任何修改即可使用

  1. 文件(FileStream 的实例)
  2. 套接字(SocketStream 的实例)
  3. 成绩单

换句话说,通过实现#printOn:,人们可以免费获得#asString(继承),并且同时能够转储表示形式文件和套接字上的对象的。 Transcript 特别有趣,因为它支持 Stream 写入协议(protocol),因此可以在向外部设备发送任何字节之前用于测试目的。

记住!

在 Smalltalk 中,目标是让对象的行为既简单又通用不仅仅是简单!

关于smalltalk - 如何在 GNU Smalltalk 中添加具有 2 个不同名称的相同方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55322402/

相关文章:

inheritance - Smalltalk:检查方法是否属于类(或其继承层次结构)

smalltalk - Python是否是GNU Smalltalk的__name __ = ="__main__"惯用语?

Smalltalk 变量 : why should I declare them?

smalltalk - 如何卸载 Pharo Glamorous Toolkit?

optimization - 在 Smalltalk 中使用其他集合选择对象的最快方法

smalltalk - Pharo Smalltalk 中有没有特定的方法来获取计算机的 Ip?

exception-handling - Visualworks Cincom Smalltalk SUnit 错误条件测试用例

smalltalk - 在 Smalltalk 中返回消息