alesch
alesch

Reputation: 842

Subclassing SmallInteger for representing numerical things?

I want to represent a telefon country code (like 46 for Sweden or 54 for Argentina). This is a small positive integer number.

1) Is subclassing SmallInteger a good idea for modelling this?

When trying this in the code browser I get:

SmallInteger immediateSubclass: #CountryCode

2) I don't know what immediateSubclass: means, in contrast to subclass:.

3) How can I create an instance of my CountryCode? as SmallIntegers can only be created by arithmetic?

I'm aware I could use encapsulation and just have a SmallInteger inside my own CountryCode class.

Thank you!

Upvotes: 3

Views: 151

Answers (4)

Jim Sawyer
Jim Sawyer

Reputation: 143

  1. No, it is not a good idea to make country code a subclass of SmallInteger.
  2. I don’t know what ‘ immediate subclass ‘ is about in this situation. Let’s ignore that bit for now.
  3. Let’s imagine you had created your TelephoneCountry as a subclass of Object; and you created a class method with the selector #code: that creates a new instance, sets the instance variable named ‘code’ to the value of the parameter, and returns the new instance. You would send that msg to your class in order to create an instance of TelephoneCountry, like this:

    country := TelephoneCountry code: 46.

    You might later ask that country for its name, or for its code.

    n := country name. c := country code.

Of course, you’ll need to write each of those methods too.

Upvotes: 0

Leandro Caniglia
Leandro Caniglia

Reputation: 14858

Encapsulating the country code in, say, the class TelephoneNumber should suffice, shouldn't it?

I guess that you may need the mapping between countries and codes and also some facility to parse and validate a telephone number string. What I don't see is the need to model the code in its own class.

Hence, I would give encapsulation a try, and stay with it until proven wrong (which should become apparent).

Upvotes: 2

blihp
blihp

Reputation: 675

  1. Composition is generally preferred over subclassing when possible. Subclassing a core class like SmallInteger in particular is not a good idea (and may not work at all) because of 2

  2. Classes defined as immediateSubclass: are special case subclasses handled by the VM. Instead of an object pointer, the value is stored directly in the object header. I believe the VM needs to be aware of each particular kind of an immediateSubclass: to handle encoding/decoding/JIT code generation.

  3. You're already starting to see the problem with creating a numeric subclass. (there will be others) You can create an Object subclass and have it proxy a numeric ivar but that will likely not be good enough on it's own to be fully convincing as a number should your object be tested with #isKindOf: etc. If you really want to do this, you will probably want to make your class a subclass of Integer with your numeric ivar inside and then do all the normal things you would do to proxy it. (i.e. either create all the needed methods for performance and debugging or implement #doesNotUnderstand: to forward messages to it and live with the downsides)

That said, ask yourself why you really need to do this for a country code? Yes it's a number, but are you really going to be doing numeric things with it (adding two country codes together, country code * 10, what does the square root of a country code even mean etc.) that you need to specialize or is the code just a numeric value with no special behavior? I would suspect that a better solution would be to create a Country or CountryCode class as a subclass of Object or some other top level model class. Then you can add an ivar for the country code (which will most likely be a SmallInteger), another for the country name etc. and add an #asInteger or #asNumber method to it if needed.

Upvotes: 3

aka.nice
aka.nice

Reputation: 9382

1) what is the benefit of inheriting from integer? Perform arithmetic on country code? Does a country code requires a class at all? For which behavior?

2) immediate subclass is an implementation detail. Normal object are pointers (object oriented pointers). Immediate objects contains the data instead of a pointer. They are recognized by virtual machine by having low bits non zero. A normal address is aligned on 4 8 or 16 bytes and have low bits set to zero.

3) You cannot create immediate object, you can't allocate memory (new), and you can't subclass them either. Only the VM can, and yes this is always via arithmetic for SmallInteger.

So yes, composition is probably what you need. Country has a small integer telefon code (in an instance variable) and also maybe other features (a name...).

Upvotes: 2

Related Questions