Skip to main content

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.