Assignment 5: Classes and Objects Revisited

Due date: Tuesday February 16, 11:59pm by e-mail

Read chapter 8 in your textbook and the lecture notes carefully then solve the following problems.

What to turn in: one file that has the solutions to each of these problems. For each exercise write down your answer to it followed by any experiments that you may have run or tester programs you may have written to check your solution.

Warm-ups:

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

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(); 
}
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() { ... }
  public Person(String givenName, int yearOfBirth) { ... }
  public String getName() { ... }
  public String changeName(String name) { ... }
  public 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.


Design exercises:

4. Implement a class Address. An address has

Supply two constructors: 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.


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.


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

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.


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


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.


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.


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

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:

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.

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:

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

For the ambitious:

Add a private method lcm to the class Fraction that takes two ints 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.