Fact-checked by Grok 2 weeks ago

Multiple inheritance

Multiple inheritance is a feature in some languages that enables a to derive , methods, and behaviors from more than one superclass, allowing for greater flexibility in and modeling complex relationships compared to single inheritance. This mechanism supports the creation of subclasses that combine functionalities from multiple parent classes, such as inheriting drawing capabilities from a GraphicalObject and color from a ColoredObject . Languages that support multiple inheritance include C++, Eiffel, , and , where a class declaration can specify multiple base classes, often using a comma-separated list in the syntax. In contrast, Java restricts classes to single inheritance but permits multiple inheritance of interfaces to avoid implementation conflicts, while C# similarly limits classes but allows multiple interfaces. The feature originated in the evolution of object-oriented paradigms following Simula 67's introduction of single inheritance in 1967, with multiple inheritance formalized in languages like C++ during the 1980s to enhance modularity and expressiveness. One notable challenge with multiple inheritance is the diamond problem, an ambiguity that arises when two superclasses inherit from a common base class, leading to duplicate or conflicting method implementations in the subclass—for instance, if classes B and C both inherit from A and define a method from A differently, the subclass D inheriting from B and C may not know which version to use. Languages address this through mechanisms like in C++, which ensures a single instance of the common base class is shared, or by using method resolution orders (MRO) in via algorithms like C3 linearization to determine invocation precedence. Advantages of multiple inheritance include improved code reusability by allowing a class to incorporate orthogonal features from unrelated hierarchies without deep nesting, facilitating more natural modeling of real-world entities like a "FlyingCar" inheriting from both "Vehicle" and "Aircraft." However, disadvantages encompass increased language complexity, potential runtime inefficiencies due to larger dispatch tables or binding overhead, and risks of semantic conflicts beyond the diamond problem, such as name clashes for fields or methods. These issues have led some languages and design principles, like those in the Gang of Four's , to favor where possible to mitigate entanglement.

Core Concepts

Definition

Multiple inheritance is a feature of (OOP) languages that enables a , known as a subclass or derived class, to derive properties, behaviors, and structures from more than one parent , or superclass, at the same time. This allows the subclass to combine functionalities from multiple sources, facilitating greater flexibility in modeling real-world entities that exhibit characteristics from diverse categories. In OOP, inheritance serves as a fundamental mechanism for code reuse and abstraction, where a subclass inherits the attributes (such as data fields) and methods (such as functions or procedures) defined in its superclass, enabling the creation of a hierarchy of classes that represent "is-a" relationships. Polymorphism, a related prerequisite, permits objects of different classes to be treated uniformly through a common interface, often achieved via method overriding or dynamic dispatch in inheritance chains. These concepts form the basis for multiple inheritance, which extends the model beyond a linear chain to a more networked structure. The key mechanics of multiple inheritance involve the subclass accessing and potentially overriding elements from all specified superclasses, resulting in a merged set of attributes, methods, and even delegation hierarchies that define the subclass's overall and behavior. This can lead to a richer, more , though it requires careful management to ensure coherent integration of inherited components. Single inheritance, as a simpler precursor, restricts derivation to a single , limiting the scope of combined features. The concept of inheritance originated in the Simula 67 programming language in 1967, where it was introduced as an extension of basic class structures to better model complex relationships in simulations and data organization. Multiple inheritance builds directly on this foundation, allowing for more intricate taxonomic arrangements in subsequent paradigms. To illustrate the basic syntax in a language-agnostic pseudocode form:
class Child(Parent1, Parent2) {
    // Inherited attributes and methods from Parent1 and Parent2
    // Additional or overriding members can be defined here
    void specificMethod() {
        // Implementation using inherited behaviors
    }
}
This declaration specifies that Child inherits from both Parent1 and Parent2, combining their features while permitting extensions.

Comparison to Single Inheritance

