The sequence of letters used to represent a number starts with the largest letter value required and continues with the same or smaller letter values that are added or subtracted to create a final total value. A letter may be included more than once as needed. If a letter is followed by a letter with the same or a smaller value, its value is added into the total. For example, XXXV (3 tens and a five) is used to represent the value 35. If a letter is followed by a letter with a larger value, it is a prefix for the following letter (also called a subtractive) and its value is subtracted from the total. For example, CCXC (2 times 100 minus 10 plus 100) is used to represent the value 290. One I can be used as a prefix for V or X. One X can be used as a prefix for L or C. One C can be used as a prefix for D or M
In this assignment, you will write three classes: one to represent a RomanLetter, another to represent a RomanNumeral consisting of RomanLetter objects in sequence, and an application that uses Roman numerals. The UML class diagram is shown in this figure: See image.
A more detailed UML class diagram for the RomanNumeral and RomanLetter classes is shown in this figure: See image.
One good way to approach developing a set of classes where there are dependencies is to write and test the class(es) that have no dependencies first. Then, write and test the class(es) that depend on the ones you have already written and tested. Finally, write the class with the main method. This is the bottom up method. That strategy would lead us to write the RomanLetter class first, the RomanNumeral class next, and theRomanNumeralApp class last.
Your RomanLetter class must encapsulate the relevant characteristics (attributes) of a letter in a RomanNumeral object. The attributes are the letter itself, its decimal value, what letter prefix it may have, and the decimal value of the letter minus the value of its prefix. For example, the RomanLetter C would have attributes of the letter itself (C), its decimal value of 100, its prefix may be X, and the decimal value of the letter C minus its prefix X is 90.
Since there is a tight coupling between the RomanNumeral class and the RomanLetter class, we can simplify our RomanLetter code by making its attributes directly accessible to code in the RomanNumeral class. This avoids the need for writing “getter” methods. We set the access for the RomanLetter attributes to “protected” which allows direct access by any code located in the same directory (package). We also set the attributes to “final”. Once they are initialized by the constructor, they cannot be modified. Therefore, a RomanLetter object is considered to be “immutable”.
This class has an attribute for an ArrayList of RomanLetter objects. When creating a new RomanNumeral object, we don’t know in advance how many RomanLetter objects will be required. If we uased a simple array instead of an ArrayList, we would need to worry about the fixed size of an array and manage “getting a larger array” when required. Using the ArrayList class, the space required for a variable number of objects is automatically managed for us.
This class also has an attribute for an array containing the valid Roman numeral letters. The number of valid letters is a constant and known in advance. We can use an array without needing to increase the size of the array later. This array will be an array of RomanLetter objects – one for each letter from the . Declare and initialize this array with new RomanLetter objects – one for each letter in sequence. Alias references to elements from this array are added to the ArrayList representing the Roman numeral.
This class has two constructors.
The RomanNumeral class implements the interface Comparable
The RomanNumeral class provides an equals(RomanNumeral that) method that returns a true if the two RomanNumerals have the same decimal value. It returns false otherwise.
The RomanNumeral class supports arithmetic with the plus(RomanNumeral that) and minus(RomanNumeral that) methods. Each method converts the values of the two RomanNumerals to decimal, adds/subtracts them, and instantiates/returns a new RomanNumeral object with the result.
I have provided a junit TestCase class for you to use in testing your RomanNumeral class (Project3.zip). One way to use this at the beginning is to write the “boilerplate” with stubs for your RomanNumeral class so that it will compile. A stub has the method header plus a return statement (if needed), but doesn’t attempt to calculate and/or return a correct value. Then, keep running the test cases as you fill in the rest of the code to complete the class. If you didn’t test your RomanLetter class, problems flagged by the provided TestCase class could be in either of your two classes. That may make it harder to finish debugging the combination of the two classes.
Include Javadoc comments in your RomanNumeral and RomanLetter class code with @author and @version for the class and with @param and @return for each method. In the comments for each method, include a brief description of the functions or calculations that your code performs. Run javadoc on your classes to create a webpage describing the API to your classes. Include a copy of this javadoc generated webpage in your project folder.
Use the javadoc webpages for the library Arrays class and your classes as guidance while you are writing the code for this class. You should find it easy to create and do operations on RomanNumeral objects including arithmetic or sorting an array of them without knowing anything about the arithmetic involved or the process of sorting.
You can define the functions for this class yourself as long as it does some arithmetic with RomanNumeral objects, creates an array of RomanNumeral objects that are out of order, prints out the array, sorts the array using Arrays.sort (lookup it on the web), and then prints the array again.
> run RomanApp
Sum of two numbers: CCLXXIV
Difference of two numbers: IV
Before sorting:
MMI
CXXXIX
CXXXV
MCMXXXIII
I
After sorting:
I
CXXXV
CXXXIX
MCMXXXIII
MMI