Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!rutgers!cs.utexas.edu!mailrus!cornell!wilk From: wilk@svax.cs.cornell.edu (Michael Wilk) Newsgroups: comp.object Subject: Subclassing vs. subtyping Message-ID: <33009@cornell.UUCP> Date: 9 Oct 89 15:17:00 GMT Sender: nobody@cornell.UUCP Reply-To: wilk@cs.cornell.edu (Michael Wilk) Distribution: comp Organization: Cornell Univ. CS Dept, Ithaca NY Lines: 93 Several times at OOPSLA I heard references to the issue of "subtyping" versus "subclassing." This issue ties in with the concept of inheritance and the concept of classes as sets. Below is my understanding of this issue based on what I heard at the conference. I do not claim to be an authority, so please correct me where I am wrong. A "class" serves at least two purposes: the (usually run-time) generation of "instances" and the (usually compile-time) genera- tion of "subclasses." If we think of classes as sets, then instances of that class refer to members of that set. The meaning of a subclass is more subtle. In Smalltalk and CLOS (and probably others) a subclass represents a set of objects that are extensions of objects in the original class: they have the same instance variables and methods, and additional instance variables and methods can be added. This seems to me a programming construct that has no semantic correlation to anything outside of programming. Let us consider an example below. A rectangle is what you think it is; a venetian blind is a rectangular geometric figure with additional horizontal lines. Class RECTANGLE Instance variables HEIGHT, WIDTH Methods HEIGHTEN, WIDEN, AREA Class VENETIAN-BLIND Inherit from RECTANGLE Instance variables NUMBER-OF-SLATS (with HEIGHT and WIDTH inherited) Methods CHANGE-NUMBER-OF-SLATS (with HEIGHTEN, WIDEN, and AREA inherited) In standard object-oriented languages, VENETIAN-BLIND is a subclass of RECTANGLE, so that all VENETIAN-BLINDS are RECTANGLES. But ask any high school mathematics teacher if all such shapes are rectangles and you'll hear a clear "No." In fact, it is quite the opposite: VENETIAN-BLIND is the more general class, as we have a rectangle whenever NUMBER-OF-SLATS equals one! The point to remember is that a rectangle consists of four sides *and nothing more*. One way to resolve this is to say that RECTANGLEs are not the quadrilaterals we normally think of, but include any extensions so long as its methods are supported in the subclasses. Thus, we should replace the name RECTANGLE with something like RECTANGULAR-THING and have two subclasses: VENETIAN-BLIND and RECTANGLE (or perhaps STRICT-RECTANGLE) where the latter is indeed the simple geometric figure without extensions. But there's nothing to insist that a programmer adopt this regimen; subclassing simply doesn't enforce it. What is more, RECTANGULAR-THING cannot generate instances of every object in the set of objects it represents; it can generate a STRICT- RECTANGLE but not a VENETIAN-BLIND. I believe C++ deals with this by calling RECTANGULAR-THING an "abstract" class and forbidding it from generating any instances at all. This is an understandable but unsatisfactory solution. Let us now try to use subclassing to create a class that repre- sents a restricted form of an existing class. Class RECTANGLE Instance variables HEIGHT, WIDTH Methods HEIGHTEN, WIDEN, AREA Class SQUARE Inherit from RECTANGLE ? Instance variables SIDE-LENGTH Methods SCALE, AREA What happened to inheritance? It was useless! Since SQUARE is more restricted than RECTANGLE we need *fewer* instance variables, not *more* as subclassing allows. And the HEIGHTEN and WIDEN methods that applied to RECTANGLEs make sense only if we allow squares to be automatically transformed into rectangles. It seems best to compose the class SQUARE without any references to the class RECTANGLE; thus, any relationship between squares and rectangles is only in the mind of the programmer. Perhaps that is enough? My conclusion is that subclassing is a tool for code re-use and does not conform to our intuitive understanding of types as sets and subtypes as subsets, making it difficult to design classes at a conceptual level before actual programming. If I am incorrect then I would appreciate a re-education. Please include references to published books or articles as I am putting together a paper and will need to make the appropriate citations. Michael Wilk (wilk@cs.cornell.edu)