Single inheritance restricts a class to deriving from exactly one superclass, resulting in a linear, tree-like that simplifies the structure of class relationships. This model promotes clarity in method resolution and attribute access, as there is a single path of to traverse, reducing the potential for conflicts during execution. In contrast, multiple inheritance permits a to derive from more than one superclass, forming a (DAG) that enables more expressive modeling of real-world entities. For instance, a representing a "FlyingCar" could inherit behaviors and attributes from both "" and "" superclasses, allowing for the integration of diverse functionalities without redundant code. However, this flexibility introduces complexities, such as ambiguities in and attribute resolution, which require additional mechanisms to disambiguate during traversal. Multiple inheritance offers significant benefits in code reuse, particularly for incorporating functionality from unrelated classes, and supports natural representations of multifaceted "is-a" relationships, such as a teaching assistant who is both a student and an employee. These advantages make it suitable for scenarios involving hybrid or composite entities, like an "AmphibiousVehicle" deriving from both "Vehicle" and "Boat" to combine land and water capabilities. Conversely, single inheritance excels in maintaining strict taxonomies, as seen in hierarchies like "Animal" > "Mammal" > "Dog," where a clear, unambiguous specialization chain avoids unnecessary coupling. While multiple inheritance enhances modularity in complex designs, it can foster tighter coupling and elevate maintenance efforts due to the intricate interdependencies it creates. Single inheritance, by design, mitigates these issues through its constrained structure but may necessitate workarounds like composition for broader reuse. Most object-oriented programming languages natively implement single inheritance for its simplicity, treating multiple inheritance as an advanced, optional extension in those that support it.

Language Implementations

In C++

Multiple inheritance in C++ allows a derived to inherit from more than one base , enabling the combination of features from multiple sources in a single . The syntax for declaring a derived with multiple bases is class Derived : access1 Base1, access2 Base2 { ... };, where each access specifier can be public, protected, or private independently for each base , determining how the base's members are accessible in the derived and its users. inheritance preserves the base's public and protected members as public and protected in the derived , protected inheritance makes them protected, and inheritance makes them private. This flexibility supports diverse design needs, such as implementing interfaces or composing behaviors. Multiple inheritance was introduced in C++ Release 2.0 in June 1989 by Bjarne Stroustrup to facilitate complex object-oriented designs, particularly in areas like graphical user interfaces where classes need to combine independent concepts such as display options and interaction styles without redundant hierarchies. In terms of memory layout, a derived class with multiple non-virtual base classes contains distinct subobjects for each base, laid out in the order of declaration, which can lead to size overhead if bases share common data or if the hierarchy duplicates subobjects. Virtual inheritance addresses this by using the virtual keyword in the base specifier, such as class Derived : virtual public Base1, public Base2 { ... };, ensuring that a common virtual base class is shared across the hierarchy, resulting in only one subobject instance regardless of multiple inheritance paths. This mechanism prevents duplication but introduces additional runtime overhead due to offset pointers in the object layout for locating the shared base. Method resolution in multiple inheritance follows a depth-first, left-to-right search order based on the declaration of bases in the derived class, starting from the derived class itself. If a name is ambiguous—such as when the same member exists in multiple bases without qualification—the compiler issues an error, requiring explicit scope resolution like Base1::[method](/page/Method)() to disambiguate. Overridden virtual functions are resolved polymorphically via virtual tables (vtables), but non-virtual calls rely on this static lookup order. The following example illustrates non-virtual versus virtual inheritance. Without virtual, a diamond-shaped hierarchy duplicates the common base:
cpp
class Base {
public:
    int data = 42;
};

class Intermediate1 : public Base {};
class Intermediate2 : public Base {};

class Derived : public Intermediate1, public Intermediate2 {
public:
    void print() {
        // Ambiguous: Intermediate1::data or Intermediate2::data?
        // std::cout << data << std::endl;  // Error: ambiguous
        std::cout << Intermediate1::data << std::endl;  // Resolves to 42
    }
};

int main() {
    Derived d;
    std::cout << sizeof(d) << std::endl;  // Typically larger due to two Base subobjects
    // static_cast<Base*>(static_cast<Intermediate1*>(&d));  // OK
    // static_cast<Base*>(static_cast<Intermediate2*>(&d));  // OK, but points to different subobjects
    return 0;
}
With , the common base is shared, avoiding duplication and ambiguity:
cpp
class Intermediate1 : virtual public Base {};
class Intermediate2 : virtual public Base {};

