Java Reference
In-Depth Information
For example, if the client adds 45 minutes to a time span of 1 hour and 30 minutes,
the result will be 1 hour and 75 minutes.
We decided that we wanted every TimeSpan object to store only valid numbers of
minutes between 0 and 59. We wrote code in our constructor to ensure that this
would be true of each object's initial state, but really we want to ensure that the con-
dition is true for every object throughout its entire lifespan, not just when it is ini-
tially created. Such a property that is true of every object of a class is called a class
invariant.
Class Invariant
An assertion about an object's state that is true for the lifetime of that
object.
Class invariants are related to preconditions, postconditions, and assertions, as pre-
sented in Chapters 4 and 5. We cannot allow any mutator method such as add to
break the invariants we have decided upon; a class invariant should be treated as an
implicit postcondition of every method in the class. Enforcing an invariant may cause
you to add preconditions to the constructors and mutator methods of your class.
We can write code at the end of the add method to deal with invalid numbers of
minutes and hours. First we want the program to throw an exception if the hours or
minutes that are passed are negative. We will also make sure that we convert each
group of 60 minutes into an hour. The following code implements the behavior:
public void add(int hours, int minutes) {
if (hours < 0 || minutes < 0) {
throw new IllegalArgumentException();
}
this.hours += hours;
this.minutes += minutes;
// converts each 60 minutes into one hour
this.hours += this.minutes / 60;
this.minutes = this.minutes % 60;
}
The code now enforces its invariant in two places: the constructor and add . It
would be preferable to solve this problem in one place rather than redundantly check-
ing for it throughout the class. A more elegant solution is to have the constructor ini-
tialize the fields to 0 and then call the add method, which performs the necessary
invariant checks and stores the values of hours and minutes :
public TimeSpan(int hours, int minutes) {
this.hours = 0;
this.minutes = 0;
add(hours, minutes);
}
 
Search WWH ::




Custom Search