Diamond problem
Encyclopedia
In object-oriented programming language
s with multiple inheritance
and knowledge organization, the diamond problem is an ambiguity that arises when two classes
B and C inherit
from A, and class D inherits from both B and C. If a method
in D calls a method defined in A (and does not override
the method), and B and C have overridden that method differently, then from which class does it inherit: B, or C?
For example, in the context of GUI
software development
, a class
It is called the "diamond problem" because of the shape of the class inheritance diagram in this situation. In this article, class A is at the top, both B and C separately beneath it, and D joins the two together at the bottom to form a diamond shape.
, Ruby
, Objective-C
, PHP
, C#, Delphi
/Free Pascal
and Java
) allow the multiple inheritance of interfaces (called protocols in Objective-C). Interfaces are essentially abstract base classes with all abstract methods and no data members. The problem is therefore less likely since there is in most cases only one implementation of a specific method or property. Ambiguity can arise when multiple interfaces declare the same methods and the class defines them separately. See explicit interfaces.
The diamond problem is not limited to inheritance. It also arises in languages such as C
and C++
when header file
s A, B, C, and D
s are created from B and C. If these two precompiled headers are combined, declarations in A are duplicated and the
is ineffective. It also is found when composing middleware
stacks; for example, if A is a database and B and C are caches
, D may ask both B and C to commit
a transaction, resulting in duplicate commit calls to A.
Programming language
A programming language is an artificial language designed to communicate instructions to a machine, particularly a computer. Programming languages can be used to create programs that control the behavior of a machine and/or to express algorithms precisely....
s with multiple inheritance
Multiple inheritance
Multiple inheritance is a feature of some object-oriented computer programming languages in which a class can inherit behaviors and features from more than one superclass....
and knowledge organization, the diamond problem is an ambiguity that arises when two classes
Class (computer science)
In object-oriented programming, a class is a construct that is used as a blueprint to create instances of itself – referred to as class instances, class objects, instance objects or simply objects. A class defines constituent members which enable these class instances to have state and behavior...
B and C inherit
Inheritance (computer science)
In object-oriented programming , inheritance is a way to reuse code of existing objects, establish a subtype from an existing object, or both, depending upon programming language support...
from A, and class D inherits from both B and C. If a method
Method (computer science)
In object-oriented programming, a method is a subroutine associated with a class. Methods define the behavior to be exhibited by instances of the associated class at program run time...
in D calls a method defined in A (and does not override
Method overriding (programming)
Method overriding, in object oriented programming, is a language feature that allows a subclass or child class to provide a specific implementation of a method that is already provided by one of its superclasses or parent classes...
the method), and B and C have overridden that method differently, then from which class does it inherit: B, or C?
For example, in the context of GUI
Gui
Gui or guee is a generic term to refer to grilled dishes in Korean cuisine. These most commonly have meat or fish as their primary ingredient, but may in some cases also comprise grilled vegetables or other vegetarian ingredients. The term derives from the verb, "gupda" in Korean, which literally...
software development
Software development
Software development is the development of a software product...
, a class
Button
may inherit from both classes Rectangle
(for appearance) and Clickable
(for functionality/input handling), and classes Rectangle
and Clickable
both inherit from the Object
class. Now if the equals
method is called for a Button
object and there is no such method in the Button
class but there is an overridden equals
method in both Rectangle
and Clickable
, which method should be eventually called?It is called the "diamond problem" because of the shape of the class inheritance diagram in this situation. In this article, class A is at the top, both B and C separately beneath it, and D joins the two together at the bottom to form a diamond shape.
Approaches
Different programming languages have addressed this problem in different ways:- C++C++C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
by default follows each inheritance path separately, so aD
object would actually contain two separateA
objects, and uses ofA
's members have to be properly qualified. If the inheritance fromA
toB
and the inheritance fromA
toC
are both marked "virtual
" (for example, "class B : virtual public A
"), C++ takes special care to only create oneA
object, and uses ofA
's members work correctly. If virtual inheritanceVirtual inheritanceVirtual inheritance is a topic of object-oriented programming. It is a kind of inheritance in which the part of the object that belongs to the virtual base class becomes common direct base for the derived class and any next class that derives from it...
and nonvirtual inheritance are mixed, there is a single virtualA
and a nonvirtualA
for each nonvirtual inheritance path toA
. Please note that nonvirtual derivation of A in this case will be useless as direct access to any part of class A from class D will practically always end up with compile error. - Common LispCommon LispCommon Lisp, commonly abbreviated CL, is a dialect of the Lisp programming language, published in ANSI standard document ANSI INCITS 226-1994 , . From the ANSI Common Lisp standard the Common Lisp HyperSpec has been derived for use with web browsers...
attempts to provide both reasonable default behavior and the ability to override it. By default, the method with the most specific argument classes is chosen; then in the order in which parent classes are named in the subclass definition. However, the programmer can override this, by giving a specific method resolution order or stating a rule for combining methods. - EiffelEiffel (programming language)Eiffel is an ISO-standardized, object-oriented programming language designed by Bertrand Meyer and Eiffel Software. The design of the language is closely connected with the Eiffel programming method...
handles this situation by select and rename directives, where the ancestors' methods to use in a descendant are explicitly specified. This allows the methods of the base class to be shared between its descendants or to even give each of them a separate copy of the base class. - PerlPerlPerl is a high-level, general-purpose, interpreted, dynamic programming language. Perl was originally developed by Larry Wall in 1987 as a general-purpose Unix scripting language to make report processing easier. Since then, it has undergone many changes and revisions and become widely popular...
and Io handle this by specifying the inheritance classes as an ordered list. In the above ambiguity, classB
and its ancestors would be checked before classC
and its ancestors, so the method inA
would be inherited throughB
. In Perl, this behavior can be overridden using themro
or other modules to use C3 linearizationC3 linearizationIn computing, the C3 superclass linearization is an algorithm used primarily to obtain a consistent linearization of a multiple inheritance hierarchy in object-oriented programming. This linearization is used to resolve the order in which methods should be inherited, and is often termed "MRO" for...
or other algorithms. - PythonPython (programming language)Python is a general-purpose, high-level programming language whose design philosophy emphasizes code readability. Python claims to "[combine] remarkable power with very clear syntax", and its standard library is large and comprehensive...
had to deal with this upon the introduction of new-style classes, all of which have a common ancestor,object
. Python creates a list of a classes using the C3 linearizationC3 linearizationIn computing, the C3 superclass linearization is an algorithm used primarily to obtain a consistent linearization of a multiple inheritance hierarchy in object-oriented programming. This linearization is used to resolve the order in which methods should be inherited, and is often termed "MRO" for...
algorithm. That algorithm enforces two constraints: children precede their parents and if a class inherits from multiple classes, they are kept in the order specified in the tuple of base classes. Thus, the method resolution order is:D
,B
,C
,A
. - Scala resolves method names using a right-first depth-first search of extended 'traits', before eliminating all but the last occurrence of each module in the resulting list. So, the resolution order is: [
D
,C
,A
,B
,A
], which reduces down to [D
,C
,B
,A
]. - JavaFX ScriptJavaFX ScriptJavaFX Script is a scripting language designed by Sun Microsystems, forming part of the JavaFX family of technologies on the Java Platform.JavaFX targets the Rich Internet Application domain , specializing in rapid development of visually rich applications for the desktop and mobile markets...
in version 1.2 allows multiple inheritance through the use of mixinsMixinIn object-oriented programming languages, a mixin is a class that provides a certain functionality to be inherited or just reused by a subclass, while not meant for instantiation , Mixins are synonymous functionally with abstract base classes...
. In case of conflict, the compiler prohibits the direct usage of the ambiguous variable or function. Each inherited member can still be accessed by casting the object to the mixin of interest, e.g.(individual as Person).printInfo;
.
Other examples
Languages that allow only single inheritance (such as AdaAda (programming language)
Ada is a structured, statically typed, imperative, wide-spectrum, and object-oriented high-level computer programming language, extended from Pascal and other languages...
, Ruby
Ruby (programming language)
Ruby is a dynamic, reflective, general-purpose object-oriented programming language that combines syntax inspired by Perl with Smalltalk-like features. Ruby originated in Japan during the mid-1990s and was first developed and designed by Yukihiro "Matz" Matsumoto...
, Objective-C
Objective-C
Objective-C is a reflective, object-oriented programming language that adds Smalltalk-style messaging to the C programming language.Today, it is used primarily on Apple's Mac OS X and iOS: two environments derived from the OpenStep standard, though not compliant with it...
, PHP
PHP
PHP is a general-purpose server-side scripting language originally designed for web development to produce dynamic web pages. For this purpose, PHP code is embedded into the HTML source document and interpreted by a web server with a PHP processor module, which generates the web page document...
, C#, Delphi
Delphi
Delphi is both an archaeological site and a modern town in Greece on the south-western spur of Mount Parnassus in the valley of Phocis.In Greek mythology, Delphi was the site of the Delphic oracle, the most important oracle in the classical Greek world, and a major site for the worship of the god...
/Free Pascal
Free Pascal
Free Pascal Compiler is a free Pascal and Object Pascal compiler.In addition to its own Object Pascal dialect, Free Pascal supports, to varying degrees, the dialects of several other compilers, including those of Turbo Pascal, Delphi, and some historical Macintosh compilers...
and Java
Java (programming language)
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...
) allow the multiple inheritance of interfaces (called protocols in Objective-C). Interfaces are essentially abstract base classes with all abstract methods and no data members. The problem is therefore less likely since there is in most cases only one implementation of a specific method or property. Ambiguity can arise when multiple interfaces declare the same methods and the class defines them separately. See explicit interfaces.
The diamond problem is not limited to inheritance. It also arises in languages such as C
C (programming language)
C is a general-purpose computer programming language developed between 1969 and 1973 by Dennis Ritchie at the Bell Telephone Laboratories for use with the Unix operating system....
and C++
C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
when header file
Header file
Some programming languages use header files. These files allow programmers to separate certain elements of a program's source code into reusable files. Header files commonly contain forward declarations of classes, subroutines, variables, and other identifiers...
s A, B, C, and D
#include
one another in a diamond as above and separate precompiled headerPrecompiled header
In computer programming, a precompiled header is a technique used by some C or C++ compilers to reduce compilation time.-Overview:In the C and C++ programming languages, a header file is a file whose text may be automatically included in another source file by the C preprocessor by the use of a...
s are created from B and C. If these two precompiled headers are combined, declarations in A are duplicated and the
#ifndef
include guardInclude guard
In the C and C++ programming languages, an #include guard, sometimes called a macro guard, is a particular construct used to avoid the problem of double inclusion when dealing with the #include directive...
is ineffective. It also is found when composing middleware
Middleware
Middleware is computer software that connects software components or people and their applications. The software consists of a set of services that allows multiple processes running on one or more machines to interact...
stacks; for example, if A is a database and B and C are caches
Database caching
Many applications today are being developed and deployed on multi-tier environments that involve browser-based clients, web application servers and backend databases...
, D may ask both B and C to commit
Commit (data management)
In the context of computer science and data management, commit refers to the idea of making a set of tentative changes permanent. A popular usage is at the end of a transaction. A commit is an act of committing.-Data management:...
a transaction, resulting in duplicate commit calls to A.