class Derived : public Intermediate1, public Intermediate2 {
public:
    void print() {
        std::cout << data << std::endl;  // Unambiguous: single shared Base subobject
    }
};

int main() {
    Derived d;
    std::cout << sizeof(d) << std::endl;  // Smaller: one Base subobject
    Base* b1 = static_cast<Base*>(static_cast<Intermediate1*>(&d));  // Points to shared Base
    Base* b2 = static_cast<Base*>(static_cast<Intermediate2*>(&d));  // Same as b1
    return 0;
}
In the non-virtual case, this setup risks the diamond problem, where multiple paths to a lead to duplicated data and ambiguous access. Compilers like (g++) and Microsoft Visual C++ (MSVC) implement vtables to handle polymorphic calls in multiple inheritance, with each base subobject potentially having its own vtable pointer for correct function dispatch. In virtual inheritance, additional vtable entries or offset pointers are used to locate the shared base, and both compilers emit warnings or errors for ambiguous conversions or lookups during compilation. For instance, g++ follows the ABI for vtable layout in multiple inheritance, while MSVC uses a Microsoft-specific ABI that includes thunks for adjusting this pointers in cross-cast scenarios.

In Python

Python supports multiple inheritance through a syntax that allows a class to specify multiple base classes in parentheses following the class name. For example, a class definition takes the form class Child(Parent1, Parent2):, where attributes and methods are dynamically bound at runtime by searching the method resolution order (MRO) of the class hierarchy. The MRO determines the order in which base classes are searched for methods and attributes during attribute lookup, ensuring that the subclass's own members take precedence (local precedence) and that the order remains consistent with the inheritance structure (monotonicity). Python employs the C3 linearization algorithm for computing the MRO, which produces a linear ordering of all superclasses that respects the order of direct superclasses and avoids non-monotonic ambiguities. Full support for multiple inheritance with the algorithm was introduced in 2.3 in 2003, alongside new-style classes, drawing influence from the programming language's approach to superclass linearization. Prior versions used a different resolution strategy, but the method was adopted to provide more predictable and monotonic behavior in complex hierarchies. The algorithm merges the MROs of a class's direct superclasses into a single linear order. It operates iteratively by identifying candidate heads (classes that appear as the first element in one of the MRO lists and do not appear in the tails of any other lists), selecting the leftmost such candidate, appending it to the result, and removing it from all lists by advancing the relevant list. If no candidate is found, the merge fails, raising a TypeError. for the merge step is as follows:
def merge(seqs):
    res = []; i = 0
    while 1:
        nonemptyseqs = [seq for seq in seqs if seq]
        if not nonemptyseqs: return res
        i += 1
        for seq in nonemptyseqs:
            cand = seq[0]
            nothead = [s for s in nonemptyseqs if cand in s[1:]]
            if not nothead: break
            else: cand = None
        if not cand: raise "Inconsistent [hierarchy](/page/Hierarchy)"
        res.append(cand)
        for seq in nonemptyseqs:
            if seq[0] == cand: del seq[0]
This process ensures a unique, unambiguous order when possible. Developers can inspect the MRO of a class using the built-in class.mro() method, which returns a tuple of the classes in resolution order. Additionally, the super() function facilitates cooperative multiple inheritance by dynamically dispatching to the next class in the MRO, allowing methods in a hierarchy to call each other without explicit knowledge of the full structure. Consider a diamond inheritance scenario where class B and class C both inherit from class A, and class D inherits from B and C:
python
class A:
    def method(self):
        print("A.method")

class B(A):
    def method(self):
        print("B.method")
        super().method()

class C(A):
    def [method](/page/Method)(self):
        print("C.method")
        [super](/page/Super)().method()

class D(B, C):
    def [method](/page/Method)(self):
        print("D.method")
        [super](/page/Super)().method()
