0704.315 Programming Languages
Homework 4
Due Date
- Both Sections: Tuesday, November 13
Form of Submission
Homework can be submitted via email or printout by deadline.
Printouts of class definitions and workspace transcripts should be included.
Preparation
- Read Smalltalk in Brief, Sections 3.1 and 3.2
Assignment
The goal of this assignment is to build a concrete subclass of an
(built-in) abstract class Magnitude. The new subclass,
Rank, will implement orderings over military ranks.
- Launch Squeak!,
bring up a browser (left-click->open...->browser),
and find the class Magnitude in the category
Kernel-Magnitudes.
- Look at each of the methods (click on their names in the 4th
pane, and look at their definitions in the main pane) and notice that
only the methods <, =, and hash
lack implementations. We won't be worrying about hash in
this exercise.
- Create a new category for your new subclass:
-
Move your mouse into the Category (first) pane, right-click and select
add item....
- Enter a new (arbitrary) category name and
hit Accept.
- Create a new class in this category:
-
In the main pane should be a template for defining a new class.
Double-click on NameOfSubclass and change it to
Rank.
-
By default, the superclass of the new class is Object (the
root class). Change it to Magnitude.
- The red outline around the pane means that there are changes
that haven't yet been saved. To commit the class definition to the
system (we'll still be able to make changes to it later), right-click
and select accept. You can commit your changes
as often as you want. If there is a syntax or other error,
Squeak! will attempt to help you fix them before committing
the change.
- You can print out the entire description of a class to a file by
selecting a class, right-clicking and selecting the
fileOut menu item. The description will be
written out into a file named
<classname>.st in your Squeak! directory.
- Go back to the definition of Rank and add the instance
variable myRank to it.
- Add two new instance methods: rank (returns current rank)
and setRank: (to set a new rank). setRank:
takes one argument, and should return the new rank, like so:
r := Rank new .
r setRank: 'Private' .
r rank
"outputs 'Private'"
Test your methods in your Workspace window.
- Currently, there is no limitation on the ranks a Rank
can have (or more precisely, what the myRank instance
variable can be set to). Modify setRank: to only
allow myRank to be set to one of the following set of
possible ranks (simplified):
- Private
- Corporal
- Sergeant
- Lieutenant
- Captain
- Major
- Colonel
- General
As a hint, you might find it useful to put all the possible ranks (as
strings) into an array.
Test your updated method in your Workspace window.
- Since the set of possible ranks never changes and would be
useful in the implementation of multiple methods, it would be a
better design to put them into a class variable, where
it can be accessible by all Rank instances and their methods.
- In the Browser, return to the class definition and add
AllRanks as a class variable
- Define the class method initialize over the
class. To introduce a class method, click on the
class button on the 2nd pane and on no
message in the 3rd pane. A template for the method
should appear in the main pane.
Once defined, you can invoke the class method by entering
Rank initialize and selecting do it
off of the menu.
- Now we have enough pieces in place to define implementations for
the two methods that we have to override:
= and <. Do so.
Test your methods in your Workspace window.
- Now that we've defined = and <, the
other comparison methods defined over Magnitudes, such
as >, <=, and max, should now
work over Rank instances. Verify this in your
Workspace window.
- Add a new method promote, which "increments" the rank.
Make sure it handles the case when the rank is already 'General'.
Test your updated method in your Workspace window.
- Save your Workspace and class definition to files, edit to taste,
and submit.