Here are the answers to homework 5.

# Assignment 5: Classes and Objects Revisited Solutions

Warm-ups:

1. Consider the following 'nonsense class'.

```class A
{ public A() { n = 0; } // constructor
public A(int a) { n = a; } // constructor
public void f() { n++; } // mutates n
public void g() { f(); n = 2 * n; f(); }
// g mutates n directly and indirectly (f)
public int h() { return n; } // accessor of n
public void k() { System.out.println(n); }
// does not return, only prints, the value of n
private int n; // instance variable
}```
Identify the constructors, mutator functions, and accessor functions. What kind of variable is `n`?

2. With the nonsense class from the preceding exercise, determine what the following program prints.

It prints `9` and `17` and here's why:

```public static void main(String[] args) {
A a = new A(); // a.n is 0
A b = new A(2); // b.n is 2
A c = b; // c points where b points so c.n = b.n = 2
A d = new A(3); // d.n is 3
a.f(); // a.n is 1
b.g(); // b.n becomes 3, 6, then 7
c.f(); // c.n is b.n and it becomes 8
d.g(); // d.n becomes 4, 8, then 9
d.k(); // d.n is printed on a line by itself
A e = new A(a.h() // a.n is 1
+ b.h() // b.n is 8 and is equal to c.n
+ c.h() // which is 8
); // so e.n is set to 1 + 8 + 8 = 17
e.k(); // e.n (17) is printed on a line by itself
}```
Work through the program by hand. Do not actually compile and run the program. Then run it and compare the results.

3. Implement all the methods of the following class:

```class Person {
public Person() {
name = "YetToBeNamed";
birthdayYear = 1999; // my default
}
public Person(String givenName, int yearOfBirth) {
name = givenName;
birthdayYear = yearOfBirth;
}
public String getName() {
return name;
}
public String changeName(String name) {
String aux;
aux = this.name;
this.name = name;
return aux;
}
public int getAgeInYears(int currentYear) {
return currentYear - birthdayYear;
}
private String name;
private int birthdayYear;
public static void main(String[] args) {
Person a = new Person();
Person b = new Person("Richard P. Feynman", 1918);
String name = a.changeName("The Next Richard Feynman");
System.out.println(
"Physicist " + name + " makes big " +
"discovery, touted as " + a.getName()
);
System.out.println(
b.getName() + " was " +
b.getAgeInYears(1945) +
" in 1945, in May. "
);
}
}```
Write a small test program that creates and works with objects of class `Person` as well.

As shown, the test program can be the very `main` method of the class we wrote.

Design exercises:

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.

```class Address {
int    houseNumber;
String street;
int    apartmentNumber;
String city;
String state;
String zipCode; // e.g., "47405-1234"
String street,
// no apartmentNumber
String city,
String state,
String zipCode) {
this.houseNumber = houseNumber;
this.street = street;
this.city = city;
this.state = state;
this.zipCode = zipCode;
}
String street,
int apartmentNumber,
String city,
String state,
String zipCode) {
this(houseNumber, street, city, state, zipCode);
this.apartmentNumber = apartmentNumber;
}
void print() {
System.out.println("Street: "      + street);
System.out.println("City: "        + city
+ "State: "       + state
+ "Postal Code: " + zipCode);
}
// same conventions as for Strings
return this.zipCode.compareTo(a.zipCode);
}
}```

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.

```class Account {
double balance;
balance += sum;
return sum;
}
double withdraw(double sum) {
if (sum > balance) {
balance -= 5;
return -5; // this will come in handy in Prob. 6
} else {
balance -= sum;
return balance; // Notice: always >= 0 (never < 0)
}
}
double inquire() { return balance; }
Account() { balance = 0; }
Account(double sum) { balance = sum; }
double interest (double rate) {
return rate * balance;
}
}```

6. Implement a class `Bank`. This bank has two objects

• `checking`
• and `savings`
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 `"S"` or `"C"`. 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.

