/** *********************************************************
* Fraction implements a Fraction ADT.
* Integrity Constraint: The object's value is the
* correct value of the last fraction Stored or computed.
* From Java lecture
* @author Jeff Offutt
* @version 1.2, 1/99
* @version 1.3, 10/01
* Added clone() and Object test.
********************************************************* **/
public class Fraction
{
// Class variables
private static int CurNumFracs = 0;
/////////////////////////////////////////////////////////////
// Instance variables. //
/////////////////////////////////////////////////////////////
private int Numerator = 0;
private int Denominator = 5;
// Class methods
/** *********************************************************
* Class Method : Returns the current number of fractions
* pre: null
* post: null
* @param None
* @return An integer, the current number of fractions
********************************************************* **/
public static int GetNumFracs ()
{
return (CurNumFracs);
}
// Public constructor methods ///////////////////////////////
/** *********************************************************
* Constructor : Sets fraction to 0/1
* pre: null
* post: fraction's value is 0/1; number of fractions is incremented
* @param None
* @return None
********************************************************* **/
public Fraction () //constructor
{
Numerator = 0;
Denominator = 1;
CurNumFracs++;
}
/** *********************************************************
* Constructor : Initialize a new fraction with supplied values
* pre: Den is not 0
* post: fraction's value is Num/Den; number of fractions is incremented
* @param Num Integer numerator
* @param Den Integer denominator
* @return None
********************************************************* **/
public Fraction (int Num, int Den) //constructor
{
Numerator = Num;
Denominator = Den;
CurNumFracs++;
}
/** *********************************************************
* Constructor : Only initializes if Init==true
* pre:
* post:
* @param Init
* @return None
********************************************************* **/
public Fraction (boolean Init) //constructor
{
if (Init)
{
Numerator = 0;
Denominator = 1;
}
CurNumFracs++;
}
// Public mutator methods ///////////////////////////////////
/** *********************************************************
* Mutator : Adds two fractions, F1 = F1+F2
* pre: Both denominators must be the same
* (checked with the exception ArithmeticException)
* post: Object's value is old-value+Right
* @param Right Fraction right-hand-side
* @return None
********************************************************* **/
public void Add (Fraction Right)
{
try
{
Numerator = Numerator + Right.Numerator;
if (Denominator != Right.Denominator)
throw new ArithmeticException ();
}
catch (ArithmeticException e)
{
System.out.println ("Fraction add error: Denominators must be the same.");
}
}
/** *********************************************************
* Mutator : Multiplies two fractions, F1 = F1*F2
* pre: null
* post: Object's value is old-value*Right
* @param Right Fraction right-hand-side
* @return None
********************************************************* **/
public void Multiply (Fraction Right)
{
Numerator = Numerator * Right.Numerator;
Denominator = Denominator * Right.Denominator;
}
// Public accessor methods //////////////////////////////////
/** *********************************************************
* Accessor : Compares two fractions for equality
* pre: null
* post: null
* @param Right Fraction right-hand-side
* @return boolean (F1 == F2)
********************************************************* **/
public boolean equals (Object Right)
{
if (!(Right instanceof Fraction))
return (false);
Fraction rhs = (Fraction) Right;
if (Numerator == rhs.Numerator && Denominator == rhs.Denominator)
return (true);
else
return (false);
}
/** *********************************************************
* Accessor : Copies current Fraction to a new version
* pre: null
* post: null
* @param None
* @return A new Fraction that equals the current one
********************************************************* **/
public Object clone ()
{
Fraction newf = new Fraction ();
newf.Numerator = Numerator;
newf.Denominator = Denominator;
return (newf); // implicit "assign up" to Object
}
/** *********************************************************
* Accessor : Prints a fraction using println
* pre: null
* post: Fraction is printed
* @param None
* @return None
********************************************************* **/
public void PrintFrac ()
{
System.out.println (Numerator + " / " + Denominator);
}
/** *********************************************************
* Accessor : Converts a fraction to a string for println
* pre: null
* post: null
* @param None
* @return String representation of the value is returned
********************************************************* **/
public String toString ()
{
return (Numerator + " / " + Denominator);
}
/** *********************************************************
* Main program function, tests the ADT class
* @param None
* @return None
********************************************************* **/
public static void main (String argv[])
{
Fraction f1, f2, f3, f4, f5;
System.out.print ("\nTesting class members ...\n");
System.out.println ("Instances: " + Fraction.GetNumFracs ());
f1 = new Fraction (1, 2);
f2 = new Fraction (3, 4);
f3 = new Fraction (2, 4);
f4 = new Fraction ();
System.out.println ("Instances: " + Fraction.GetNumFracs ());
System.out.print ("\nTesting current values ...\n");
System.out.print ("f1: ");
f1.PrintFrac ();
System.out.print ("f2: ");
f2.PrintFrac ();
System.out.print ("f3: ");
f3.PrintFrac ();
System.out.print ("f4: ");
f4.PrintFrac ();
System.out.print ("\nTesting Add() and Multiply() ...\n");
f2.Add (f3);
System.out.print ("f2: ");
f2.PrintFrac ();
f1.Multiply (f3);
System.out.print ("f1: ");
f1.PrintFrac ();
System.out.println ("Instances: " + Fraction.GetNumFracs ());
System.out.print ("f1: ");
System.out.println (f1); // Implicit call to f1.toString()
System.out.print ("\nTesting equals() and == ...\n");
f5 = new Fraction (2, 4);
System.out.print ("f5: ");
System.out.println (f5);
if (f3 == f5)
System.out.println ("f3 and f5 are the same.");
else
System.out.println ("f3 and f5 are not the same.");
if (f3.equals (f5))
System.out.println ("f3 and f5 have the same values.");
else
System.out.println ("f3 and f5 do not have the same values.");
if (f4.equals (f5))
System.out.println ("f4 and f5 have the same values.");
else
System.out.println ("f4 and f5 do not have the same values.");
f1.Add (f5);
System.out.print ("f1: ");
f1.PrintFrac ();
// Test clone()
System.out.print ("\nTesting clone() ...\n");
Fraction fclone1, fclone2;
fclone1 = new Fraction (6, 7);
fclone2 = (Fraction) fclone1.clone();
if (fclone1.equals (fclone2))
System.out.println ("fclone1 and fclone2 have the same values.");
else
System.out.println ("fclone1 and fclone2 do not have the same values.");
System.out.println ("fclone2: " + fclone2);
///// October, 2001, 432
// Checking inheritance rules.
System.out.print ("\nTesting inheritance ...\n");
Object o;
Fraction fobj1 = new Fraction (2, 4);
Fraction fobj2 = new Fraction (1, 4);
o = fobj1; // Assign up
// This does not work because there is no Add() for objects of type Object
// o.Add (fobj2); // Compile error
// This works because there is a toString() defined for Object,
// but the rules of inheritance says that if we overload a method,
// the lowest possible version is run (in this case, Fraction's toString() ).
System.out.println ("Value of o: " + o);
// Checking initialization
System.out.print ("\nTesting Initialization ...\n");
Fraction finit1 = new Fraction (false);
Fraction finit2 = new Fraction ();
System.out.println ("Value of finit1: " + finit1);
System.out.println ("Value of finit2: " + finit2);
} // end main
} // End Fraction