Spring Semester 2002

Lab Notes Ten: Classes and objects revisited.

I include here a few problems for your review and exercise.

Write a program that produces random 8-letter words. Every time you run the program it gives you a new random word. (By word we mean, in this problem, a String of lowercase letters.)

frilled.cs.indiana.edu%javac One.java
frilled.cs.indiana.edu%java One
frilled.cs.indiana.edu%java One
frilled.cs.indiana.edu%java One
frilled.cs.indiana.edu%java One
Write a program that asks for a sequence of numbers (integers, as in the problems you saw on the practical exam) which it prints back, sorted in ascending order.

Here's an example of how your program might run:

frilled.cs.indiana.edu%javac One.java
frilled.cs.indiana.edu%java One
Welcome, we sort sequences of numbers.
Numbers> 1 2 3
OK, here's the array sorted: 1 2 3 
Numbers> 3 2 1
OK, here's the array sorted: 1 2 3 
Numbers> 1 3 2 4 5 7 6 8
OK, here's the array sorted: 1 2 3 4 5 6 7 8 
Numbers> 8 7 6 5 4 9 3 2 1 0
OK, here's the array sorted: 0 1 2 3 4 5 6 7 8 9 
Numbers> quit
Thanks for using this program. Good bye!
You might, of course, need this (countTokens(), that is) useful.

Look at this program, and figure out what it does and how you can use it.