```class Bank {
Account checking;
Account savings;
void deposit(double amount, String account) {
else // my default
}
void withdraw(double amount, String account) {
if (account.equals("C")) checking.withdraw(amount);
else // my default
savings.withdraw(amount);
}
void transfer (double amount, String account) {
if (account.equals("C"))
if (checking.withdraw(amount) >= 0)
else // default
if (savings.withdraw(amount) >= 0)
else savings.add(5);  // no penalty for transfers
}
void printBalances() {
System.out.println(
"Checking: " + checking.inquire() +
"\nSavings: " + savings.inquire()
);
}
}```

7. Define a class `Country` that stores the name of the country, its population, and its area. Using that class, write a test program that creates a few countries and stores them in an array and then prints

• The country with the largest area
• The country with the largest population
• The country with the largest population density (people per square mile)
Here's an answer with the `main` as part of the very class we are defining:

```class Country {
String name;
long population;
double area;
Country(String name, long population, double area) {
this.name = name;
this.population = population;
this.area = area;
}
double density () {
if (area > 0)
return population/area;
else return 0;
}
public static void main(String[] args) {
int numberOfCountries = 10;
Country[] countries = new Country[numberOfCountries];

double lArea    = -1;    int lAreaIndex = -1;
long   lPop     = -1;     int lPopIndex = -1;
double lDensity = -1; int lDensityIndex = -1;

for (int i=0; i < countries.length; i++) {
if (lArea < countries[i].area) {
lArea = countries[i].area;
lAreaIndex = i;
}
if (lPop < countries[i].population) {
lPop = countries[i].population;
lPopIndex = i;
}
if (lDensity < countries[i].density()) {
lDensity = countries[i].density();
lDensityIndex = i;
}
}
System.out.println(
"Largest area: "       + country[lAreaIndex]       +
"Largest population: " + country[lPopulationIndex] +
"Largest density: "    + country[lDensityIndex]
);
}
String toString() { // comes in handy in the println above
return "\nCountry name: " + name +
"\nPopulation: "   + population +
"\nArea: "         + area +
"\nDensity: "      + density()
}
}```

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.
```class Triangle {
int sideA, sideB, sideC;

Triangle (int a, int b, int c) { // constructor
sideA = a; sideB = b; sideC = c;
} // negative numbers and zero lengths accepted
// but see how isTriangle() used below

boolean isTriangle () {
int max = Math.max(Math.max(sideA, sideB), sideC);
return sideA > 0 && sideB > 0 && sideC > 0 &&
(max < sideA + sideB + sideC - max);
}
boolean isRight() {
int max = Math.max(Math.max(sideA, sideB), sideC);
return isTriangle() &&
(max * max) == (sideA * sideA) +
(sideB * sideB) +
(sideC * sideC) -
(max * max);
}
boolean isScalene() {
return isTriangle() &&
! isIsosceles(); // we get some peer help
}
boolean isIsosceles() {
return isTriangle() &&
(sideA == sideB ||
sideA == sideC ||
sideB == sideC);
}
boolean isEquilateral() {
return isTriangle() &&
(sideA == sideB && sideA == sideC);
}
public static void main(String[] args) {
Triangle a, b, c;
a = new Triangle( 3,  4,  5);
b = new Triangle( 0,  0, -1);
c = new Triangle( 6,  6,  6);
System.out.println(
a + " isosceles? Answer: " + a.isIsosceles()
);
System.out.println(
a + " right? Answer: "     + a.isRight()
);
System.out.println(
c + " isosceles? Answer: " + c.isIsosceles()
);
System.out.println(
c + " scalene? Answer: "   + c.isScalene()
);
}
String toString() {
System.out.println(
"Triangle: (" + sideA + ", "
+ sideB + ", "
+ sideC +
") ";
);
}
}```

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.

```class Vehicle {
int currentSpeed;
int currentDirection;
String owner;
}```
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.

```class Vehicle {
int currentSpeed;
int currentDirection;
String owner;
static int highestVIN;
int VIN;
}```
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.

