Inheritance (object-oriented programming)
In 1967, Ole-Johan Dahl and Kristen Nygaard presented a design that allowed specifying objects belonging to different classes while sharing common properties. This idea first appeared in the Simula 67 programming language. The concept built upon earlier remarks Tony Hoare made about records in 1966 regarding record subclasses with private fields. Simula 67 collected common properties into a superclass where each subclass could potentially have its own superclass. Values of a subclass became compound objects consisting of prefix parts from various superclasses plus a main part belonging to the subclass itself. These parts were all concatenated together so attributes remained accessible via dot notation. The idea then spread to Smalltalk, C++, Java, Python, and many other languages.
A class acquiring features from one superclass defines single inheritance. A derived class inherits the properties of another class without exception for constructors or destructors. One class can inherit features from more than one parent class through multiple inheritance. Multilevel inheritance occurs when a subclass is inherited from another subclass creating an inheritance path like ABC. Class B serves as an intermediate base class linking inheritance between A and C. The chain ABC represents this multilevel structure extending to any number of levels. Hierarchical inheritance happens when one class acts as a superclass for more than one subclass. Both B and C share parent class A yet remain separate subclasses. Hybrid inheritance mixes two or more types occurring when class A has subclass B which has two subclasses C and D.
Inheritance should not be confused with subtyping in programming language theory. Subtyping establishes an is-a relationship whereas inheritance only reuses implementation establishing a syntactic relationship. Inheritance does not ensure behavioral subtyping even if it commonly used for subtype relationships. Some statically-typed class-based OO languages like C++ and Java agree on both concepts while others differ. Subtyping sometimes referred to as interface inheritance acknowledges specialization of type variables inducing a subtyping relation. Inheritance defined here known as implementation inheritance or code inheritance focuses solely on reuse mechanisms. An instance of the reusing class cannot necessarily be substituted for an instance of the inherited class without assurance of polymorphic substitutability. It is entirely possible to derive a class whose object will behave incorrectly when used where parent class expected per Liskov substitution principle constraints.
The colon indicates that the subclass inherits from the superclass in C++ syntax. The visibility modifier is optional and may be either private or public if present. Default visibility remains private when no modifier appears in the declaration. Private derivation results in members not being inherited by the derived class. Protected derivation allows subclasses to access data without allowing external code access. Public derivation makes all base class features available to clients. Java and C# lack visibility modifiers for inheritance making them equivalent to public SuperClass in C++. A protected access modifier exists in modern languages including C++ and Java allowing subclasses to access data without exposing it outside the chain of inheritance. Client code generally has access to all object's superclass data even if superclass declared non-public through casting capabilities.
Allen Holub identified the fragile base class problem as introducing unnecessary coupling through implementation inheritance. Modifications to base class implementation can cause inadvertent behavioral changes in subclasses breaking encapsulation. Complex inheritance within insufficiently mature designs leads to the yo-yo problem creating many very thin layers of code. Developers tended to break code into more layers of inheritance as system functionality grew during the late 1990s. Many layers consisting of only one or two lines of actual code make debugging a significant challenge. Too many layers make determining which layer needs debugging difficult for development teams combining multiple layers with single responsibility principle. Static hierarchy locks developers into original design standards preventing objects from changing type while retaining state at runtime.
Implementation inheritance has been controversial among programmers since at least the 1990s when critics advocated interface inheritance instead. The authors of Design Patterns favor composition over inheritance as an alternative technique requiring more programming effort but avoiding substitutability issues. Java inventor James Gosling reportedly stated he would not include implementation inheritance if redesigning Java today. Explicit delegation requires more programming effort yet avoids the substitutability issue entirely. Private and protected inheritance in C++ thought of as an is implemented in terms relationship rather than is-a relationship. Composite reuse principle supports polymorphism by separating behaviors from primary class hierarchy including specific behavior classes as required in business domain classes. This approach allows behavior modifications at run time enabling one class to implement behaviors buffet-style instead of restricted to ancestor class behaviors.
Common questions
Who created the Simula 67 programming language that introduced inheritance in 1967?
Ole-Johan Dahl and Kristen Nygaard presented the design for Simula 67 in 1967. This language allowed specifying objects belonging to different classes while sharing common properties.
What is the difference between single inheritance and multiple inheritance in object-oriented programming?
Single inheritance occurs when a class acquires features from one superclass without exception for constructors or destructors. Multiple inheritance allows one class to inherit features from more than one parent class simultaneously.
Why does implementation inheritance differ from subtyping in programming language theory?
Subtyping establishes an is-a relationship whereas inheritance only reuses implementation establishing a syntactic relationship. Inheritance does not ensure behavioral subtyping even if it commonly used for subtype relationships.
How does C++ syntax indicate that a subclass inherits from a superclass using visibility modifiers?
The colon indicates that the subclass inherits from the superclass in C++ syntax with optional private or public visibility modifiers. Default visibility remains private when no modifier appears in the declaration.
What problems did Allen Holub identify regarding complex inheritance hierarchies in the late 1990s?
Allen Holub identified the fragile base class problem as introducing unnecessary coupling through implementation inheritance. Complex inheritance within insufficiently mature designs leads to the yo-yo problem creating many very thin layers of code.
All sources
21 references cited across the entry
- 1webDesigning Reusable ClassesRalph Johnson — August 26, 1991
- 2bookConference proceedings on Object-oriented programming systems, languages and applications - OOPSLA '89OL Madsen — 1989
- 3bookAdvanced Methods and Deep Learning in Computer VisionDavies, Turk — Elsevier Science — 2021
- 4conferenceInheritance is not subtypingWilliam R. Cook et al. — 1990
- 5tech reportTypeful ProgrammingLuca Cardelli — 1993
- 6conferenceA study of the fragile base class problemLeonid Mikhajlov et al. — Springer — 1998
- 7conferenceWhat programmers do with inheritance in JavaEwan Tempero et al. — Springer — 2013
- 8tech reportRecord HandlingC. A. R. Hoare — 1966
- 9conferenceClass and subclass declarationsOle-Johan Dahl et al. — Norwegian Computing Center — May 1967
- 10bookFrom Object-Orientation to Formal MethodsOle-Johan Dahl — 2004
- 11webC++ Inheritance
- 12bookThe Design and Evolution of C++Bjarne Stroustrup — Pearson — 1994
- 13bookThe complete reference C++Herbert Schildt — Tata McGraw Hill — 2003
- 14bookObject Oriented Programming With C++E. Balagurusamy — Tata McGraw Hill — 2010
- 15inlineoverride(C# Reference)
- 17bookMastering C++K.R. Venugopal et al. — Tata McGraw Hill Education Private Limited — 2013
- 18bookConcepts in programming languageJohn Mitchell — Cambridge University Press — 2002
- 19journalEvolution of object behavior using context relationsLinda M. Seiter et al. — 1996
- 20webWhy extends is evilAllen Holub — 1 August 2003
- 21conferenceDesigning an object-oriented programming language with behavioural subtypingPierre America — 1991