CSC 153 | Grinnell College | Spring, 2005 |
Computer Science Fundamentals | ||
Laboratory Exercise | ||
This laboratory provides additional practice in defining simple Java classes and in designing one class to take advantage of existing classes.
Consider the problem of maintaining a roster of students in a class. For each student, we wish to store both an address and a telephone extension. For the roster itself, we wish to support the following operations:
put
: add the name, address, and phone extension to the roster
get
: retrieve the address and phone extension of the student
with a given name
remove
: delete the entry of the student with a given name
printAll
: print (in any order) the entries in the class roster
Since the demands of this problem are modest, we look for a relatively simple solution. In particular, we will use the Java class library, making few changes when possible.
A student's name could be represented by a Java String
.
The application consistently uses the student's address and telephone
extension as a package, so it seems natural to combine those into a simple
AddressPhone
class with two fields:
String address;
int extension;
In considering needed methods, the application requires creating/initializing an address/extension object and then printing the data. The application does not require changing either field, so we do not need to include any mutator methods. Rather, we provide just two methods:
// two-parameter constructor:
AddressPhone (String add, int phone) {
// initialization code goes here
}
String toString() {
// code to format data within a String goes here
}
Of course, many additional methods could be defined, but they do not seem needed for this problem
Write class AddressPhone
implementing the methods given above.
Hint: Several elements of AddressPhone
can be modeled
after the Course.java
example that we studied in the first Java lab.
Add a main
method, so that you can test that the constructor
and toString
methods work correctly in at least a couple
cases.
Hint: Again Course.java
from the first Java lab can serve as a model.
In reviewing the operations needed for this application, we note that the
Hashtable class from the
previous lab on Hashtables and Inheritance contains almost everything
that we need. Thus, our approach will be to take advantage of the
Hashtable class, adding a printAll
method and a
main
for testing. Some basic elements of Java
object-oriented problem solving and Java make this approach relatively
straight forward.
First, we define our new CourseRoster Class, based on the Hashtable Class. This is done with the initial declaration:
public class CourseRoster extends Hashtable <String, AddressPhone> {
// CourseRoster will have keys as Strings and values as CoursePhone objects
With this declaration, CourseRoster
automatically has all
methods implemented in Hashtable
. Thus, instead of writing
all methods identified at the start of this lab, we only must implement
printAll
— and perhaps a main
for testing.
Thus, the full description of CourseRoster
has this form:
public class CourseRoster extends Hashtable <String, AddressPhone> {
// CourseRoster will have keys as Strings and values as AddressPhone objects
public void printAll() {
// In outline:
// set up a PrintWriter object for printing
// loop through all keys
// for each key,
// retrieve the corresponding address/phone value
// print out the name and address/phone value
}
public static void main (String[] args) {
// declare a couple objectgs:
CourseRoster csc151 = new CourseRoster();
CourseRoster csc153 = new CourseRoster();
// add two students to one course and one to the other
csc151.put ("Mickey Mouse", new AddressPhone("Hollywood", 314159));
csc151.put ("Minnie Mouse", new AddressPhone("Hollywood", 271828));
csc151.put ("Donald Duck", new AddressPhone("Disneyland", 12345));
// test required methods
}
In creating an entry (with the put
method, we give an explicit
string for the key. For the value, we need an AddressPhone
object, with an address and telephone number. Thus, in each case, we create a new
object, using our constructor.
CourseRoster
toString
method of class
AddressPhone
already formats the relevant address and
telephone information, the print statement can have the form
out.println ("Student: " + retrievedKey + "\n" + retrievedValue);
where retrievedKey
and retrievedValue
are
obtained using methods from the Hashtable class, as indicated in the outline.
Suppose that in addition to the operations discussed previously, we also
want to maintain a count of the number of students in a class. To
accomplish this task, we want to add a field numberStudents
within the class and a method classSize
.
The definitions of these items is straight forward:
int numberStudents;
public int classSize () {
return numberStudents;
}
To maintain this count, however, we need to initialize
numberStudents
in a constructor and then modify the
put
and remove
methods. Strategically, we want
these methods to do about what they have done before, but we also want to
increment or decrement the numberStudents
.
Again, the constructor is easy:
CourseRoster () {
numberStudents = 0;
}
In writing put
and remove
, we want to change the
counter variable, but then use the corresponding operation in
Hashtable
. Within object-oriented problem solving, we call
CourseRoster
as subclass of HashTable
, since
CourseRoster
extends HashTable
. Similarly,
we say HashTable
is a superclass of
CourseRoster
. This jargon explains the needed code in
CourseRoster
to define the new put
method.
public AddressPhone put (String name, AddressPhone addph) {
numberStudents++; // increment the count
return super.put (name, addph); // invoke Hashtable's run method
}
numberStudents
and making adjustments to methods as necessary.
This document is available on the World Wide Web as
http://www.walker.cs.grinnell.edu/courses/153.sp06/labs/lab-java-prob.sol-2.shtml
created 18 April 2006 last revised 19 April 2006 |
![]() ![]() |
For more information, please contact Henry M. Walker at walker@cs.grinnell.edu. |