COS 441 - Subtyping - April 25, 1996

Subtyping

What if we want B to inherit from A, but yet be sortable? To do this we introduce the idea of subtyping. Class A is a subtype of B if A can be used in any situation where B can be used. This implies that A has at least all the methods of B with the appropriate types, plus any instance variables if they are not private. We could say that A implements B's interface.

A subclass B implies A subtype B, but the inverse implication does not hold. A can be a subtype of B if it is implemented independently but supports all the operations of B.

Implicit subtyping of this kind (here noted by '<') gives us the following type rule:

A |- e : C   C < D
------------------
A |- e : D

Few object-oriented languages in common use have an implicit subtyping rule like the one above. More often, the subtyping hierarchy is explicitly declared (as in Java). Abstract classes are used to define interfaces. They have the following properties.

In Java, classes can subclass one other class, but implement (subtype) many interfaces (abstract classes). For example, a Java class declaration looks like:

class A extends B implements C, D, E { body };
Thus subclassing is single inheritance, but subtyping is multiple inheritance.

C++ provides no separate subtyping hierarchy, but a good programming discipline is to emulate one. Make an abstract class (interface) by declaring all methods to be pure virtual functions. Build a class that implements the interface by inheriting and overriding all of these methods. The compiler will generate an error if any pure virtual function is not overridden.

For your assignment, if you are doing abstract classes rather than multiple inheritance, follow a Java-like idea: