Next: Summary. Up: Fraction class example. Previous: Design.


Coding

Textbook: Section 3.8

Remember that a class definition is a grouping of four possible types of definitions: class variable definitions, instance variable definitions, instance method definitions, and class method definitions. (That's the order I typically would write them, too.)

Now we'll write our class. We begin by putting in our instance variables.

import csbsju.cs160.*;

public class Fraction {
    private int num;
    private int den;
    
    // ... rest of stuff will go here
}
We're defining two instance variables, called num and den. Both should be fractions.

Now we'll add our constructor method, which takes two parameters specifying the numerator and denominator.

    public Fraction(int numerator, int denominator) {
        num = numerator;
        den = denominator;
    }
This is a good first shot, but it isn't entirely accurate: We decided to remember fractions in lowest form, and the two parameters passed in won't necessarily be in lowest form yet. To do this, we'll want to compute the GCD of the numerator and denominator, and divide both numbers by the GCD.

To help compute the GCD, we'll add a new method. We don't technically need to define this method, but it helps makes things clearer to have this additional method. This method is a static method (since it doesn't operate directly on a fraction), and it's a private method (since it doesn't really belong in the Fraction class.

    public Fraction(int numerator, int denominator) {
        if(denominator < 0) {
            numerator *= -1;
            denominator *= -1;
        }

        int div = gcd(numerator, denominator);
        num = numerator / div;
        den = denominator / div;
    }

    private static int gcd(int a, int b) {
        while(b != 0) {
            int r = a % b;
            a = b;
            b = r;
        }
        return a;
    }

The first method is simply to convert a fraction into its closest double approximation. This will be a matter of performing the division - but we'll need to be careful to do double division, not integer division.

    public double doubleValue() {
        return (num + 0.0) / den;
    }

Now we'll do the arithmetic methods. For the add method, we employ the following equation.

 a     c    ad + bc
--- + --- = -------
 b     d       bd
The add() method will just be a straightforward translation of this equation.
    public Fraction add(Fraction other) {
        return new Fraction(num * other.den + den * other.num,
            den * other.den);
    }
The multiply() method is even simpler.
    public Fraction multiply(Fraction other) {
        return new Fraction(num * other.num, den * other.den);
    }
I'm not showing you subtraction and division, but they're simple modifications of the above.

Now we want to define the compareTo() method. To do this, we observe that comparing a/b to c/d is the same as comparing a*d to b*c (assuming b and d are positive, something that we ensured in the creation of the Fraction).

    public int compareTo(Fraction other) {
        // first check if they are equal
        if(num == other.num && den == other.den) return 0;

        // otherwise see which is less
        int first = num * other.den;
        int second = other.num * den;
        if(first < second) return -1;
        else return 1;
    }

The next method we need is the toString() method.

    public String toString() {
        if(den == 1) {
            return "" + num;
        } else {
            return num + "/" + den;
        }
    }

That leaves the parseFraction class method. This is a class method since it isn't something we'd want to do on a particular Fraction object - it's just something we might reasonably ask the Fraction class to do for us.

    public static Fraction parseFraction(String str) {
        int numer; // numerator of new fraction
        int denom; // denominator of new fraction

        int slash = str.indexOf("/");
        if(slash < 0) { // the string contains only an integer
            numer = Integer.parseInt(str);
            denom = 1;
        } else {
            numer = Integer.parseInt(str.substring(0, slash));
            denom = Integer.parseInt(str.substring(slash + 1));
        }

        return new Fraction(numer, denom);
    }


Next: Summary. Up: Fraction class example. Previous: Design.