CSE 331: Subtyping
Java lets a method written for one type be handed an object of
another: B is a Java subtype of A when the compiler accepts a
B where an A is expected, which it does when B reaches A by a
chain of extends and implements. Writing extends grants two
things at once, inheritance, the subclass having the superclass's
fields and methods without writing them out, and Java subtyping.
Neither says whether a client reasoned about against A's
specification is still right when a B arrives. That takes a
behavioral subtype: every object that satisfies B's
specification also satisfies A's, so each method they share has
a specification in B at least as strong. The compiler checks only
the return type and the checked exceptions of an override, and
nothing in the Javadoc, so the rule is the programmer's: declare
only behavioral subtypes. A Square that extends a mutable
Rectangle breaks it, since its setWidth cannot keep Rectangle's
promise that the height is unchanged; immutable shapes or
composition keep the reuse without the broken promise.