如何让一个类使用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的机会,而width asString在Smalltalk中起着核心作用。

请注意,在我的实现中,我使用了heigh asStringString。您的代码尝试将NumberString连接(两次):

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


这将不起作用,因为您只能将#,的实例与#asString并置。

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

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


有点儿冗长,因此是首选。

最后一件事。我建议使用此命令更改上面的第一行:

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


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

最后的想法:我将选择器#description重命名为as。介词#asString用于将一个对象转换为另一个不同类的对象(这就是为什么#asString可以的原因)。但这似乎并非如此。

附录:为什么?

为什么要使用#printOn:而不是相反地实现#printOn:是有原因的:通用性。尽管工作量(代码复杂度)相同,但是Stream显然是赢家,因为它可以与任何字符FileStream一起使用。特别是,它将在不进行任何修改的情况下工作


文件(SocketStream的实例)
套接字(Transcript的实例)
#printOn:


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

记得!

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

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

10-11 02:55