class Sum {
    public static void main(String[] args) {
	int sum = 0; 
	for (int i = 0; i < args.length; i++) {
	    try {
		sum += Integer.parseInt(args[i]); 
	    } catch (Exception e) {
		System.out.println("Bad input: " + args[i] + " not a number.");
Here now are a few more problems, on Chapter Three related matters.

We need to review these things as we move into Inheritance and Applets.

Problems 1-8, and 10 are for (strongly suggested, badly needed) practice.

(Problem 9 becomes the lab assignment, as indicated.)

Problem 1. Consider the following 'nonsense class'.

class A
{ public A() { n = 0; } 
  public A(int a) { n = a; } 
  public void f() { n++; } 
  public void g() { f(); n = 2 * n; f(); }
  public int h() { return n; } 
  public void k() { System.out.println(n); }   
  private int n; 
Identify the constructors, mutator, accessor and effector functions.

What kind of variable is n? (See chapter 3 and 7 in the book for more help with the terminology).

Problem 2. With the class defined by Problem 1, determine what this program prints and why (how).

public static void main(String[] args) {
  A a = new A(); 
  A b = new A(2); 
  A c = b;
  A d = new A(3); 
  a.f(); b.g(); c.f(); d.g(); 
  A e = new A(a.h() + b.h() + c.h()); 
A few suggestions, in preparation for the upcoming exam(s): If totally lost start by running the program, then justify its output.

Problem 3. Implement all the methods of the following class:

class Person {
  Person() { ... }
  Person(String givenName, int yearOfBirth) { ... }
  String getName() { ... }
  String changeName(String name) { ... }
  int getAgeInYears(int currentYear) { ... }
  private String name;
  private int birthdayYear; 
Write a small test program that creates and works with objects of class Person as well.

You will notice that a Person resembles an Employee (or a Tigger, for that matter).

Problem 4. Implement a class Address. An address has

Supply two constructors: Supply a print function that prints the address with

Supply a method compareTo that

Problem 5. Implement a class Account. An account has

Pass a value into a constructor to set an initial balance.

If no value is passed the initial balance should be set to $0.

Charge a $5 penalty if an attempt is made to withdraw more money than available in the account.

Enhance the Account class to compute interest on the current balance.

Problem 6. Implement a class Portfolio. Every Portfolio is composed of two things:

They are both of the type Account that was developed in the preceding exercise.

Implement four instance methods:

Here the account string is "savings" or "checking":

Problem 7. Define a class Country.

An object of type Country will store

A Country is like an Employee.

Problem 8. Write a class called Triangle that can be used to represent a triangle. It should include the following methods that return boolean values indicating if the particular property holds:

Write a simple tester program that creates a few triangles and asks them about their type.

What comes next is:


Problem 9. This problem has several parts:
  1. Write a simple Vehicle class that has fields for (at least) current speed, current direction in degrees, and owner name.

  2. Add a static field to your Vehicle class for the highest Vehicle Identification Number issued, and a non-static field that holds each vehicle's ID number.

  3. Write a main method for your Vehicle class that creates a few vehicles and prints out their field values. Note that you can also write a separate tester program as well.

  4. Add two constructors to Vehicle. A no-arg constructor and one that takes an initial owner's name. Modify the tester program from the previous step and test your design.

  5. Make the fields in your Vehicle class private, and add accessor methods for the fields. Which fields should have methods to change them and which should not?

  6. Add a changeSpeed method that changes the current speed of the vehicle to a passed-in value, and a stop method that sets the speed to zero.

  7. Add two turn methods to Vehicle. One that takes a number of degrees to turn, and one that takes simply either a Vehicle.TURN_LEFT or a Vehicle.TURN_RIGHT constant. Define the two constants accordingly.

  8. Add a static method to Vehicle that returns the highest identification number used so far.

  9. Add a toString method to Vehicle.
This problem is really following the steps developed in the Dilbert
lecture so if you understand that lecture you will have no problem putting together the solution to this lab assignment.

This is the end of LAB ASSIGNMENT TEN. (Only Vehicle needs to be turned in).

But you may also be asked about the three programs at the very top of this document.

I also include here the text for the Fractions exercise that appears in the Dilbert lecture.

Problem 10. Define a class of Fractions (an abstraction for the concept) and use it in a test program.

Here's how one may get started:

class Fraction {

  int num;
  int den; 

  Fraction(int a, int b) { this.num = a; this.den = b; }

  public String toString() {
      return " (" + num + "/" + den + ") "; 

  Fraction add(Fraction other) {
    return new Fraction(
             this.num * other.den + this.den * other.num, 
             this.den * other.den

  public static void main(String[] args) {

    Fraction a = new Fraction(1, 3);
    Fraction b = new Fraction(2, 3); 





For a longer description of this problem, consider ordinary fractions like 3/4 and -1/2. A fraction is the ratio of two integers: a numerator and a denominator. You need to create a user-defined type for fractions by defining a class Fraction.

This class should supply a set of necessary operations on fractions

and should hide implementation details of data representation and internal manipulations.

Remember that a class encapsulates data structures with access and manipulation procedures. In designing a class, an important task is to decide on the internal data representation which is isolated from the outside view. Member methods will keep the data representation consistent. Outside methods are not allowed to create or modify the internal structures directly. They may do this by calling (other) methods in the class.

Here are some (internal) representation considerations to guide your design:

Your Fraction class can be designed to enforce such conventions, not just to have them as principles that one can choose to follow or ignore. This is one big advantage of object-oriented programming. The canonical representation conventions should be enforced by the Fraction constructor.

The constructor should take the two arguments n and d and construct a fraction n/d out of it. The denominator of the resulting Fraction should not be zero or negative. The fraction should be reduced by removing the gcd (greatest common divisor) between the numerator and the denominator. You should define a member method gcd that computes the gratest common divisor of two numbers and make the constructor use it to create canonical Fractions. gcd should be implemented as a classwide method since it is independent of Fraction instances. It should be declared private because it does not contribute to the public interface of the Fraction class.

We provided gcd in a separate class, Euclid (in Lecture Notes Fifteen).

The operations for fractions listed above should implement binary operations. In other words we are going to define methods such that a Fraction can be added to, subtracted from, multiplied with, or divided by another Fraction. The result should be a Fraction.

You should also define a few predicates.

Each Fraction that you create should be able to respond to the following questions:

You should also add a toString method to Fraction (an instance method) that returns a String representation of a Fraction. It must be an instance method as it is used to produce a representation of the object in a textual context.

Testing your Fractions:

// TestFrac.java

class TestFrac {
  public static void main(String[] args) {
    Fraction x = new Fraction( 1, 20); 
    Fraction u = new Fraction(-1, 60); 
    Fraction v = new Fraction( 1, 30); 
    Fraction y; 
    y = x.plus(u).minus(v); // in one step!
    System.out.println( x + " + " + 
                        u + " - " + 
                        v + " = " + y); 
Lecture Notes Fifteen contain a test program, too.

One last, final question for this lab:

What's this program doing (and how)?

import java.util.*; 

class One {
    public static void main(String[] args) {
	System.out.println("Welcome, you know what you have to do. "); 

	ConsoleReader console = new ConsoleReader(System.in); 

	while (true) {

	    System.out.print("Enter> "); 

	    String line = console.readLine(); 
	    if (line.equals("quit") || line.equals("")) break; 

	    StringTokenizer nizer = new StringTokenizer(line); 

	    int[] numbers = new int[nizer.countTokens()]; 

	    for (int i = 0; i < numbers.length; i++) {

		numbers[i] = Integer.parseInt(nizer.nextToken()); 



	    System.out.print("Here's your line of input, processed: ");



	System.out.println("Thank you for using this program."); 


    public static void show(int[] args) {
	for (int i = 0; i < args.length; i++) {
	    System.out.print(args[i] + " "); 

    public static void process(int[] args) {

	for (int i = 0; i < args.length - 1; i++) {
	    for (int j = i; j < args.length; j++) {

		if (args[i] > args[j]) {
		    int temp = args[j];
		    args[j] = args[i];
		    args[i] = temp; 




Last updated: Mar 26, 2002 by Adrian German for A201