I have been challenged by @nhgrif to write a Fraction class to better my understanding of OOP. I have found an interesting challenge here (I apologize that the source is not mentioned, I was not able to find it either).
Problem statement: Create a class named Fraction having two integer data members named for a fraction's numerator and denominator. The class' default constructor should provide both data members with default values of 1 if no explicit initialization is provided. The constructor must also prohibit a 0 denominator value. Include member functions for displaying an object's data values and mathematical functions capable of adding, subtracting, multiplying, and dividing two Fraction objects.
I have written this on Ideone.com hence explaining why everything is in one file. I have made a slight change to the default values given no parameters, as I have been told a 0/1
default fraction makes more sense than 1/1
.
I have also added a simple but potentially useful method to cast a fraction into its decimal value.
I named my fraction variables using a pattern like fractionN_D
where N is numerator and D is denominator. It seemed short enough to be practical (as compared to fractionThreeFourths
) while still carrying meaning. Any suggestion on that is of course welcome.
class Fraction {
private final int numerator;
private final int denominator;
Fraction() {
numerator = 0;
denominator = 1;
}
Fraction (int numerator, int denominator) {
this.numerator = numerator;
if (denominator == 0) {
throw new IllegalArgumentException("Denominator cannot be zero.");
} else {
this.denominator = denominator;
}
}
public String getFraction() {
return numerator + "/" + denominator;
}
public double getFractionDecimal() {
return ((double) numerator) / denominator;
}
// Mathematical functions
public String addFraction(Fraction otherFraction) {
// Sum formula: a/b + c/d = (ad + cb)/bd
int a = this.numerator;
int b = this.denominator;
int c = otherFraction.numerator;
int d = otherFraction.denominator;
return ((a*d) + (c*b)) + "/" + (b*d);
}
public String subtractFraction(Fraction otherFraction) {
// Subtraction formula: a/b - c/d = (ad - cb)/bd
int a = this.numerator;
int b = this.denominator;
int c = otherFraction.numerator;
int d = otherFraction.denominator;
return ((a*d) - (c*b)) + "/" + (b*d);
}
public String multiplyByFraction(Fraction otherFraction) {
// Multiplication formula: a/b * c/d = ac/bd
int a = this.numerator;
int b = this.denominator;
int c = otherFraction.numerator;
int d = otherFraction.denominator;
return (a*c) + "/" + (b*d);
}
public String divideByFraction(Fraction otherFraction) {
// Division formula: (a/b) / (c/d) = ad/bc
int a = this.numerator;
int b = this.denominator;
int c = otherFraction.numerator;
int d = otherFraction.denominator;
return (a*d) + "/" + (b*c);
}
}
class TestFraction {
public static void main(String[] args) {
Fraction fraction3_4 = new Fraction(3,4);
Fraction fraction2_3 = new Fraction(2,3);
System.out.println("F1: " + fraction3_4.getFraction() + " Dec: " + fraction3_4.getFractionDecimal());
System.out.println("F2: " + fraction2_3.getFraction() + " Dec: " + fraction2_3.getFractionDecimal() + "\n");
System.out.println("F1 + F2: " + fraction3_4.addFraction(fraction2_3));
System.out.println("F2 + F1: " + fraction2_3.addFraction(fraction3_4) + "\n");
System.out.println("F1 - F2: " + fraction3_4.subtractFraction(fraction2_3));
System.out.println("F2 - F1: " + fraction2_3.subtractFraction(fraction3_4) + "\n");
System.out.println("F1 * F2: " + fraction3_4.multiplyByFraction(fraction2_3));
System.out.println("F2 * F1: " + fraction2_3.multiplyByFraction(fraction3_4) + "\n");
System.out.println("F1 / F2: " + fraction3_4.divideByFraction(fraction2_3));
System.out.println("F2 / F1: " + fraction2_3.divideByFraction(fraction3_4));
}
}
The output of the above program is as follows:
F1: 3/4 Dec: 0.75 F2: 2/3 Dec: 0.6666666666666666 F1 + F2: 17/12 F2 + F1: 17/12 F1 - F2: 1/12 F2 - F1: -1/12 F1 * F2: 6/12 F2 * F1: 6/12 F1 / F2: 9/8 F2 / F1: 8/9
1/1
as default is that this is the identity value for multiplication/division. It also avoids one vector by which a fraction produces divide by zero errors as a component of other divisions. \$\endgroup\$ – ben rudgers Mar 5 '15 at 2:42