```class Vehicle {

int currentSpeed;
int currentDirection;
String owner;
static int highestVIN;
int VIN;

public static void main(String[] args) {

Vehicle a = new Vehicle();
a.VIN = highestVIN++;
a.owner = "Larry Bird";

Vehicle b = new Vehicle();
b.VIN = highestVIN++;
b.owner = "Mark Jackson";

System.out.println("VIN: " + a.VIN + " belongs to " + a.owner);

System.out.println("VIN: " + b.VIN + " belongs to " + b.owner);

// Note that both cars are stopped, and facing East.

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

```class Vehicle {
int currentSpeed;
int currentDirection;
String owner;
static int highestVIN;
int VIN;

Vehicle() { VIN = highestVIN++; }
Vehicle (String owner) { this(); this.owner = owner; }

public static void main(String[] args) {

Vehicle a = new Vehicle("Larry Bird");
Vehicle b = new Vehicle("Mark Jackson");

System.out.println("VIN: " + a.VIN + " belongs to " + a.owner);
System.out.println("VIN: " + b.VIN + " belongs to " + b.owner);
}
}```
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?

```class Vehicle {
private int currentSpeed;
int getSpeed() {
return currentSpeed;
}
void changeSpeed(int newSpeed) {
currentSpeed = newSpeed;
}
private int currentDirection;
int getCurrentDirection() {
return currentDirection;
}
void setDirection(int newDirection) {
currentDirection = newDirection % 360;
}
private String owner;
int getOwner() {
return owner;
}
void setOwner(String newOwner) {
owner = newOwner;
}
private static int highestVIN;
private int VIN;
int getVIN() {
return VIN;
}
Vehicle() { VIN = highestVIN++; }
Vehicle (String owner) { this(); this.owner = owner; }
public static void main(String[] args) {
Vehicle a = new Vehicle("Larry Bird");
Vehicle b = new Vehicle("Mark Jackson");
System.out.println("VIN: " + a.getVIN() + " belongs to " + a.getOwner());
System.out.println("VIN: " + b.getVIN() + " belongs to " + b.getOwner());
}
}```
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.

```class Vehicle {
private int currentSpeed;
int getSpeed() { return currentSpeed; }
void changeSpeed(int newSpeed) { currentSpeed = newSpeed; }
void stop() { currentSpeed = 0; }
private int currentDirection;
int getCurrentDirection() { return currentDirection; }
void setDirection(int newDirection) { currentDirection = newDirection % 360; }
private String owner;
int getOwner() { return owner; }
void setOwner(String newOwner) { owner = newOwner; }
private static int highestVIN;
private int VIN;
Vehicle() { VIN = highestVIN++; }
Vehicle (String owner) { this(); this.owner = owner; }
public static void main(String[] args) {
// ...
}
}```
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.

```class Vehicle {
private int currentSpeed;
int getSpeed() { return currentSpeed; }
void changeSpeed(int newSpeed) { currentSpeed = newSpeed; }
void stop() { currentSpeed = 0; }
private int currentDirection;
int getCurrentDirection() { return currentDirection; }
void setDirection(int newDirection) { currentDirection = newDirection % 360; }
static final String TURN_LEFT = "Turn left";
static final String TURN_LEFT = "Turn left";
void turn(int degrees) {
currentDirection = (currentDirection + degrees) % 360;
}
void turn(String direction) {
if (direction.equals(left)) {
currentDirection = (currentDirection + 90) % 360;
} else { //default
currentDirection = (currentDirection - 90) % 360;
}
}
private String owner;
int getOwner() { return owner; }
void setOwner(String newOwner) { owner = newOwner; }
private static int highestVIN;
private int VIN;
Vehicle() { VIN = highestVIN++; }
Vehicle (String owner) { this(); this.owner = owner; }
public static void main(String[] args) {
// ...
}
}```
8. Add a static method to `Vehicle` that returns the highest identification number used so far.

```class Vehicle {
private int currentSpeed;
int getSpeed() { return currentSpeed; }
void changeSpeed(int newSpeed) { currentSpeed = newSpeed; }
void stop() { currentSpeed = 0; }
private int currentDirection;
int getCurrentDirection() { return currentDirection; }
void setDirection(int newDirection) { currentDirection = newDirection % 360; }
static final String TURN_LEFT = "Turn left";
static final String TURN_LEFT = "Turn left";
void turn(int degrees) { currentDirection = (currentDirection + degrees) % 360; }
void turn(String direction) {
if (direction.equals(left)) { currentDirection = (currentDirection + 90) % 360; }
else { currentDirection = (currentDirection - 90) % 360; }
}
private String owner;
int getOwner() { return owner; }
void setOwner(String newOwner) { owner = newOwner; }
private static int highestVIN;
static int highestVIN() {
return highestVIN;
}
private int VIN;
Vehicle() { VIN = highestVIN++; }
Vehicle (String owner) { this(); this.owner = owner; }
public static void main(String[] args) {
// ...
}
}```
9. Add a `toString` method to `Vehicle`.
```class Vehicle {
String toString() {
return "The radar reports: VIN " +  VIN +
" owned by " + owner +
" heading " + currentDirection +
" (degrees) " +
" at a speed of " + speed);
}
private int currentSpeed;
int getSpeed() { return currentSpeed; }
void changeSpeed(int newSpeed) { currentSpeed = newSpeed; }
void stop() { currentSpeed = 0; }
private int currentDirection;
int getCurrentDirection() { return currentDirection; }
void setDirection(int newDirection) { currentDirection = newDirection % 360; }
static final String TURN_LEFT = "Turn left";
static final String TURN_LEFT = "Turn left";
void turn(int degrees) { currentDirection = (currentDirection + degrees) % 360; }
void turn(String direction) {
if (direction.equals(left)) { currentDirection = (currentDirection + 90) % 360; }
else { currentDirection = (currentDirection - 90) % 360; }
}
private String owner;
int getOwner() { return owner; }
void setOwner(String newOwner) { owner = newOwner; }
private static int highestVIN;
static int highestVIN() { return highestVIN; }
private int VIN;
Vehicle() { VIN = highestVIN++; }
Vehicle (String owner) { this(); this.owner = owner; }
public static void main(String[] args) {
// ...
}
}```

10. Define a class of `Fractions`

Consider ordinary fractions like 3/4 and -1/2. A fraction is the ratio of two integers: a numerator and a denominator. Create a user-defined type for fractions by defining a class `Fraction`. The 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 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.

`gcd` is described in your text on page 149.

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

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

For the ambitious:

Add a private method `lcm` to the class `Fraction` that takes two `int`s and returns their least common multiple. (For example, `lcm(15, 12)` is `60`. Hint: use `gcd`). Modify `minus` and `plus` in `Fraction` to use `lcm`.

```// File: Fraction.java

