将SmallInteger子类化以表示数字事物?

时间:2019-04-26 22:43:33

标签: smalltalk

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

1)子类化SmallInteger是对此建模的好主意吗?

在代码浏览器中尝试此操作时,我得到:

SmallInteger immediateSubclass: #CountryCode

2)与immediateSubclass:相比,我不知道subclass:是什么意思。

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

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

谢谢!

4 个答案:

答案 0 :(得分:3)

    在可能的情况下,通常优先选择
  1. 组成而不是子类。子类化一个核心类,例如 由于2,特别是SmallInteger并不是一个好主意(可能根本不起作用)

  2. 定义为immediateSubclass:的类是特殊情况下处理的子类 由VM。该值代替对象指针,而是直接存储在对象头中。我认为VM需要了解每种特定的 immediateSubclass:处理编码/解码/ JIT代码

  3. 您已经开始看到创建数字子类的问题。 (会有其他)您可以创建一个Object子类,并让它代理一个数值ivar,但是如果用#isKindOf:等对您的对象进行测试,那么靠数字本身就可能不足以令人信服。如果确实要这样做,则可能希望将您的类设为Integer的子类,并在其中包含数字ivar,然后执行所有常规操作来代理它。 (即创建性能和调试所需的所有方法,或实施#doesNotUnderstand:来将消息转发给它并承受不利影响)

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

答案 1 :(得分:2)

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

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

3)您不能创建立即对象,不能分配内存(新),也不能对其进行子类化。只有VM可以,是的,这始终是通过SmallInteger的算法实现的。

是的,合成可能正是您所需要的。 Country有一个小的整数Telefon代码(在一个实例变量中),也许还有其他功能(一个名称...)。

答案 2 :(得分:2)

将国家/地区代码封装在类TelephoneNumber中就足够了,不是吗?

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

因此,我将尝试封装,并继续使用直到被证明是错误的(应该很明显)。

答案 3 :(得分:0)

  1. 不,将国家/地区代码设为SmallInteger的子类不是一个好主意。
  2. 在这种情况下,我不知道“直接子类”是什么。让我们暂时忽略这一点。
  3. 假设您创建了TelephoneCountry作为Object的子类;并且您使用选择器#code:创建了一个类方法,该方法创建了一个新实例,将名为“ code”的实例变量设置为该参数的值,并返回了新实例。您可以将该msg发送到您的类中,以创建TelephoneCountry的实例,如下所示:

    国家/地区:=电话国家/地区代码:46。

    您稍后可能会询问该国家的名称或代码。

    n:=国家名称。 c:=国家/地区代码。

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