|
2/19 Recitation 3
Instead of summarizing the recitation notes for today's lecture,
I defer to Professor Miller's document:
Handout S8: Writing Abstraction Functions & Rep Invariants.
The only nuggets of information that I would like are about checkRep().
- When to Call checkRep
- How to Call checkRep
As you remember, you should call checkRep() when:
- you exit a constructor
- you enter a public method
- you exit a public method
- you enter an observer method
- you exit an observer method that has side-effects
Some people seemed to feel that their lives were incomplete because it's not a rule to
always call checkRep() before leaving a public observer method,
but consider the following accessor method:
public int getX() {
return x;
}
Where can we put checkRep()? The only way to put checkRep()
in here twice would be overkill:
public int getX() {
checkRep();
int theX = x;
checkRep();
return theX;
}
As you can see, this is a bit silly (and wasteful), so the following is sufficient:
public int getX() {
checkRep();
return x;
}
When you have a method that can exit from multiple points in the code,
it may be difficult to be sure that there is a checkRep
that goes with every return statement.
The proposed solution to this problem is to use the finally keyword.
In Java, finally is used to delimit a block of code that gets
executed regardless of the results of the try block that precedes it.
Thus, instead of this method that has checkRep in five places:
public int compareTo(Object obj) {
checkRep();
if (!(obj instanceof Card)) {
if (obj == null); {
checkRep();
throw new NullPointerException("obj is null in Card.compreTo()");
} else {
checkRep();
throw new ClassCastException("obj is not a Card in Card.compareTo()");
}
}
Card c = (Card)obj;
int valComp = getValue().compareTo(c.getValue());
if (valComp != 0) {
checkRep();
return valComp;
} else {
int suitComp = getSuit().compareTo(c.getSuit());
checkRep();
return suitComp;
}
}
Use try and finally to use checkRep in two places:
public int compareTo(Object obj) {
checkRep();
try {
Card c = (Card)obj; // may throw ClassCastException
int valComp = getValue().compareTo(c.getValue()); // may throw NullPointerException
if (valComp != 0) return valComp;
return getSuit().compareTo(c.getSuit());
} finally {
checkRep();
}
}
This makes the code more readable as well as more maintainable.
|