The MRO for D is [D, B, C, A, object], computed via , ensuring that D.method() calls B's method, which then calls C's, then A's, avoiding duplication and . Calling D().method() outputs "D.method", "B.method", "C.method", and "A.method". Attribute lookup in multiple involves dynamic traversal of the MRO, which introduces a slight performance overhead compared to single due to the additional resolution steps, though this is typically negligible for most applications.

In Other Languages

eschews multiple class to mitigate and , opting instead for interfaces that enable a class to implement multiple behaviors through the implements keyword; while pre- 8 interfaces offered only type declarations and methods, the introduction of default methods in 8 permits limited implementation across interfaces, with rules resolving any conflicting defaults. C# follows a comparable model to , enforcing single while permitting a to implement multiple for polymorphic ; to conflicts, such as when multiple declare the same member, explicit allows developers to specify distinct realizations accessed via the type. Eiffel offers robust support for multiple , allowing a to inherit from several parents via the inherit ; it addresses name clashes through renaming (e.g., rename f as A_f), which reassigns inherited features to unique identifiers, and select clauses in repeated scenarios to designate specific versions of ambiguous features, all while upholding design-by-contract assertions for verifiable reliability. Common Lisp, through its Common Lisp Object System (CLOS), supports multiple inheritance, allowing classes to specify multiple superclasses. Method dispatch occurs via generic functions with , and ambiguities are resolved using method combinations such as :before, :primary, :after, and :around methods. Perl implements multiple inheritance by populating the @ISA array with parent package names, facilitating dynamic loading at to extend class hierarchies; however, it lacks automatic resolution for inheritance ambiguities, such as the diamond problem, requiring manual intervention by developers to manage method dispatch order. Scala utilizes traits to provide mixin-style multiple inheritance, where classes can extend multiple traits to compose behaviors; traits support concrete and abstract members, and Scala's linearization algorithm—depth-first left-to-right traversal—establishes a consistent method resolution order similar to the C3 scheme, preventing duplication in diamond-like structures. For instance, traits can be stacked to layer functionality:
scala
trait Ord {
  def compare(that: Any): Int
}

trait Ordered extends Ord {
  override def compare(that: Any): Int =
    if (that.isInstanceOf[Ordered])
      this.compareTo(that.asInstanceOf[Ordered])
    else
      this.hashCode - that.hashCode
  def compareTo(that: Ordered): Int
}
Here, Ordered extends Ord and overrides compare to delegate to compareTo when possible, demonstrating trait stacking with selective overriding. Several modern languages forgo multiple inheritance to prioritize simplicity and composability; Go rejects inheritance hierarchies in favor of embedding structs within types and implicit interface satisfaction, enabling flexible reuse without rigid parent-child relationships, while Rust employs traits solely for defining shared methods implementable by any type, emphasizing composition to avoid inheritance pitfalls. Post-2000 developments reflect a broader trend toward refined mechanisms in languages blending object-oriented and functional paradigms, with traits emerging as a composable to raw multiple inheritance by encapsulating stateless behavior units that can be selectively aliased or excluded during mixing; this evolution is exemplified in Kotlin, where via the by keyword allows a to forward calls to an object instance, simulating multiple inheritance without direct superclass proliferation.

Challenges and Solutions

The Diamond Problem

The diamond problem arises in multiple inheritance when a derived class inherits from two or more intermediate classes that share a common , forming a diamond-shaped in the . This structure creates in resolving members, such as methods or data fields, from the shared , as the or must determine which path to follow. Additionally, without specific mechanisms, it can lead to duplicate subobjects of the ancestor within the derived instance. A classic illustration involves four classes: a base class A, two intermediate classes B and C that both inherit from A, and a derived class D that inherits from both B and C. If A defines a m() or a member x, accessing m() or x from an instance of D becomes , as there are two potential paths (DBA and DCA). Without explicit qualification (e.g., B::m()), this results in a due to unresolved ambiguity. The consequences include memory bloat from multiple instances of the ancestor class's subobjects in the derived class, increasing object size and potentially leading to inefficient resource use in large systems. Method dispatch can also fail at runtime or compile time if virtual functions are overridden differently along each path, causing unpredictable behavior or errors. The inheritance graph visually appears as a diamond: A at the apex, B and C as the middle points branching outward, and D at the base, highlighting the convergence of paths. The problem was first systematically discussed in the late 1980s during the development of object-oriented languages supporting , notably as "fork-join inheritance" in Sakkinen (1989) and in Stroustrup's analysis of C++ design choices. In practice, it complicates in complex hierarchies by introducing subtle ambiguities and can inflate sizes through duplicated structures. Languages like encounter this in their method resolution order (MRO), where the linearization algorithm is designed to handle structures correctly.

