In C ++ kann eine Klasse (direkt oder indirekt) von mehr als einer Klasse erben, was als
Mehrfachvererbung bezeichnet wird .
C # und Java beschränken Klassen jedoch auf eine einzelne Vererbung, die jede Klasse von einer einzelnen übergeordneten Klasse erbt.
Die Mehrfachvererbung ist eine nützliche Methode zum Erstellen von Klassen, die Aspekte zweier unterschiedlicher Klassenhierarchien kombinieren. Dies tritt häufig auf, wenn unterschiedliche Klassenframeworks in einer einzelnen Anwendung verwendet werden.
Wenn zwei Frameworks beispielsweise ihre eigenen Basisklassen für Ausnahmen definieren, können Sie mithilfe der Mehrfachvererbung Ausnahmeklassen erstellen, die mit beiden Frameworks verwendet werden können.
Das Problem bei der Mehrfachvererbung besteht darin, dass dies zu Mehrdeutigkeiten führen kann. Das klassische Beispiel ist, wenn eine Klasse von zwei anderen Klassen erbt, von denen jede von derselben Klasse erbt:
class A {
protected:
bool flag;
};
class B : public A {};
class C : public A {};
class D : public B, public C {
public:
void setFlag( bool nflag ){
flag = nflag; // ambiguous
}
};
In diesem Beispiel wird das flag
Datenelement durch definiert class A
. Aber class D
stammt von class B
und ab class C
, von denen beide abgeleitet sind A
, so dass im Wesentlichen zwei Kopien von flag
verfügbar sind, da zwei Instanzen von A
in D
der Klassenhierarchie sind. Welches möchten Sie einstellen? Der Compiler wird sich beschweren , dass der Verweis auf flag
in D
ist mehrdeutig . Eine Lösung besteht darin, die Referenz explizit zu disambiguieren:
B::flag = nflag;
Ein weiterer Fix besteht darin, B und C als zu deklarieren virtual base classes
bedeutet, dass nur eine Kopie von A in der Hierarchie vorhanden sein kann, wodurch Mehrdeutigkeiten beseitigt werden.
Andere Komplexitäten bestehen bei Mehrfachvererbung, z. B. die Reihenfolge, in der die Basisklassen beim Erstellen eines abgeleiteten Objekts initialisiert werden, oder die Art und Weise, wie Mitglieder versehentlich vor abgeleiteten Klassen verborgen werden können. Um diese Komplexität zu vermeiden, beschränken sich einige Sprachen auf das einfachere Einzelvererbungsmodell.
Dies vereinfacht zwar die Vererbung erheblich, schränkt jedoch auch ihre Nützlichkeit ein, da nur Klassen mit einem gemeinsamen Vorfahren Verhaltensweisen gemeinsam nutzen können. Schnittstellen verringern diese Einschränkung etwas, indem sie Klassen in verschiedenen Hierarchien erlauben, gemeinsame Schnittstellen verfügbar zu machen, selbst wenn sie nicht durch gemeinsame Nutzung von Code implementiert werden.