对SmallInteger进行子类化以表示数字事物?

问题描述 投票:3回答:4

我想代表一个电话国家代码(如瑞典为46或阿根廷为54)。这是一个小的正整数。

1)对SmallInteger进行子类化是一个很好的建模吗?

在代码浏览器中尝试这个时,我得到:

SmallInteger immediateSubclass: #CountryCode

2)与immediateSubclass:相比,我不知道subclass:的含义。

3)如何创建CountryCode的实例?因为SmallIntegers只能通过算术创建?

我知道我可以使用封装,只在我自己的SmallInteger类中有一个CountryCode

谢谢!

smalltalk
4个回答
3
投票
  1. 在可能的情况下,组合物通常优于亚类化。特别是对SmallInteger这样的核心类进行子类化并不是一个好主意(并且可能根本不起作用)因为2
  2. 定义为immediateSubclass:的类是VM处理的特殊情况子类。该值直接存储在对象头中,而不是对象指针。我相信VM需要知道每种特定类型的immediateSubclass:来处理编码/解码/ JIT代码生成。
  3. 您已经开始看到创建数字子类的问题。 (还有其他人)你可以创建一个Object子类并让它代理一个数字ivar,但如果你的对象需要用#isKindOf:等进行测试,那么它本身可能就不足以完全令人信服了。如果你真的想要要做到这一点,你可能想让你的类成为Integer的子类,里面有你的数字ivar,然后做你要做的所有正常事情来代理它。 (即要么创建所有需要的性能和调试方法,要么实现#doesNotUnderstand:将消息转发给它并与缺点一起生活)

也就是说,问问自己为什么你真的需要为国家代码做这个?是的,它是一个数字,但是你真的会用它来做数字的事情(加上两个国家代码,国家代码* 10,国家代码的平方根甚至意味着什么等等)你需要专门化或是代码只是一个没有特殊行为的数值?我怀疑更好的解决方案是创建一个Country或CountryCode类作为Object或其他顶级模型类的子类。然后你可以为国家代码(很可能是一个SmallInteger)添加一个ivar,为国家名称等添加另一个ivar,并在需要时添加一个#asInteger#asNumber方法。


2
投票

1)从整数继承有什么好处?对国家代码执行算术运算?国家代码是否需要课程?对于哪种行为?

2)immediate子类是一个实现细节。普通对象是指针(面向对象的指针)。立即对象包含数据而不是指针。虚拟机通过使低位非零来识别它们。普通地址在4 8或16字节上对齐,低位设置为零。

3)你不能创建直接对象,你不能分配内存(新),也不能将它们子类化。只有VM可以,是的,这总是通过SmallInteger的算术运算。

所以是的,组合可能就是你所需要的。 Country有一个小整数telefon代码(在一个实例变量中),也可能有其他功能(名称......)。


2
投票

将国家代码封装在比如TelephoneNumber这个类应该就足够了,不应该吗?

我想你可能需要国家和代码之间的映射,还有一些解析和验证电话号码字符串的工具。我没有看到需要在自己的类中建模代码。

因此,我会尝试封装,并坚持下去,直到证明错误(这应该变得明显)。


0
投票
  1. 不,将国家/地区代码作为SmallInteger的子类并不是一个好主意。
  2. 在这种情况下,我不知道'直接的子类'是什么。我们暂时忽略这一点。
  3. 让我们假设您已经将您的TelephoneCountry创建为Object的子类;并且您使用选择器#code创建了一个类方法:它创建一个新实例,将名为'code'的实例变量设置为参数的值,并返回新实例。您可以将该msg发送到您的班级,以便创建一个TelephoneCountry实例,如下所示: country:= TelephoneCountry代码:46。 您可能稍后会询问该国家/地区的名称或代码。 n:=国家/地区名称。 c:=国家代码。

当然,您也需要编写每种方法。


推荐问答