Resolution Strategies

One strategy to resolve ambiguities in multiple inheritance hierarchies, such as duplicate instances of shared base classes, involves declaring shared ancestors as virtual bases. This ensures that only a single instance of the shared base class is constructed and shared among all derived classes that inherit from it through multiple paths, thereby avoiding duplication and access conflicts. Another approach is explicit qualification, where developers use scope operators to disambiguate or attribute calls from specific classes. For instance, in cases of name clashes, the can the identifier with the full to the desired , allowing precise over which inherited member is invoked without altering the structure. Linearization algorithms provide a systematic way to define a consistent order for traversing the graph, particularly useful for in the presence of multiple s. These algorithms, often based on , produce a of the that respects local precedence (a appears before its direct superclasses) and monotonicity (adding a superclass preserves the existing order). A seminal example is the C3 linearization, which merges linearizations of superclasses while merging heads and checking for consistency, ensuring unambiguous dispatch. Renaming clauses offer a mechanism to handle naming conflicts by allowing subclasses to redefine or alias inherited features with new names. This enables the integration of multiple parents without immediate clashes, as the child class can selectively rename overlapping to maintain distinct identities while preserving access to all original behaviors. Such clauses promote flexibility in hierarchy design by decoupling name resolution from the topology. Best practices for mitigating multiple inheritance issues emphasize preferring over deep inheritance hierarchies, where objects delegate behavior to composed instances rather than inheriting it, reducing coupling and ambiguity risks. Additionally, using forward declarations can help manage complex dependencies in header files during , preventing circular inclusions that might exacerbate challenges in large systems. Empirical studies indicate that multiple inheritance enhances reusability in languages like C++ and compared to Java's interface-based approach.

Alternatives and Extensions

Mixins and Traits

are small, focused es designed to provide specific, reusable functionality that can be incorporated into larger es through multiple , typically without forming deep hierarchies. These es, often named with a suffix like "Mixin" (e.g., SerializableMixin for adding methods), are composed in a controlled order during definition to minimize conflicts, such as by placing them after the primary in the list. Traits represent a more formalized language-level construct for achieving similar reusability, appearing as built-in features in languages like and , where they encapsulate blocks of methods and fields that can be mixed into es or other traits. Unlike plain mixins, traits often include abstract (required) s that the adopting must implement, and they incorporate mechanisms for overriding and resolving conflicts, such as linearization to define a of precedence. In , for instance, traits enable fine-grained composition by allowing multiple traits to be extended in a , with the handling dispatch according to a that respects declaration order. A key distinction between mixins/traits and full multiple inheritance lies in their emphasis on horizontal augmentation—enabling a to "has-a" certain capability or "can-do" specific behaviors—rather than building complex, vertical is-a hierarchies that risk ambiguity. This approach promotes over deep subclassing, making it particularly suitable for adding orthogonal features like or validation without altering core structure. As an implementation pattern, mixins and traits are forward-compatible with single-inheritance languages by leveraging abstract base classes (ABCs) as mixin foundations, allowing behavioral extension without violating strict inheritance rules. For example, in Python, an ABC can serve as a mixin base to enforce interfaces while providing default implementations. Historically, mixins trace their origins to the Flavors object system in Lisp, developed in the late 1970s at MIT's Artificial Intelligence Laboratory as a non-hierarchical approach to object-oriented programming. Traits trace their origins to entities in the Mesa programming language (late 1970s, used for Xerox Star), with later influences from prototype-based systems and formalization as a composable construct in Smalltalk dialects in the early 2000s, including adoption in frameworks like Ruby on Rails for modular behaviors using mixin-like modules. A representative example is a logging , which can be stacked into a definition to add logging without introducing diamond issues:
python
class LoggingMixin:
    def log(self, message):
        print(f"LOG: {message}")