public class Fraction {
private int num;    // numerator
private int denom;  // denominator
public Fraction(int n, int d) {
int g;
if (d == 0) {
System.out.println("Fraction: fraction "
+ "with 0 denominator?"); System.exit(1);
}
if (n == 0) {
num = 0;
denom = 1;
} else {
if (d < 0) {
n = -n;
d = -d;
}
if ((g = gcd(n, d)) != 1) { // remove gcd
n /= g;
d /= g;
}
num = n;
denom = d;
}
}
private static int gcd(int a, int b) {
a = Math.abs(a);
b = Math.abs(b);
if (a == 0) return b; // 0 is error value
if (b == 0) return a;
int t;
while (b > 0) {
t = a % b; // take "-" to the extreme
a = b;
b = t;
}
return a;
}
public boolean isZero() {
return (denom == 1 && num == 0);
}
public boolean isInt() {
return (denom == 1);
}
public boolean equals(Fraction y) {
return (num == y.num && denom == y.denom);
}
public boolean greaterThan(Fraction y) {
return (num * y.denom > denom * y.num);
}
public Fraction minus(Fraction y) {
return new Fraction(
num * y.denom - y.num * denom,
denom * y.denom
);
}
public Fraction plus(Fraction y) {
return new Fraction(
num * y.denom + y.num * denom,
denom * y.denom
);
}
public Fraction times(Fraction y) {
return new Fraction(num * y.num, denom * y.denom);
}
public Fraction dividedBy(Fraction y) {
return new Fraction(num * y.denom, denom * y.num);
}
}```
The part for the ambitious will be posted here.

If you have any questions please let us know.