Two terms that are often confused are ''subtyping'' and ''subclassing''. This confusion is unsurprising, as many languages (CeePlusPlus, JavaLanguage, etc.) equate the two (more or less) - in C++, the only way to create a subtype is through subclassing. As a result, many ObjectOriented texts also treat them as equivalent or gloss over the differences. But they are two different concepts, neither of which need imply the other. In short, ''subtyping'' is a mathematical concept having to do with substitutability, whereas ''subclassing'' is a type construction method found in most ObjectOrientedLanguage''''''s (if not all). '''Subtyping''' Subtyping is a ''mathematical'' relationship, ultimately related to sets. It is convenient to define a type as a set of possible ''values'' or ''states'' that an object may assume (for mutable objects, the object may transition between any value or state in the set; though not necessarily so). A subtype is, in this view, a subset and a proper subtype is a proper subset. This is known as SemanticSubtyping. This explanation is an oversimplification, but it will do. Most modern OO languages use ''SyntacticSubtyping'', where types and subtypes are specified by construction. Syntactic subtyping is less powerful than semantic subtyping in that some types are difficult or impossible to create (depending on the features of the specific language). However, it's much easier to implement, and less likely to diverge. Syntactic subtyping also avoids many paradox issues that plague set-theoretic approaches - metaclasses and the like are difficult to model in SemanticSubtyping. Some languages use a weaker approach still - ''nominative subtyping'', wherein type/subtype relationships have to be explicitly declared, e.g., with ''extends'' clauses. CeePlusPlus and JavaLanguage are in this camp. Other languages provide ''structural subtyping'', commonly known as DuckTyping, in which the subtype relationship is determined by feature comparison. (SmalltalkLanguage is in this category). However, all syntactic approaches still uphold the fundamental relationship of subtypes - they correspond to subsets. Substitutability still applies (up to a point; any language can allow a derived class method to do something nasty and predictable like dump core; no typechecker can deal with this). Some of you may be asking "what about abstract base classes, or interfaces? Those don't have instances! How can a non-empty set be a subtype of the empty set?" Stay tuned. '''Subclassing''' Subclassing (also known as ''inheritance'') is a method of class/object construction, wherein portions of one class or object are ''copied'' into another (with some of the copied features possibly being modified, or ''overridden'', in the new class). In many languages, this technique is equivalent to subtyping - if class B inherits from class A, then by definition B is a subtype of the type A. Conversely, many languages don't provide any other means of creating subtypes other than subclassing. Languages in this camp include CeePlusPlus, JavaLanguage, and EiffelLanguage (though C++ does provide PrivateInheritance, which creates subclasses without subtyping - this feature is rarely used. Implementation of a JavaInterface is considered subclassing for this discussion). There are many other ways of forming subtypes found in various languages: * ''DuckTyping'', mentioned above. Simply create a new type that has the same features of some existing type; the language will consider it a subtype. * ''Restriction''. A form of subtyping that obeys LiskovSubstitutionPrinciple; a predicate is applied to some type and only those values that satisfy the predicate are considered members of the subtype. In languages that support type invariants, this corresponds to strengthening the invariant. PascalLanguage subranges are a primitive form of this. * ''Delegation''. Often suggested as an alternative to inheritance (see WhatIsDelegation; or go to http://www.c2.com/cgi/wiki?search=Delegation for a better list); any feature not found in the current object/class is delegated to another. * ''Type algebra''. A generalization of all of the above. In some languages, one can introduce new ''supertypes'' by the type union operator, or DuckTyping again (this time specifying fewer features). At any rate... in languages where subtyping and subclassing are equivalent, there still is an important difference between the two. Suppose I have a base class Base, and two derived classes Derived1 and Derived2. (Assume Base has no other subclasses, direct or indirect - we're discussing nominatively typed languages like CeePlusPlus or JavaLanguage). There are several sets we can consider. 1 The set corresponding to all (possible) objects of class Base - those objects that are created by a call to "new Base" in C++ or Java. If Base is abstract, this is empty; otherwise it may contain some elements. 2 The sets corresponding to all possible objects of class Derived1 and Derived2. These two sets are disjoint from each other, and are also disjoint from the set of elements in class Base. 3 The sets corresponding to all possibly objects of ''type'' Base. This set is the ''union'' of all sets in 1 and 2 above; if other subclasses of Base were to be created, their members would be ''added'' to this set. Notice that this set is ''larger'' than the set of objects of ''class'' Base. 4 The sets corresponding to all possible objects of ''type'' Derived1 and Derived2. Since Derived1 and Derived2 are leaf classes; these two sets are the same as the class sets described in 2 above; that would not be true any more if Derived1 or Derived2 were further subclassed. So... to answer the question posed above... the set of all objects of a type ''is'' a superset of the set of all objects of its subtypes, but the set of all objects in a particular class is (in languages like C++ or Java) ''disjoint'' from its subclasses. ---- See the influential paper InheritanceIsNotSubtyping