class MyClass(PrimaryBase, LoggingMixin):
    def do_something(self):
        self.log("Action performed")
        # Primary logic here
This pattern ensures the mixin methods are called only when explicitly invoked, avoiding unintended overrides. The advantages of mixins and traits include enhanced modularity by isolating concerns into reusable units, which facilitates unit testing of individual behaviors in isolation, and their use in frameworks like Django for pluggable class-based views, such as adding form handling or permissions without monolithic classes.

Interface-Based Approaches

Interfaces represent abstract contracts in object-oriented programming, specifying method signatures without implementations, which allows classes to implement multiple interfaces simultaneously. This approach enables polymorphism and behavioral reuse across disparate hierarchies, sidestepping the ambiguities inherent in full class multiple inheritance, such as method resolution conflicts. In languages like Java and C#, a single class can conform to multiple such contracts, inheriting type compatibility without inheriting state or risking the diamond problem. Introduced in 8, default methods extend this model by permitting s to provide concrete implementations for methods, thereby allowing shared to be inherited from multiple sources while maintaining for existing code. For instance, the TimeClient includes a default method getZonedDateTime(String zoneString) that constructs a ZonedDateTime object using LocalDateTime.now() and ZoneId.of(zoneString), which implementing classes like SimpleTimeClient can use directly or override. This feature supports multiple inheritance of —without state—resolving conflicts by prioritizing class implementations over defaults, or explicit overrides if defaults clash across s. Similar capabilities appear in C# through default implementations since version 8.0. The complements interface-based design by having a implement an and forward calls to a separate helper object that holds the actual logic, thus achieving . This avoids rigid hierarchies and enables runtime flexibility, such as dynamically assigning roles (e.g., a FlightSegment delegating checkLuggage to a LuggageCompartment instance). Unlike multiple , delegation prevents subclass explosion—for example, combining six roles via inheritance might require 63 subclasses, whereas delegation uses a single with references. This paradigm offers several advantages, including between components, elimination of diamond inheritance issues, and simplified refactoring since changes to one do not propagate through deep class trees. However, it introduces for forwarding methods in or implementing each signature, potentially increasing verbosity compared to direct . The shift toward interface-based and composition-oriented approaches gained prominence following the "Design Patterns: Elements of Reusable Object-Oriented Software" by Gamma et al. (1994), which advised to "favor object composition over class " to enhance flexibility and modularity. It became dominant in from its 1995 release and in C# from 2000, influencing modern language designs to prioritize contracts over implementation hierarchies. In contemporary , 's interfaces further this approach by supporting multiple extensions—such as interface Square extends Shape, PenStroke—and optional properties marked with ? (e.g., color?: string), enabling type-safe reuse in JavaScript ecosystems like applications without runtime overhead. For example, a class might implement interfaces for event handling and data , combining them via extension for modular frontend components.

