0% found this document useful (0 votes)
8 views

Lab 07

The document describes writing a Fraction class in Java that can represent fractions and perform operations like addition and comparison. It discusses adding methods to construct Fractions, add two Fractions together, and using if/else statements in the Fraction constructor to validate denominator values.

Uploaded by

Nedal Muhammed
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

Lab 07

The document describes writing a Fraction class in Java that can represent fractions and perform operations like addition and comparison. It discusses adding methods to construct Fractions, add two Fractions together, and using if/else statements in the Fraction constructor to validate denominator values.

Uploaded by

Nedal Muhammed
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 11

J A V A L A B M A N U A L

LAB OBJECT ORIENTED PROGRAMMING IN JAVA

7 Another Utility Class


Using if-else
PURPOSE

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.

 Complete Post Lab Exercises #1 ________ and #2 _______

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

7.1 WRITING A FRACTION CLASS


Java provides the primitive types double and float to store fractional values that, when printed, are in decimal form.

Some elementary school calculators work with fractions in the form .

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

public Fraction(int num, int den)


{
numerator = num;
denominator = den;
}

public String toString()


{
return numerator + "/" + denominator;
}

//The Fraction class is meant to be a utility class, used by a client


//class.
//The main method is present for testing purposes by the author
//of the class.
//It should be commented out after the class is made available.

public static void main(String[] args)


{
Fraction f1 = new Fraction(3,4);
System.out.println(f1);
}
}
Compile and run the program. Record the results.
_____________________________________________________________________________________________

Passing and Returning Objects


To add two Fraction objects and find the sum, an instance method called plus is needed.
The method is invoked on a Fraction , the first addend.
The second addend must be passed to the method.
The sum of the addends, a Fraction is returned.
The header of the method is.
public Fraction plus(Fraction other)
the sum the second fraction
Before we write the method, let's write some statements that correctly call the plus method.
S t e p 2 : Add, to the main method, this code that finds and prints the sum of 3/4 and 1/6.
Fraction f2, sum;
f2= new Fraction(1,6);

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

The "cleanest" code that implements what is shown above is.


public Fraction plus(Fraction other)
{
int den = denominator * other.denominator;
int num = numerator * other.denominator + denominator * other.numerator;
return new Fraction(num, den);
}
The line
int den = denominator * other.denominator;
calculates the common denominator. den is a local variable that exists only during the execution of the method.
denominator is the instance variable belonging to this object, the object on which the method is invoked. Therefore,
another way to refer to denominator is this.denominator .
The above statement can be replaced with
int den = this.denominator * other.denominator;

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;

Again, the choice is yours.


S t e p 3 : Add the plus method to the Fraction class. Compile the code and run the program. Record what is printed.

_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________

7.2 USING THE SELECTION STATEMENTS IF AND IF – ELSE


A selection statement allows a choice to be made as to which statements will be executed based on some condition. A
selection statement can be used to improve the constructor of the Fraction class,
public Fraction(int num, int den)
{
numerator = num;
denominator = den;
}

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

S t e p 4 : Add a class constant to the Fraction class.


public static final int DEFAULT_DENOMINATOR = 1;
and then modify the constructor to
public Fraction(int num, int den)
{
if(den < 0)
{
num *= -1;
den *= -1;
}
if(den == 0)
{ Note: These braces are optional since the body of
den = DEFAULT_DENOMINATOR; the if contains only a single statement.
}
numerator = num;
denominator = den;
}

A flow chart for this code is.

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

What does this do to the flow chart on the previous page?


A flow chart for this code is

false
den < 0

true

num *= -1
den *= -1

false
den == 0

true

den = 1

numerator = num;
denominator = den;

Make this change to the constructor.


Compile and run the program.
S t e p 6 : An if – else structure is also needed in an equal’s method for the Fraction class.
Two fractions are equal if the results of cross multiplying are equal.

That is . One version of equals is.

public boolean equals(Fraction other)


{
if(numerator * other.denominator == other.numerator * denominator)
return true;
else

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

System.out.print(sum + " and 11/12 are " );


if(sum.equals(new Fraction(11,12)))
System.out.println("equal");
else
System.out.println("not equal");

Compile the code and run the application. Record the results.

_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________

7.3 ANOTHER USE FOR THE RESERVED WORD THIS


In most cases, there is more than one constructor for an object. Generally, the constructor that initializes the most data
members does all the work and the other constructors call this constructor. Consider a second constructor that is passed
only the numerator and constructs a Fraction that is a whole number.

public Fraction(int num)


{
this(num, DEFAULT_DENOMINATOR);
}
The single statement calls another constructor for this object that has two formal parameters of type int, passing num and 1
as the numerator and denominator.
S t e p 7 : Add the new constructor to the Fraction class and statements that call the constructor and print the new
Fraction . Compile and run the program. Record the new statements that you added and the printed result.

_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________

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

7.4 REDUCING A FRACTION


To reduce a Fraction, the numerator and denominator are each divided by their greatest common divisor, which at least is
one. A method to find the greatest common divisor of two integer values uses a loop. In class and in previous labs, you
have been introduced to the while loop. Understanding the mathematical algorithm that this method uses in not needed.
However, you should be able to follow the code.
A flowchart is shown to help you follow the code.

int gcd(int a, int b) a = Math.abs(a);


{ b = Math.abs(b);
a = Math.abs(a);
b = Math.abs(b);

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

a and b have been passed 24 and -45 24 -45

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

" The second time 21 24 21 true

PAGE 7.8
J A V A L A B M A N U A L

" The third time 3 21 3 true

" The fourth time 0 3 0 false

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

numerator = numerator / greatestCommonDivisor;


denominator /= greatestCommonDivisor;
}
To call the reduce method from the constructor, add the statement.
reduce();
as the last statement in the constructor Fraction(int, int).
Compile the code and run the application. Record any changes that you notice in the output of the program.
_____________________________________________________________________________________________
_____________________________________________________________________________________________
_____________________________________________________________________________________________

7.5 POST-LABORATORY EXERCISES


1. Modify the Fraction class by modifying or adding some or all the following methods.
For each method add code to the main method that tests it.

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.

D a t a M e m b e r s : Two private variables of type double representing the x and y coordinates.

Constructors:
public Point(double x, double y) initializes the two coordinates.
public Point() initializes the two coordinates to 0.

Public Methods:

A. public String toString() returns a String representation "(x, y)"


B. Accessor and mutator methods for both instance variables.
C. public double distanceBetween(Point p) returns the distance between this Point and Point p
D. public double distanceToOrigin() returns the distance between this Point and (0,0)
E. public Point midpoint(Point p) returns the midpoint between this Point and Point p

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)

 Then the distance between P and Q is

 The midpoint between P and Q is

 The slope of the line between P and Q is

 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

You might also like