Magnitude is the abstract superclass of everything that can be compared. Most of the standard Smalltalk classes that are magnitudes are numbers, but most of the subclasses of Magnitude that you are likely to make, such as loudness, brightness, and grades, are not numbers. How can you make a new kind of magnitude?
The purpose of this exercise is to learn how to make a concrete subclass of an abstract class like Magnitude. The goal is to make a class to represented military ranks. Military ranks can be compared with each other, so they are magnitudes, but they are not numbers.
The simplest kind of magnitudes only have to define one method, and all the other comparison methods are derived automatically from it. (What is this method? If you didn't know from the notes, how would you find out?)
Each MilitaryRank has a name. You can use the names to decide which is the highest rank. Suppose you had a literal array #( 'private' 'corporal' 'sergeant' 'second liutenant' 'first liutenant' 'captain' 'major' 'liutenant colonel' 'colonel' 'general' ) called ranks. This is much too rough to be useful, but it gets the idea across. Then you could find out whether one rank came before another by
(ranks indexOf: rank1 name) < (ranks indexOf: rank2 name)
Give MilitaryRank a method that returns that array. Then you should be able to easily define the < method for ranks.
You have to be able to create a new object. Create class and instance methods so that you can say
MilitaryRank named: 'private'and get the right kind of instance. Write methods so you could say
MilitaryRank privateWhat are the advantages of each way of creating objects?
Try 3 < MilitaryRank private and MilitaryRank private < 3. What error messages should they return? Figure out how to make good error messages.
self error: 'Big Mistake!'will generate an error message.
The army and the navy have different systems of rank. You can't compare the rank of someone from the army and the navy, though a Seaman knows better than to get in the way of a General. One solution is to make two classes, ArmyRank and NavyRank. If you do it right, you can make them almost identical, with most code in their common superclass. The only difference between them should be the method that returns the literal array and the instance creation methods. Implement this approach. Pay attention to what happens when you try to compare ranks that are not comparable. Note that we don't really care what the navy ranks are. Your solution should work for any new ranking system.
Once you get your code working, parcel in the Refactoring Browser and try out Smalllint. Smalllint is a tool that does for Smalltalk what lint does for C; it checks for common errors that you might have made. Running Smalllint on your code will help prevent some common errors that might cost you points. To run it, first create a Smalllint window, then select the military rank classes (all of them), then select the lint tests, and then tell it to run the checks.
Also, try out our test suite for ArmyRank and NavyRank. It uses the testing framework. So, first load the packages of the testing framework and then file in the test suite. You can run the test suite by executing "RankTestCase run". The result is an object that keeps track of all the errors. Inspect it or print it. If it indicates any errors, then run the particular test that caused the error. For example, if testNavy caused the error, then execute "RankTestCase new testNavy".
Eliminate duplication as much as possible. If you aren't careful, you will duplicate a lot of code between the different ranks. You can also duplicate code between the comparison methods. The less duplication, the easier your programs are to understand and to change.