Zum Inhalt springen
L

Wikipedia · einfach zusammengefasst · Stand

Diamond-Problem

Das Diamond-Problem entsteht durch Mehrfachvererbung in der Objektorientierten Programmierung und Wissensmodellierung. Es kann auftreten, wenn eine Klasse D …

Inhalt4 Abschnitte
  1. 1. Grundidee des Diamond-Problems
  2. 2. Beispiel mit einem Amphibienfahrzeug
  3. 3. Lösung in C++
  4. 4. Vermeidung und alternative Konzepte

Grundidee des Diamond-Problems

Das Diamond-Problem ist ein Problem der Mehrfachvererbung in der objektorientierten Programmierung und in der Wissensmodellierung. Es entsteht, wenn eine Klasse D über zwei verschiedene Vererbungspfade, B und C, von derselben Basisklasse A abstammt. Das Vererbungsdiagramm hat dadurch die Form einer Raute (englisch „diamond“).

Die zentrale Schwierigkeit ist, dass D die Eigenschaften von A möglicherweise doppelt erbt. Dadurch kann unklar werden, welche geerbte Methode oder welches geerbte Datenmitglied verwendet werden soll. Außerdem muss entschieden werden, ob D eine gemeinsame Instanz von A oder zwei getrennte Instanzen von A enthalten soll.

Beispiel mit einem Amphibienfahrzeug

Ein Amphibienfahrzeug kann sowohl Eigenschaften eines Landfahrzeugs als auch eines Wasserfahrzeugs erben. Beide Klassen stammen wiederum von der Klasse Fahrzeug ab. Fahrzeug besitzt eine Methode zur Fortbewegung sowie die Eigenschaften Höchstgeschwindigkeit und Sitzplätze für Insassen.

Dabei entstehen mehrere Fragen und Mehrdeutigkeiten:

  • Soll sich das Amphibienfahrzeug wie ein Landfahrzeug, wie ein Wasserfahrzeug oder gleichzeitig wie beide fortbewegen?
  • Die Höchstgeschwindigkeit kann je nach Verwendung unterschiedlich sein. Dafür wären zwei verschiedene Werte sinnvoll.
  • Die Anzahl der Sitzplätze bleibt dagegen unabhängig von der Verwendung gleich. Dafür sollte nur ein Wert gespeichert werden.

Die Mehrdeutigkeit der Fortbewegung kann nur im Einzelfall gelöst werden. Im Beispiel kann das Amphibienfahrzeug zwei verschiedene Fortbewegungsarten beziehungsweise -methoden besitzen, obwohl die Klasse Fahrzeug nur eine Fortbewegungsart festlegt.

Lösung in C++

C++ erlaubt bei der Definition von B und C festzulegen, ob beide eine gemeinsame Instanz der Basisklasse A verwenden oder ob jede Klasse eine eigene Instanz von A besitzt.

Bei der Diamond-Vererbung wird A virtuell geerbt:

class B: virtual A { int b; }; class C: virtual A { int c; }; class D: B, C { int d; };

B und C verweisen dann auf Member der Oberklasse A und greifen auf dieselbe Variable a zu. D enthält damit nur eine gemeinsame Instanz von A.

Bei normaler Mehrfachvererbung lautet die Beziehung dagegen beispielsweise:

class B: A { int b; }; class C: A { int c; }; class D: B, C { int d; };

In diesem Fall besitzen B und C jeweils eigene Kopien der Member von A. D hat dadurch Zugriff auf zwei unterschiedliche Variablen a. Die virtuelle Basisklasse verhindert somit die Replikation der Member der Basisklasse in der abgeleiteten Klasse.

Vermeidung und alternative Konzepte

Wegen der möglichen Probleme unterstützen einige objektorientierte Programmiersprachen keine Mehrfachvererbung oder stellen Ersatzkonzepte bereit. Teilweise gibt es beispielsweise die Konstruktion von Zwillingsklassen.

Eiffel bietet Konstrukte namens „renaming“, mit denen Namenskonflikte bei Mehrfachvererbung transparent aufgelöst werden können. Smalltalk und Oberon verbieten Mehrfachvererbung vollständig.

Java, die .NET-Sprachen und Object Pascal erlauben ebenfalls keine Mehrfachvererbung von Klassen. Sie bieten jedoch Interfaces an. Ein Interface ist ein spezieller Typ einer abstrakten Klasse, von dem mehrfach geerbt werden kann. Dabei wird nur die Deklaration vererbt, nicht die Implementierung der Funktionen und insbesondere keine Membervariablen. Ab Java 8 können Interfaces auch Methoden enthalten; diese dürfen jedoch keine Membervariablen verwenden.

PHP verwendet ab Version 5.4 sogenannte Traits unter dem Begriff „horizontal reuse“ (horizontale Wiederverwendung). Traits sind lose Klassenfragmente, die in andere Klassen eingebunden werden können.

Weiterlesen