[C++ vs. Java] Und es gibt sie doch in Java: Multiple Inheritance
-
Ich bin gerade ein bisschen verwirrt.
Die Javaianer behaupten ja von sich, keine
multiple inheritance zu kennen.
ABER:
Ein Klassentyp S kann zwar als Supertypen nur eine einzige Klasse T haben,
aber beliebig viele Interfacetypen T1,T2...,T(n-1),Tn.
Ich verstehe nun nicht, warum man so radikal ist und sagt,
weil die Schnittstellentypen abstrakte Klassen sind,
gilt es nicht als multiple inheritance, von mehreren
von ihnen auf einmal abzuleiten.
-
Es ist keine klassische Mehrfachvererbung.
interface Foo1 { void foo(); } interface Foo2 { void foo(); }
Wenn du diese beiden Interfaces implementierst, hast du eine Methode foo(), in C++, wenn du von zwei abstrakten Klassen die abstrakten Methoden erben würdest, hättest du beide (und müsstest sowohl Foo1::foo() als auch Foo2::foo() implementieren).
Es ist auch aus anderen Gründen nicht das selbe. Ein Interface zu implementieren ist daher nicht mit dem erben von einer ABC in C++ zu vergleichen.
-
struct A { virtual void f()=0; }; struct B { virtual void f()=0; }; struct C : A, B { void f(){} }; int main() { C c; c.f(); }
Comaeu mag das
-
Stimmt, wenn du beide abstrakt erbst, geht es sogar. Aber spätestens, wenn eine konkret ist, sollte es nicht mehr gehen. Also das selbe ist es definitiv nicht.
-
Optimizer schrieb:
Also das selbe ist es definitiv nicht.
Ich habe damit lediglich gezeigt, dass C++ interfaces im java Sinn unterstützt und dass man bei Java keinen Vorteil mit Interfaces hat, sondern das selbe auch in C++ machen kann.
-
Vererbung schließt die Möglichkeit ein Dinge von der Basisklasse weiterzubenutzen, bzw. ist das, was Vererbung ausmacht (denk mal daran, was Vererbung im biologischen Sinn bedeutet: Eigenschaften von den Eltern übernehmen).
Durch das Implementieren eines Interfaces stellst du lediglich eine Subtyp-Beziehung her, erbst aber nichts.
-
// Es gibt halt noch mehr, was closeable ist, z.B. ein Socket. struct Closeable // sei ein Interface { virtual void close() = 0; }; // Interface für Buffer struct Buffer { virtual void close() = 0; }; struct Stream { virtual void close() {} }; struct FileStream : public Stream, Closeable { virtual void close() {} }; struct BufferedFileStream : public FileStream, Buffer { // causes implicit closing of the stream void anotherMethod() { close(); } }; int main() { BufferedFileStream x; x.close(); }
Der Aufruf in anotherMethod ist mehrdeutig, was nicht im Java-Sinne ist. In Java würde die Methode von FileStream genommen wäre, weil die in Closeable und Buffer eh abstrakt sind. In C++ hast du jetzt hier 3 verschiedene close(). Ich bitte die Länge des Beispiels zu entschuldigen, es läuft gerade Home Improvement und ich hab ein bisschen rumprobieren müssen. Es lässt sich sicher ein einfacherer Fall finden.
Ob das Verhalten hier für dich ein Nachteil ist, kannst du natürlich bewerten wie du willst, aber es ist nicht das, was man Sprachen wie Java und C# unter einem Interface verstehen würde.
-
btw. ein Interface ist für mich genau das, was es heißt: eine Schnittstelle. Man könnte sagen, in C++ existiert nicht direkt ein Mechanismus, um eine Schnittstelle zu spezifizieren. Wenn ich in einem Template einen Typ T benutze, geht das gut, wenn T eine bestimmte Schnittstelle (Operatoren, Methoden) implementiert. Wenn nicht, dann stellt der Compiler fest, dass irgendne Methode fehlt.
In Java oder C# muss man in den Generics die Schnittstellen vorher angeben, die man nutzen will und man hat Sprachmittel, um zu spezifizieren, welcher Typ welche Schnittstellen implementiert. In C++ implementiert man die Schnittstelle einfach, hat aber keine Möglichkeit zu sagen, dass eine bestimmte Schnittstelle von einem bestimmten Typ implementiert ist.
Das Implementieren von Interfaces ist IMHO nicht direkt etwas, was mit Vererbung zu tun haben muss (siehe Helium).btw. gibt es in C# auch Interfaces mit structs, structs kennen aber keine Vererbung.