Lab 07
Lab 07
The Fraction class is another example of a utility class that allows you to write methods that are more complex.
You will write methods that.
are passed objects.
create and return new objects.
use if – else.
provide a private service and are not available for public use!
TO PREPARE
Read : Chapter
TO COMPLETE
This is an individual lab. You may ask the lab tutor for help, and you may consult with your neighbor if you are
having difficulties.
Your grade for the lab will be determined by handing in a hardcopy of your final Fraction.java and the result of
one run of the program.
Let's design a class called Fraction that stores the numerator and denominator of a fraction, which will be the instance
variables of a Fraction object.
The methods should include.
o constructors to create Fraction objects.
o methods that allow two Fraction s objects to be added, subtracted, multiplied and divided
o methods to allow display of the Fraction in the form numerator/denominator.
o a method that finds the decimal equivalent of the Fraction
o methods to compare two Fraction objects for equality, is less than and is greater than.
S t e p 1 : We start with one constructor, Fraction(int num, int den) , and a to String method. This is enough to
allow a client to create and print a Fraction object. We will design the client as a developer might by including a main
PAGE 7.1
method in the Fraction class for testing purposes. Once the Fraction class is developed, rather than omitting the main
method, it can be commented out, thus allowing further testing if changes are made to the class.
Begin the class definition by entering the following in the file Fraction.java .
class Fraction
{
//instance variables
private int numerator, denominator;
//constructors
PAGE 7.2
J A V A L A B M A N U A L
sum = f1.plus(f2);
System.out.println(f1 + " + " + f2 + " = " + sum);
S t e p 3 : Recall that to add two fractions a common denominator is needed. While it is not necessarily the least
common denominator, the product of the two denominators is a common denominator.
or using f1 and f2
Look carefully at this state of memory diagram of the main method that illustrates the method plus as it is invoked on the
Fraction f1 .
Fraction sum = f1.plus(f2);
The method plus has a parameter other of type Fraction that has been passed f2 . Therefore, other stores a copy of the
reference f2 . That is, when an object is passed to a method, a reference is passed, i.e. objects are passed by
reference .
f2 f1 sum
Fraction Fraction
numerator 1 numerator 3
denominator denominator 4
6
Fraction
other numerator 22
num 22
return denominator 24
den
24
method plus
PAGE 7.3
Similarly, the second statement could be modified using the reference to the current object, this .
Notice, that even though other 's instance variables are private , the plus method has direct access to them
(other.numerator and other.denominator ) because plus is a method defined in the Fraction class.
Also, the statement
return new Fraction(num, den);
could be replaced with the two statements.
Fraction answer = new Fraction(num, den);
return answer;
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
which currently allows fractions with a negative integer in the denominator, such as -3/-2 and 4/-3, to be created.
Converting these two fractions to 3/2 and -4/3 would be preferable. This change can be made by multiplying both num
and den by -1 if den is a negative number. That is,
if(den < 0)
{
num = num * -1;
den = den * -1;
}
The braces are needed to create a block of statements that are executed if the denominator is less than ( < ) zero.
Another condition that should be checked is the possibility that the client could pass zero to den.
Since a Fraction with a denominator of zero is illegal we have two choices:
1. Change the denominator to another value, such as 1.
2. Refuse to create a new Fraction by instead throwing an illegal argument exception.
The second choice is probably preferable, but that is a topic that we are not ready to discuss.
Therefore, we will implement the first choice.
PAGE 7.4
J A V A L A B M A N U A L
false
den < 0
true
num *= -1
den *= -1
false
den == 0
true
den = 1
numerator = num;
denominator = den;
Now, add statements to the main method that create and print the fractions -3/-2, 4/-3 and 5/0 . Compile the code and
run the application. Record what is printed.
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
PAGE 7.5
S t e p 5 : Notice that if den is less than zero, it is not necessary and, therefore, it is inefficient to test if den is equal to
zero. Instead of using two if structures, an if – else structure should be used.
if(den < 0)
{
num *= -1;
den *= -1;
}
else if(den == 0)
{
den = DEFAULT_DENOMINATOR;
}
false
den < 0
true
num *= -1
den *= -1
false
den == 0
true
den = 1
numerator = num;
denominator = den;
PAGE 7.6
J A V A L A B M A N U A L
return false;
Add the equals method to the Fraction class and uncomment this code, that tests equals , in the main method.
System.out.print(sum + " and " + f1 + " are ");
if(sum.equals(f1))
System.out.println("equal");
else
System.out.println("not equal");
Compile the code and run the application. Record the results.
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
S t e p 8 : Introduce a second class constant to store the default numerator of zero. Following the previous example, write
a third constructor that has no parameters and initializes the numerator and denominator to their default values. Compile
and run the program. Record the new statements that you added and the printed result.
PAGE 7.7
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
while (b != 0) false
{ b != 0
int r = a % b;
a = b;
b = r; true
}
int r = a % b;
return a; a = b;
} b = r;
return a;
The first two lines assign the absolute values of the a and b to a and b using the Math class method.
public int abs(int n)
Next, the condition for the loop, b != 0 (b is not equal to zero) is evaluated to true or false . If true , the three
statements in the body of the loop are executed. Notice, that the local variable r is declared inside the block of statements
that is the body of the loop and, therefore, is known only inside the body of the loop. Also, notice that the value of b is
changed inside the body of the loop and, therefore, the next time the loop condition is evaluated b has stores a new value.
Using a is 24 and b is -45 , follow the code, recording the state of memory for the method in a chart.
r a b b != 0
After finding |a| and |b| and evaluating the condition 24 45 true
After the body of the loop is executed the first time 24 45 24 true
PAGE 7.8
J A V A L A B M A N U A L
Since b != 0 is false , the loop ends, and control goes to the statement following
the body of the loop.
So, the value stored in a, the least common denominator of 24 and -45, is returned.
Since the client is not expected to call this method, the method should be modified by private to restrict its use to inside
the Fraction class only. Add the method to the Fraction class.
private int gcd(int a, int b)
{
a = Math.abs(a);
b = Math.abs(b);
while (b != 0)
{
int r = a % b;
a = b;
b = r;
}
return a;
}
S t e p 9 : Follow the code of the gcd method by making a list of the variables and the values they store if the values
passed are gcd(22, 24)
To actually reduce a Fraction , we need a method that reduces the current Fraction by dividing the numerator and
denominator of this Fraction by the value returned by the gcd method. This method could be public if the client is
expected to reduce a Fraction . Or, the method could be private if every Fraction is reduced when it is created. The
second approach is the one we will take. Therefore, the method is modified by private and is called from the constructor.
Add this method to the Fraction class.
private void reduce()
{
int greatestCommonDivisor = gcd(numerator, denominator);
PAGE 7.9
A. public Fraction minus(Fraction other) returns the difference of this object and other .
Add code to main to find and print the difference of f1 and f2 and of 0 and f1 .
B. public Fraction times(Fraction other) returns the product of this object and other .
Add code to main to find and print the product of f1 and f2 , of 0 and f1 , and 5 and -2/3 .
C. public Fraction dividedBy(Fraction other) returns the quotient of this object and other . If other
equals zero, the null reference should be returned.
Add code to main to find and print the quotient of f1 and f2 , of f1 and 0 , and f1 and 5 .
D. public double toDecimal() returns the decimal equivalent of this object expressed as a double .
Add code to main to print the decimal equivalent of f1 , -3/7 and 0 .
E. public Fraction reciprocal() returns the reciprocal of this object unless this object equals zero, in which
case the null reference is returned.
Add code to main to find and print the reciprocals of f1 , f2 and 0 .
F. public boolean isLessThan(Fraction other) returns true if this object is less than other .
Add code to main to print if f1 is less than f2 , if f2 is less than f1 , and if f1 is less than f1 .
G. public boolean isGreaterThan(Fraction other) returns true if this object is less than other .
Add code to main to determine if f1 is greater than f2 , if 0 is greater than f1, and if f1 is greater than -5 .
H. Modify public String toString() so that whole number fractions are expressed without the denominator of
one. i.e. 5/1 should be expressed as 5 instead of 5/1. Add testing.
I. public String toMixedString() that returns a String representation of this object as a mixed number if the
numerator is larger than the denominator. Otherwise, the toString() representation is returned. Add testing.
2. Add code to the main testing method in the Fraction class to calculate and print each of the following.
Each calculation should be a single statement.
A. B. C.
3. Write a class Point that represents the coordinates of a point (x,y) in a two-dimensional coordinate system.
The class should also contain a main method to test each method as it is written.
Constructors:
public Point(double x, double y) initializes the two coordinates.
public Point() initializes the two coordinates to 0.
Public Methods:
PAGE 7.10
J A V A L A B M A N U A L
F. public void translate(double changeInX, double changeInY) changes the x coordinate of this
Point by changeInX and changes the y coordinate by changeInY
G. public boolean equals(Point p) returns true if this Point and p represent the same coordinates
and false otherwise.
H. public double slope(Point p) returns the slope of the line between this Point and p . If two points
have the same x value, the line is vertical and its slope is undefined. In this case you should
return the static constant NaN defined in class Double. NaN stands for Not – a – Number and is
a double value.
I. public String lineEquation(Point p) returns the equation of the line between this Point and p.
Again, a vertical line is a special case.
Suppose you have two points P (x1, y1) and Q (x2, y2)
The equation of the line between P and Q is where is the slope of the line and
. The equation of a vertical line is .
PAGE 7.11