Daily Exercise 16:
Calculator

Prof. Kesden wrote a daily exercise covering today's topic and I decided to use it as well. You can find it here.

Although we're trying to cover the same material, we don't always cover it in exactly the same way. So, before jumping into the problem, let me address two ideas that are assumed in exercise 16: throwing exceptions and a menu class

Throwing Exceptions:

My focus on exceptions was to catch naturally occuring exceptions. On the other hand, it is possible to throw exceptions ourselves. We may have cause to do this when we are writing general methods (say, for a class we are creating). In some circumstances, the input parameters given to one of the methods that we write don't make sense. From within the class being created, we don't know how to handle the problem, so we throw (or raise) an exception should this occur.

Recall the Fraction class that we worked with a few weeks ago. In particular, there were two methods (a constructor and a mutator) which gave us problems. I'll repeat that code here.

public Fraction (int numerator, int denom) {
this.numerator = numerator;
if (denom != 0)
denominator = denom;
else
// if someone tried to construct a fraction with a zero denominator,
// this is truly an error. The correct approach will be to
// throw an exception but we haven't learned how yet
denominator = 1;
}

public void setDenominator(int toValue) {
if (toValue != 0)
denominator = toValue;
}

As originally stated in both methods, the correct approach to addressing someone who tries to set a denominator to zero is to throw an exception. We can do this in two different ways. Use a pre-existing Exception class or create one of our own.

In the first way (discussed on pp. 558-559 of the text), we can throw a new object of a pre-existing exception class. The class ArithmeticException is used by the Java compiler whenever there is a division by zero. We could rewrite the above methods as follows (I'll leave the second to you):

public Fraction (int numerator, int denom) {
this.numerator = numerator;
if (denom == 0)
throw new ArithmeticException("Attempted to create a fraction with zero denominator");
denominator = denom;
}

However,  the exception that we threw was not exactly an Arithmetic exception (because we weren't trying to do arithmetic).  In the second way, (discussed on p. 565 of the text) we define a new exception class nexted within the fraction class. Such an exception class is just like a variable or a method of the fraction class and it is called a nested class. The following class for exceptions could be put anywhere within the Fraction class.

public class IllegalFractionException extends Exception {

public IllegalFractionException () {}
public IllegalFractionException (String reason) {
super(reason);
}
}

I haven't discussed the purpose of "extends Exception" or of  "super(reason);" yet, but they have to do with inheritance. To create exception classes of our own, we need to inherit the general properties of the Exception class.

We would use this new exception class in much the same way as we did with ArithmeticException. This time I'll rewrite the second method:

public void setDenominator(int toValue) {
if (toValue == 0)
throw new IllegalFractionException
("Attempted to set the denominator of " + this + " to zero.");
denominator = toValue;
}