LARA

A Guide To Inheritance in Programming Languages

Inheritance is one of the core features of Object Oriented programming, which provides reusability and extensiblity. The use of inheritance is often debated among programmers, computer scientists, and language designers. Some claim it should be mostly avoided, and others - generally the functional programming community - go beyond it and advocate that it is simply a bad idea. One of the most common objections is pointed out in the module system section of [4]: “That’s why inheritance in class-based languages is a bad idea. If a class D inherits from a class C, you have an implementation dependency of C on D. This is called the fragile base class problem, because changes to C force reconsideration of D.” Although that is a valid criticism, the use of inheritance can be justified by the module systems' very limited support for code reuse. Leaving aside that discussion, the main topic of this essay is when and how to use inheritance. Obviously, inheritance can not be used arbitrarily, and not all the class hierarchies make sense. For instance, Palsberg and Schwartzbach [8] defined a well-formedness criterion for the use of inheritance, based on IS-A and HAS-A relations. Intuitively the relation A IS-A B holds whenever A is a subclass of B, and A HAS-A B holds whenever B-object is a constituent part of an A-object. A class graph, has nodes as classes and directed IS-A and HAS-A edges between them. A class hierarchy is well-formed, if and only if no directed cycle contains an IS-A edge in its corresponding class graph.

Inheritance is not subtyping [1], but I will focus on subclassing that creates subclasses, and I will handle the useful exceptional cases (e.g. implementation inheritance) explicitly by providing some static guarantees.

Classifying Inheritance

inheritance.jpg

Meyer [7], classified valid use of inheritance into 12 categories (can be seen in the tree above), and argued that any kind of inheritance that does not fall into one of these should not be used. Meyer's classification is problematic in a couple of aspects. First, he argues that IS-A relation can be used as a negative rule in the Popperian style to detect and reject inappropriate uses of inheritance, but not all the uses for which the relationship holds is appropriate. As a results, he tries to identify the appropriate uses of inheritace when IS-A relation holds, and fragments the classification redundantly. He does not give any convincing example, when IS-A relation holds between two classes and using iheritance is inappropriate. His only example is, MALE and FEMALE should not be subclasses of the PERSON class, if gender does not significantly matter within the system. However, existence of a class is an entirely different debate, and Meyer's classification does not prevent this use anyway. According to his classification, if there is an abstract PERSON class and two derived classes MALE and FEMALE, this can be categorized as “subtype inheritance”. His definition for subtype inheritance is, “Subtype inheritance applies if A and B represent certain sets A' and B' of external objects such that B' is a subset of A' and the set modeled by any ther subtype heir of A is disjoint from B'. A must be deferred.” Because, MALE and FEMALE model disjoint sets and are subsets of the set modeled by PERSON, this is an instance of subtype inheritance. My main point is, there is no need to fragment the classification with complicated definitions, when a rigorously defined IS-A relationship holds between two classes. The problem with Meyer's classification is, his definition of IS-A relation is too informal and heavily relies on natural language, which is inherently ambiguous . Some examples of this kind of ambiguity can be seen in [2].

Meyer's informal IS-A rule of inheritance is “Do not make a class B inherit from a class A unless you can somehow make the argument that one can view every instance of B also an instance of A.”. The notion of substitutability was first proposed by Liskov and Wing [6], and it was called “behavioral subtyping”. According to that definition, for B to be a behavioral subtype of A, its invariant must imply A's invariant, and its methods must preserve the behavior of A's methods, that is when contracts are inherited, preconditions cannot be strengthened and postconditions cannot be weakened. Leavens and Naumann [5] formalized behavioral subtyping and fixed some problems with Liskov and Wing's definition. Comprehensive list of work on behavioral subtyping can be found in [5].

Subsumption problem also arises in the context of knowledge representation. Taxonomies play a key role in conceptual modelling, and wrong uses of subsumption in taxonomies, makes models confusing, and difficult to integrate or reuse. Welty and Guarino [9], developed OntoClean for analysing ontologies based on formal, domain-independent properties of classes (the metaproperties) such as identity, unity, rigidity, and dependence. OntoClean allows designers to make assumptions about each property in the taxonomy and checks the consistency of each set of metaproperties. Rigorous analysis of the ontological meta-properties of taxonomic nodes lead to consistent usage of the subsumption relation. A detalied account of ontology cleaning example can be seen in [3].

Another problem with Meyer's classification is, even though he says inheritance should only be used when IS-A relation holds between classes, he includes implementation inheritance in his classification. Just to include implementation inheritance, which actually represents “is-implemented-in-terms-of” relation, he says there are different forms of “is-a” and he modifies the definition of his IS-A relation.

I will divide uses of inheritance into two:

1) Proper Inheritance: It applies when A subsumes B. Subsumption has been very well studied in both in knowledge representation research and programming languages research. The former focuses on attributes and the latter focuses on methods (behavior) of the objects. Both are crucial, so I define subsumption as the composition of behavioral inheritance and OntoClean principles. A subsumes B if,
a) B is a behavioral subtype of A
b) The relation between A and B does not violate OntoClean principles.

2) Convenience Inheritance: This is using inheritance just for resusing some features. Meyer says, convenience inheritance is unacceptable; however, implementation inheritance is a form of convenience inheritance. Instead of changing the definition of “is-a” into something different, just to allow some forms of inheritance for convenience, I will propose a more general approach. The principle is ensuring safety when one class does not subsume the other. For instance, in the presence of implementation inheritance, Meyer proposes hiding the inherited methods using Eiffel's facilities. C++ has a private inheritance mechanism that can be used for the same purpose. However, some languages like Java do not have such facilities. For any kind of convenience inheritance, static safety mechanisms should be developed.

References

[1] William Cook, Walter Hill, and Peter Canning. Inheritance is not subtyping. In Seventeenth Symposium on Principles of Programming Languages, pages 125-135, 1990.

[2] Nicola Guarino, Christopher Welty. Evaluating ontological decisions with OntoClean. Communications of the ACM, v.45 n.2, February 2002.

[3] Nicola Guarino, Christopher Welty. An overview of OntoClean. In S. Staab and R. Studer, editors, Handbook on Ontologies. Springer Verlag, 2003.

[4] Robert Harper. Programming in Standard ML. Draft, 2005. Available at: http://www.cs.cmu.edu/~rwh/smlbook/

[5] Gary T. Leavens, David A. Naumann. Behavioral subtyping, specification inheritance, and modular reasoning. Technical Report 06-20a, Department of Computer Science, Iowa State University, Ames, Iowa, 50011, Aug. 2006.

[6] Barbara Liskov, Jeanette M. Wing. A behavioral notion of subtyping. ACM Transactions on Programming Languages and Systems, 16(6), 1994.

[7] Bertrand Meyer. Object-oriented software construction (2nd ed.). Prentice-Hall, Inc., Upper Saddle River, NJ, 1997.

[8] Jens Palsberg, Michael I. Schwartzbach. Object-oriented type systems. John Wiley and Sons Ltd., Chichester, UK, 1994.

[9] Christopher Welty, Nicola Guarino. Supporting ontological analysis of taxonomic relationships. Data & Knowledge Engineering, v.39 n.1, p.51-74, October 2001.