December 21, 2024
Frogs and Toads
M206 develops the course material in a very gradual way. Students are
introduced to a small part of object technology and then, after building
upon that snippet, you are gradually introduced to something new.
Block I introduces the Frog, Toad
and HoverFrog classes. The inheritance hierarchy
looks like this:
Object
Frog
HoverFrog
Toad
Object is the superclass of all other classes
in the Smalltalk system. Object is the most
abstract of all classes, it has no attributes. By abstract I mean generalised,
without attention to detail, it is utterly non-specific. You can create
Object instances but it won't do you much good.
But any other class in the Smalltalk system will inherit all of Object's
protocol, meaning all of its message selectors. Software development involves
creating software that models some aspect of the real world with software
components (objects). This process employs pre-existing classes or, if
required, new ones are created. Classes are used to manufacture objects
according to some pre-determined template. Compared to Object
all classes are more specific but some are more specific than others.
M206 uses amphibians to show that having settled on some fairly arbitrary
behaviour, namely that all these beasts have a property of position
and colour, we can go about modelling them with
objects and that these objects will respond to certain messages but not
to others. Therefore we look at behaviour first when developing software.
We don't have to consider how this behaviour is implemented (coded). We
only need to know that if the correct message is sent to an object it
will behave in the required manner. The responsiblity for carrying out
the required behaviour is undertaken by the receiver of the message. It
may well be the case that part of this behaviour is the need to send messages,
either to other objects, or itself. In this way objects collaborate to
perform some required task.
For teaching purposes it was decided to make Frog and Toad different. They have the same attributes of position and colour. We can see that they some similarity of protocol, the same message selectors. But there is a difference, since newly created instances of these two classes have different values for the same attributes. Furthermore, there is a message(s) that instances of Frog understand and instances of Toad do not. The behaviour of Toad and Frog objects differs.
Toad and Frog have
inherited all the abstract protocol from Object,
but they need to be far more specific to do the job of modelling the rather
contrived behaviour of frogs and toads. Furthermore, apart from instances
of Frog having a slightly different protocol,
objects of the Frog class behave differently
on receipt of some messages than would a Toad
instance. If I send the right message to a Frog
instance I can observe in the GUI that it moves one stone to the right.
A Toad instance will move two stones to the
right. So that's a visual clue to the fact that the implementation, within
Frog and Toad class,
of the right message varies (see below for reasons
why you should not always trust your eyes!). This is a good example of
polymorphism, the same message being sent to objects of different classes,
each class having a different implementation of that message.
Smalltalk always determines the receiver of a message first. Once the
system has done this it determines the class of that object. It then says
to itself, OK I have an instance of Frog, say,
that has received a right message and now I
need to use the implementation of the right
message for this particular class. So it executes the correct piece of
code, and not the code for the right message
of the Toad class.
Toad is not a subclass of Frog
because the course team decided to make these two classes have different
behaviour. Furthermore, in order to show the power of subclassing they
created a subclass of Frog. HoverFrog
is like Frog but it creates objects that have
some additional behaviour. These beasts were required to hover and so
needed another attribute called height. To implement
this behaviour it was necessary to extend the protocol inherited from
both Frog and Object.
Consequently HoverFrog has some extra message
selectors in its protocol.
At some later stage in the course you will be introduced to the concept
of factoring out common behaviour in order to be more efficient. You will
be invited to think about the fact that the current hierarchy could be
improved. You will need to decide what messages could be held in an abstract
class and then inherited by Frog, HoverFrog
and Toad. That way we can write quite a lot
of code in this superclass and all the subclasses will inherit. This saves
time and effort and reduces the chance of error. This is REUSE
in action.
This new hierarchy would look like this
Object
Amphibian
Frog
HoverFrog
Toad
Note that Toad still isn't a subclass of Frog but it is a subclass of Amphibian, as is Frog. HoverFrog is still a subclass of Frog and also inherits, indirectly, the protocol (and attributes) of Amphibian. All of these classes, directly or indirectly, inherit from Object.
Students often ask about initialising and the fact that instances of subclasses can be initialised differently from instances of the superclass. Initialising refers to the values of an object's attributes that are set at the moment of its creation. So what happens here?
When an instance of Frog, Toad or HoverFrog is created, it receives a message called initialize (in Block I this is hidden from you). Again this is polymorphism, because it is possible to write different implementations (code) of this in order to model the behaviour required for a particular class. A subclass may indeed be initialised differently for a specific reason, namely that the real world (problem domain) requires it. The course team could have decided that a hoverfrog was required to sit on the second stone instead of the first when it is instantiated (created). In order to simplify things in the early stages of M206 they decided against it.
Another regular cause of confusion is the jump message. You may ask how is HoverFrog a subclass of Frog when the jump message appears to produce different behaviour in an instance of these two classes?
The jump selector is in the protocol of Frog
and is therefore inherited by HoverFrog. To
understand jump you need to understand the concept
of a change of state in an object. A change of state can be determined
by asking yourself, 'has the value of an object's attributes been changed
on receipt of a message?' I think confusion stems from relying too much
on the GUI to inform your judgement. You need to use the inspector tool.
If you have a Frog instance and a HoverFrog
instance in the GUI (LB-06 is an example) and you send a jump
message to the Frog instance, it will appear
to move up and down in the GUI. Opening the inspector tool should prove
something to you. What? Now send a message to the Hoverfrog
object which changes its height. Open the inspector
and note the value of its height attribute.
Now send it a jump message. The GUI shows no
movement and that leads you to believe that it's behaviour on receipt
jump is different to that of the frog. But again
you need to use the inspector tool to prove or disprove this assertion.
This should tell you something about the jump
message. What? There are other message selectors in the protocol of HoverFrog
that will at some point have no effect on the state of a HoverFrog
instance. Again, using the inspector tool, you can determine that the
behaviour of the object in receipt of these messages is dependent on the
state of that object at the time the object receives the message. What
are these messages?
I am deliberately leaving you to work these out because they usually have
a bearing on TMA01.
Personally I think that the GUI confuses students when they use the jump message. But it does reinforce the fact that the domain model, the world of objects and messages, is quite separate from the GUI. A Graphical User Interface allows humans to pass messages to objects in the domain model and receive information held within the domain model. You can't trust your eyes to give you the real picture of the domain model, you need to use the inspector tool or send the object an inspect message (which is what the tool does).
These amphibian classes are extremely contrived and they could have been implemented differently. They were developed to teach key OO concepts such as inheritance, polymorphism and message sending. It could be argued that the Course Team should have developed a more realistic real world example. I'm not sure what the amphibian equivalent of misanthrope is (herpethrope?), but if you teach M206 for long enough you start to suffer from it.
⇑ Up to top of page