References

  1. [1]
    Multiple Inheritance
    Multiple inheritance simply means that a class can inherit properties from more than one base class.
  2. [2]
    10.2.5. Multiple Inheritance
    Multiple inheritance allows a subclass to have more than one superclass, implemented in C++ with a comma-separated list of superclasses.
  3. [3]
    Programming Languages - Lecture 17 - Williams College CS334
    Some object-oriented languages, including both C++ and Eiffel, support multiple inheritance. Multiple inheritance allows a class to extend two or more classes.
  4. [4]
    The multiple-inheritance dispatch problem
    Java, C++, and other OO languages introduce the challenge of multiple inheritance, in which a class or interface can extend multiple interfaces or classes.
  5. [5]
    [PDF] A Semantics of Multiple Inheritance - Luca Cardelli
    An examination of the differences between Simula, Smalltalk and other languages suggest that inheritance is the only notion critically associated with object- ...
  6. [6]
    Single and Multiple Inheritance
    Disadvantages of multiple inheritance: Language and implementation complexity. Potential inefficiency--dynamic binding costs more with multiple inheritance ( ...
  7. [7]
    C++ syntax, semantics and concepts questions
    The advantage of multiple inheritance is that it allows a class to inherit the functionality of more than one base class thus allowing for modeling of complex ...
  8. [8]
    [PDF] Chapter 11
    Single and Multiple Inheritance. - Disadvantage of multiple inheritance: - Language and implementation complexity. - Potential inefficiency - dynamic binding ...
  9. [9]
    [PDF] Chapter 12
    Single and Multiple Inheritance. • Multiple inheritance allows a new class to inherit from two or more classes. • Disadvantages of multiple inheritance: – ...
  10. [10]
    Multiple Inheritance - an overview | ScienceDirect Topics
    Multiple inheritance is a feature in object-oriented programming that allows a class to inherit from more than one parent class. A subclass with more than one ...<|control11|><|separator|>
  11. [11]
    [PDF] The Birth of Object Orientation: the Simula Languages - UiO
    The main impact of Simula 67 has turned out to be the very wide acceptance of many of its basic concepts: objects, but usually without own actions, classes,.
  12. [12]
    On the notion of inheritance | ACM Computing Surveys
    SAKKINEN, M. 1989. Disciplined inheritance. In ECOOP'89: Proceedings of the Third European Conference on Object-Oriented Programming (Nottingham, England ...
  13. [13]
    Implementing modular class-based reuse mechanisms on top of a ...
    Apr 9, 2018 · Inheritance is characterized as single or multiple depending on the number of classes a class can inherit from. Single inheritance is simple ...
  14. [14]
    Multiple and Virtual Inheritance, C++ FAQ - Standard C++
    The C++ rules say that virtual base classes are constructed before all non-virtual base classes. The thing you as a programmer need to know is this: ...
  15. [15]
    [PDF] A History of C++: 1979− 1991 - Bjarne Stroustrup's Homepage
    Jan 1, 1984 · Also, adding multiple inheritance in 2.0 was a mistake. Multiple inheritance belongs in C++ but is far less important than parameterized types.
  16. [16]
    None
    ### Summary of Reasons for Multiple Inheritance in C++, Especially for GUI Frameworks
  17. [17]
    Multiple Base Classes | Microsoft Learn
    Oct 3, 2025 · Virtual base classes offer a way to save space and avoid ambiguities in class hierarchies that use multiple inheritance. Each nonvirtual object ...
  18. [18]
  19. [19]
    C++ vtables - Part 2 - Multiple Inheritance | Shahar Mike's Web Spot
    Mar 8, 2016 · In this post we will cover multiple inheritance, which complicates things even when only inheriting from pure-interfaces.
  20. [20]
  21. [21]
    The Python 2.3 Method Resolution Order — Python 3.14.0 ...
    On the other hand, if you really want to know how multiple inheritance works, then this paper is for you. ... The Method Resolution Order (MRO) is the set of ...
  22. [22]
    What's New in Python 2.3 — Python 3.14.0 documentation
    Python 2.2 originally used a topological sort of a class's ancestors, but 2.3 now uses the C3 algorithm as described in the paper “A Monotonic Superclass ...
  23. [23]
    [PDF] A Monotonic Superclass Linearization for Dylan
    Jun 28, 1996 · A Monotonic Superclass Linearization for Dylan. Kim Barrett <kab@camellia.org>. Bob Cassels <Cassels@harlequin.com>. Paul Haahr <haahr@netcom ...
  24. [24]
  25. [25]
  26. [26]
  27. [27]
    Fast Subtype Checking for Single Inheritance - Python Discussions
    May 11, 2025 · can incur performance overhead due to the need to traverse the MRO of a class. This overhead becomes especially pronounced in the following ...<|separator|>
  28. [28]
    Multiple Inheritance of State, Implementation, and Type
    The Java programming language supports multiple inheritance of type, which is the ability of a class to implement more than one interface.
  29. [29]
    Interfaces - define behavior for multiple types - C# | Microsoft Learn
    An interface in C# contains definitions for a group of related functionalities that a non-abstract class or a struct must implement.
  30. [30]
    Multiple inheritance - Eiffel Software - The Home of EiffelStudio
    You write for example rename f as A_f in the clause in C stating that C inherits from A. Then f will be known, in the code of C, under the new name.Missing: select | Show results with:select
  31. [31]
    perlootut - Object-Oriented Programming in Perl Tutorial - Perldoc Browser
    ### Summary: Multiple Inheritance, Dynamic Loading, and Diamond Problem in Perl (perlootut)
  32. [32]
  33. [33]
    Traits | Tour of Scala
    Use the extends keyword to extend a trait. Then implement any abstract members of the trait using the override keyword: Scala 2; Scala 3.Missing: stacking | Show results with:stacking
  34. [34]
    Frequently Asked Questions (FAQ) - The Go Programming Language
    ### Go's Stance on Inheritance, Favoring Composition
  35. [35]
    Traits: Defining Shared Behavior - The Rust Programming Language
    ### Summary of Rust's Use of Traits for Behavior, No Class Inheritance, Favoring Composition
  36. [36]
    Traits: A mechanism for fine-grained reuse - ACM Digital Library
    Existing schemes based on single inheritance, multiple inheritance, or mixins, all pose numerous problems for reuse. To overcome these problems we propose ...Missing: trends | Show results with:trends
  37. [37]
    Delegation | Kotlin
    ### Summary of Kotlin Delegation for Multiple Inheritance-like Behavior
  38. [38]
    3. Data model — Python 3.14.0 documentation
    Objects are Python's abstraction for data. All data in a Python program is represented by objects or by relations between objects.
  39. [39]
    Inheritance - Eiffel.org
    Inheritance allows us to make extensions and adaptations to existing software, while at the same time, leaving the original software unaltered.
  40. [40]
    (PDF) Monotonic conflict resolution mechanisms for inheritance
    Aug 7, 2025 · The main topic of this paper is multiple inheritance and conflict resolution methods in Object Oriented Programming.Missing: survey | Show results with:survey<|control11|><|separator|>
  41. [41]
    (PDF) A Comparative Study on the Effect of Multiple Inheritance ...
    Aug 7, 2025 · Our analysis finds inheritance is used for two main reasons: to support subtyping and to permit what we call external code reuse.Missing: strategies | Show results with:strategies
  42. [42]
    Controlling the C3 Super Class Linearization Algorithm for Large ...
    A monotonic superclass linearization for Dylan · Monotonic conflict resolution mechanisms for inheritance · Proposal for a monotonic multiple inheritance ...
  43. [43]
    [PDF] Flavors : A non-hierarchical approach to object-oriented programming
    Jan 31, 2007 · This paper presents a non-hierarchically organized object-oriented system, an implementation of which has been in practical use on the MIT Lisp ...
  44. [44]
    [PDF] Traits: Composable Units of Behaviour*
    Mixins use the ordinary single inheritance operator to extend various base classes with the same set of features. However, although this inheritance operator is ...
  45. [45]
    The History of Ruby - SitePoint
    Jul 26, 2014 · The Ruby language is 21 years old. Its strong community and adoption by the open source community has kept this language steady and improving.Key Takeaways · Primary School Years · Strong Adult<|control11|><|separator|>
  46. [46]
    Default Methods - Interfaces and Inheritance - Oracle Help Center
    Default methods add new functionality to interfaces, ensuring binary compatibility. They are specified with the `default` keyword and are implicitly public.
  47. [47]
    [PDF] Fundamental Patterns Delegation (When not to use Inheritance)
    Delegation is a way of extending and reusing the functionality of a class by writing an additional class with additional functionality that uses instances of ...
  48. [48]
  49. [49]
    Handbook - Interfaces - TypeScript
    Interfaces inherit even the private and protected members of a base class. This means that when you create an interface that extends a class with private or ...Our First Interface · Excess Property Checks · Indexable Types · Class Types