Let's ask a few objects what class they are. Open a fresh workspace and evaluate the following expressions, displaying the results:
'This is a string'.
#(7 'abc' 6.15)
4 @ 5.
Okay, so we've seen that the objects above are classified as a String, an Array and a Point respectively. Now the interesting thing here is that the classes String, Array and Point are also objects too (remember everything is an object in Smalltalk). The fact that class objects have names that begin with an upper case letter should, perhaps, indicate to you that these objects are held in global variables. There are around 600 classes in the basic Dolphin image so there are this number of different types of object, all with different behaviours. Naturally, this number will grow as you program new classes for yourself.
Every object is associated with a particular class. In Smalltalk programs we say that every object is an "instance" of its class. This means that 'hello' is an instance of String and 4 @ 5 is an instance of Point.
Question: if a class describes the behaviour of its objects and yet a class is also an object, what describes the behaviour of a class? What is a class object an instance of? The answer is a metaclass. I'm afraid that metaclasses are beyond the level of our current discussion but they are intriguing. Indeed, many computer scientists would consider them to be one of the most intriguing aspects of Smalltalk but, for more information, you'll have to research this for yourself!
So what do class objects actually do and what do they contain?
One thing classes do is to describe the layout of data in their instances. Most objects have to hold information about their state and they do this using instance variables. We'll learn more about instance variables in a moment but for now, suffice it to say that it is the responsibility of a class object to define the number and names of these variables in its instances. You can find out what instance variables are required by an object by sending the message #allInstVarNames to its class. Try:
This answers an array of strings showing the instance variable names for all Point objects. As you might expect, a Point (which represents a point on a two dimensional Cartesian plane) has variable slots for its x and y co-ordinates.
Another thing that classes do is to hold onto pieces of Smalltalk code called methods that describe how instances respond to individual messages. You can query a class to determine what message selectors its instances will respond to. Try displaying the results of:
Point respondsTo: #<=.
(4 @ 5) respondsTo: #<=.
Once you know that a class supports a particular message then you can also ask to see the code for the method that implements the message. Let's take a look at the Smalltalk code that handles the comparison of two points:
(Point compiledMethodAt: #<=) getSource.
The important thing to note here is not so much the code itself, but the fact that Smalltalk objects can be so introspective. You can send them messages to do many things, including asking them to describe how they actually work. This is another important aspect of Smalltalk and is often called reflection since objects have the ability to reflect upon their own behaviour.