Intro to Specifications
A specification describes, at an abstract level, how a method (procedure) or class behaves. Chapters 3 and 5 of the Liskov text describe method and class specifications in detail; this document gives a small amount of intuition and outlines the differences between the Liskov notation and the 6.170 notation.
Class Specifications
Class specifications describe an abstract view of the contents and behavior of a class.
Specification Fields
Much the same way a class implementation lists actual (concrete) fields of a class, a class specification lists "specification fields" of the class. (Specification fields are more commonly called "abstract fields", but "abstract" has another meaning in Java, so we will avoid that terminology.) Specifications always refer only to specification fields, never to concrete fields. Concrete fields depend on a particular implementation, so we don't want to expose them in a specification, which can be implemented in many different ways.
By convention, in specification fields, lowercase types like "sequence" refer to mathematical entities. Primitive Java types like "float" are also specified in lower case. Capitalized types refer to Java classes.
The presence of a specification field does not imply anything about the interface or implementation of the class. The interface may not provide methods to query the specification field's state, so clients of the class may not have access to the information stored in the specification field. Likewise, the implementation may not actually have a concrete field of the specification field's type, since that information may be computed from multiple concerete fields, or it may not be available at all. The point is that specification fields are a convenience for use in specifications.
Method Specifications
Method specifications describe the behavior of a procedure in terms of its preconditions and postconditions. Note that method specifcations may only refer to specification fields, method arguments, and global variables, never to concrete fields of the implementation.
Preconditions
Preconditions are properties that must be true when the method is called. It is the responsibility of the caller to guarantee that these properties hold. If the preconditions do not hold, the method is allowed to behave in absolutely any fashion, including crashing the program, continuing with incorrect results, informing the user of the problem, or gracefully recovering from the problem. Callers should always assume that preconditions are not checked by a method. However, it is good practice -- though not required -- for a method to check its preconditions (if the check can be performed efficiently) and throw an error if they are not satisfied. (In 6.170, how you handle unsatisfied preconditions will not affect your grade.)
Preconditions are indicated by the "requires" clause in a method specification. If a "requires" clause is omitted from the method specification, it is assumed that the method does not have any preconditions.
Postconditions
Postconditions are properties that a method guarantees will hold when the method exits. If the precondition did not hold when the method was called, then all bets are off, and the method may behave in any fashion whatsoever. In particular, if the precondition does not hold upon method entry, then the postcondition need not hold on method exit.
A postcondition can be written as a single complex logical formula, but it is convenient to separate it into logically distinct parts. The Liskov text uses "effects" and "modifies"; 6.170 uses "returns", "effects", "throws", and "modifies". (The the descriptions below, "default" refers to what is assumed if that clause is ommitted from the method specification.)
returns (default: no constraint on what is returned)
the value returned by the method, if any.
effects (default: true, which means "can have any effect")
the side effects of the method, such as changes to the state of the current object or an object passed in via an argument.
throws (default: none, which means that no exceptions are ever thrown)
the exceptions that may be raised, and under which conditions.
modifies (default: nothing, which means that there are no side effects)
values that may be modified by the procedure. They are not guaranteed to be modified, unless otherwise indicated by the effects clause. For instance, if a specification field is listed in the modifies clause but not in the effects clause, then it may take on any value allowed by the abstract invariants of this class of objects.
If object x has specification fields f, g, and h, then "modifies x" means that any combination of x.f, x.g, and x.h might be modified. "modifies x.g, x.h" would be more restrictive.
Often, programmers are more interested in quantities that are not listed in the modifies clause, since they are guaranteed not to be changed by the method.
By convention, the Javadoc tags for method specifications appear in the following order: requires, modifies, throws, effects, returns.
Top