Tutorial 12:
Double Arrays and Polymorphism (July 20)
Today's tutorial covers two topics that are central to your success on
the final assignment: twodimensional arrays and polymorphism. These were
covered in lecture modules 10 and ll (see
handouts).
 Double Arrays
We will be implementing a class GradeBook , which stores marks
for a number of students for a number of assignments by using a 2D array.
Stored are the names of each student, the marks of each student on each
assignment (the 2D array), and the maximum score for each assignment.
The methods you are to implement are:
GradeBook(String[]) : Constructor from a list of student names
int numAssignments() : Get num. of assignments so far
int numStudents() : Get num. of students in the book
addAssignment(int[],int) : Add a new assignment with the given
scores for the students
int getMark(String,int) : Get a student's mark on a single
assignment
changeMark(String,int,int) : Change a student's mark on a single
assignment
double avgMark(int) : Get the average mark on a given assignment
double studentAvg(String) : Get the given student's average over
all assignments
String topStudent() : Get the name of the student with the
highest average
curveAssignment(int) : Curve all the marks on a given assignment
to the highest mark.
Details for these methods can be found in the comments of the skeleton
code. The first 6 methods (including constructor) must be implemented for the
tests to function properly. Then you can try implementing any of the other
methods and test your implementation with the provided
GradeBookTest class.
 Polymorphism
Included in the skeleton code are two classes, Sequence
and SequenceUtils . The first is a class to represent arithmetic
sequences, with an iteratorlike implementation. SequenceUtils
just contains a few methods to perform some basic operations on a given
Sequence object.
 Refactoring
Now suppose we want to be able to handle any kind of sequences, not just
arithmetic ones. To accomplish this without modifying the
SequenceUtils class, rewrite Sequence to be an
interface and make a new class called ArithmeticSeq that
implements this interface.
 New Sequences
Now we can actually add new sequence classes. Some ideas are Geometric
Sequences (i.e. of the form <a,ab,ab^{2},ab^{3},...>)
and the Fibonacci sequence.
 Another interface
Notice that the sumFirst method in SequenceUtils
is actually calling next() k times and adding up the results. But
for some sequences, such as arithmetic and geometric, we can actually compute
this sum explicitly with formulas.
To handle this, make a new interface
SummableSeq that is a subinterface of Sequence ,
with just one method, int sumFirst(int k) . Then make your
arithmetic and geometric sequence classes implement this interface.
Finally, we have to add code to the SequenceUtils class
to recognize SummableSeq arguments and handle them more
efficiently. One solution is to override the sumFirst method
by writing another method with signature
public static int sumFirst(SummableSeq ss, int k)
The problem with this is when we have something like:
Sequence s = new ArithmeticSeq(2,3);
SequenceUtils.sumFirst(s,10); // doesn't call sumFirst in ArithmeticSeq!
What is happening here and why? Now use the instanceof operator
in the original sumFirst method to handle this and make everything
work just like we want.
