Reputation: 842
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
Reputation: 143
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
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
Reputation: 675
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
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.
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
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