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
gknmhyzw
frilled.cs.indiana.edu%java One
kkbkzihm
frilled.cs.indiana.edu%java One
ydsyocnr
frilled.cs.indiana.edu%java One
nlewmvkx
frilled.cs.indiana.edu%```
Write a program that asks for a sequence of numbers (`int`egers, 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!
frilled.cs.indiana.edu%```
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.");
}
}
System.out.println(sum);
}
}```
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();
d.k();
A e = new A(a.h() + b.h() + c.h());
e.k();
}```
A few suggestions, in preparation for the upcoming exam(s):
• Work through the program by hand.
• Do not actually compile and run the program first.
• After you have an answer run the program and compare the results.
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

• a house number,
• a street,
• an optional apartment number,
• a city,
• a state and a
• postal code.
Supply two constructors:
• one with an apartment number
• and one without.
Supply a `print` function that prints the address with
• the street on one line and
• the city, state, and postal code on the next line.

Supply a method `compareTo` that

• tests whether one address comes before another
• when the addresses are compared by postal code.

Problem 5. Implement a class `Account`. An account has

• a `balance`,
• functions to `add`
• and `withdraw` money,
• and a function to `inquire` the current balance.
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:

• a `checking` account (or, rather, `Account`)
• and a `savings` account
They are both of the type `Account` that was developed in the preceding exercise.

Implement four instance methods:

• `deposit(double amount, String account)`
• `withdraw(double amount, String account)`
• `transfer(double amount, String account)`
• `printBalances()`
Here the account string is `"savings"` or `"checking"`:
• For the deposit or withdrawal, it indicates which account is affected.
• For a transfer it indicates the account from which the money is taken; the money is automatically transferred to the other account.

Problem 7. Define a class `Country`.

An object of type `Country` will store

• the name of the country,
• its population, and
• its area.
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:

• `isRight` (a right triangle)
• `isScalene` (no two sides are the same length)
• `isIsosceles` (exactly two sides are the same length)
• `isEquilateral` (all three sides are the same length)
Write a simple tester program that creates a few triangles and asks them about their type.

A201/A597 LAB ASSIGNMENT TEN

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 `Fraction`s exercise that appears in the Dilbert lecture.

Problem 10. Define a class of `Fraction`s (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);

System.out.println(a.toString());

System.out.println(b);

}

}```
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

• subtraction
• multiplication
• division
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:

• A fraction is essentially a pair of integers called `numerator` and `denominator`.

• The numerator carries the sign of the fraction and can be positive, negative, or zero.

• The denominator is kept positive and can never be zero.

• Fractions with the same value may have different representations (for example 1/2, 2/4, 3/6). In our representation let's decide for equal fractions to have the same numerator and the same denominator. That means that all fractions must be reduced to their lowest terms. (A data representation in which all equal quantities are represented uniquely is known as a canonical representation. Keeping fractions canonical is desirable and we should enforce this.) The canonical representation of 0 (zero) as a fraction is 0/1.
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 `Fraction`s. `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:

• `isZero()`
• `isInt()`
• `equals(anotherFraction)`
• `greaterThan(anotherFraction)`
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 `Fraction`s:

```// 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. ");

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());

}

One.process(numbers);

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

One.show(numbers);

}

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] + " ");
}
System.out.println();
}

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