Mehrfachvererbung
-
Artchi schrieb:
Warum wird eigentlich CaesarJ entwickelt? Konnte mir bisher auch niemand von den Java-Fans beantworten?
Ich kann Dir sagen, warum Dir das keiner beantwortet: Das interessiert keinen. Und schon gar keinen "Java-Fan". Mir persönlich ist dieses Projekt völlig unbekannt, obwohl ich eigentlich regelmäßig die großen Java-Seiten im Netz abklappere. Wenn dieses Projekt in der Java Welt irgendeine Bedeutung hätte, würde es auch hin und wieder auf diesen Seiten erwähnt werden.
Mit anderen Worten: CaesarJ scheint halt so ne Idee von irgendeiner Randgruppe oder so zu sein. ...und nur weil da irgendeine Uni oder ne größere Firma mit zu tun hat, ändert sich das noch lange nicht.
Zusatz: Insgesamt scheint sich in der Java-Welt fast keiner für Mehrfachvererbung zu interessieren. Wenn irgendwelche Forderungen nach bestimmten Sprachfeatures aufkommen, sind das andere Features. "const" war zum Beispiel mal sehr begehrt. "Operator Overloading" ist auch hin und wieder im Gespräch. ...und genauso sind auch einige andere Features manchmal im Gespräch, die andere Sprachen, wie zum Beispiel C++, bieten. Es sind ja damals mit Java 5.0 auch einige Features dazugekommen, die teilweise öfter mal nachgefragt wurden. ...naja: Zumindest ist "Mehrfachvererbung" einfach nicht bei den Features dabei, die nachgefragt werden.
Zusatz 2: Top 25 RFEs: http://bugs.sun.com/bugdatabase/top25_rfes.do
-
Artchi schrieb:
Optimizer schrieb:
Artchi schrieb:
// Diese Methode würden Auto und Boot auch haben, wird hier einfach überschrieben
Genau, und ich bin der Weihnachtsmann. Welche Methode willst du denn überschreiben? Oder doch lieber Auto::bewege() und Boot::bewege()?
Auto und Boot sind virtuell abgeleitete Klassen, und du hast die Doppeldeutigkeit aufgelöst.
Beispiel:
class Auto : virtual public AutoBase { void fahre(Ort a, Ort b) { AutoBase::bewege(a, b); } }; class Boot : virtual public BootBase { void schwimme(Ort a, Ort b) { BootBase:bewege(a, b); } };
Hätte gedacht, das virtuelle Ableitung hier für dieses Problem allgemein bekannt ist.
Was bringt dieses "Gefrickel" jetzt? Für mehrere Methoden schreibst du dann sucheTankstelle -> sucheTankMöglichkeit, sucheBootshafen -> sucheTankMöglichkeit und hast jedesmal geile Methoden, die nur delegieren, hundertfach. Das sieht nur bei einer vererbten Methode noch akzeptabel aus. Du hast zwei zusätzliche Basisklassen, die keiner wollte. Sind das die großen Vorteile der Mehrfachvererbung?
Die "Doppelbelastung" hättest du auch ohne Mehrfachvererbung, nur in einem anderen Level:
class AmphibienFzg : public Auto { Boot boot; }
Oder wie hättest du das gelöst?
Man darf keine Komposition aus Auto und Boot bauen, denn AmphibienFzg enthält ja kein Auto und kein Boot. Ebenso wäre es ein Designfehler, AmphibienFzg von Auto abzuleiten, wenn es sich nicht in jeder Hinsicht wie ein Auto verhält. Dast ist natürlich programmabhängig. In GTA versinken Autos im Wasser, dort dürfte man ein AmphibienFzg nicht von Auto ableiten.
Der Kern ist, dass man eigentlich nur etwas Verhalten von Auto und Boot haben möchte. Dieses Verhalten kann man verallgemeinern und in Klassen ausmodellieren. Ich kann mir sowas vorstellen:
class AmphibienFzg : Vehicle { SharedLandfahrzeugBehaviour land; SharedWasserfahrzeugBehaviour water; }
So schafft man sich kleine Bauteile, aus denen man wie mit Legosteinen verschiedene Land-, Wasser-, und Luft-Fahrzeuge zusammenbauen kann:
class Boat : Vehicle { SharedWasserfahrzeugBehaviour water; }
class Car : Vehicle { SharedLandfahrzeugBehaviour land; }
Mögliche Codeduplizierung beschränkt sich jetzt auf das LandfahrzeugBehaviour einbinden sowohl in Auto als auch in Amphib. - ein Einzeiler. Unter manchen Umständen kann es auch noch akzeptabel sein, protected Methoden aus der Basisklasse nur in manchen abgeleiteten Klassen öffentlich zugänglich zu machen. In C++ kann man zusätzlich private Vererbung bemühen.
Aber niemals öffentlich ableiten, wenn nicht das Verhalten völlig passend ist, wie wahrscheinlich in den meisten Szenarien mit Auto und Amphib.
Konkreter kann ich jetzt nicht werden, da wir - wie gesagt - kein vernünftiges Szenario haben.
-
1310-Logik schrieb:
Das Beispiel ist doch falsch.
Ein AmphibienFz steht doch hierarchisch auf der selben Ebene wie Auto und Boot, erbt also nur von Fahrzeuge gemeinsames.Korrekt. "Amphibienfahrzeug" ist keineswegs ein konkreterer Begriff als Auto. Eher ist Auto noch was konkreteres, nämlich ein Ableitung von Landfahrzeug. Du hast genau den entscheidenden Punkt genannt.
-
Sehe ich nicht so.
"Amphibienfahrzeug" (ebenso wie Auto, Fahrrad, Dreirad, Roller)
ist eine Verfeinerung von "Fahrzeug" und gleiochzeitig eine Verfeinerung von "Boot", (gleichrangig neben Ruderboot, Dampfschiff, Kreuzer). "Amphibienfahrzeug" steht also hierarchisch auf derselben Stufe wie "Auto" (direkt abgeleitet von "Fahrzeug") und "Paddelboot" (direkt abgeleitet von "Boot").Das Beispiel "Amphibienfahrzeug" ist tatsächlich eine Anwendung, wo Mehrfachvererbung die nächstliegende Möglichkeit ist.
Ciao
-
Entschuldige, meine Basisklasse war schlecht benamst. Müsste "Fortbewegungsmittel" heissen...
Das ein Amphi. kein Auto ist, muss einleuchten, es ist auch kein Auto mit erweiterter funktionaluität. Es ist eben ein Spezialfahrzeug. Ein Panzer ist auch kein Auto, oder?
-
Keine Ursache für die Entschuldigung
Fortbewegungsmittel
/ | \
/ | \
/ | \
Landfahrzeuge Fluggeräte Wasserfahrzeuge
/ | \ ... / | \
/ | \ / | \
/ | \ / | \
Panzer Auto AMPHIBIENFAHRZEUG Tretboot Dampfschiff
... ... ... ...Ciao
-
Schade, hatte den Text ASCII-Art-mäßig sorgfältig mit blanks formatiert. Naja, die
muß man sich halt jetzt dazudenken.
-
Quodli Z. schrieb:
"Amphibienfahrzeug" (ebenso wie Auto, Fahrrad, Dreirad, Roller)
ist eine Verfeinerung von "Fahrzeug" und gleiochzeitig eine Verfeinerung von "Boot", (gleichrangig neben Ruderboot, Dampfschiff, Kreuzer).Ach so. Ein Dreirad ist eine Verfeinerung von Dampfschiff. Das leuchtet ein.
-
Fortbewegungsmittel / | \ / | \ / | \ Landfahrzeuge Fluggeräte Wasserfahrzeuge / | \ ... / | \ / | \ / | \ / | \ / | \ Panzer Auto AMPHIBIENFAHRZEUG Tretboot Dampfschiff ... ... ... ...
-
camper schrieb:
Fortbewegungsmittel / | \ / | \ / | \ Landfahrzeuge Fluggeräte Wasserfahrzeuge / | \ ... / | \ / | \ / | \ / | \ / | \ Panzer Auto AMPHIBIENFAHRZEUG Tretboot Dampfschiff ... ... ... ...
1310-Logik schrieb:
Ein Amphibienfahrzeug dürfte in einem Katalog unter "Spezialfahrzeuge" zu finden sein.
@camper: Bei Dir sind die Amphibienfahrzeuge ja offensichtlich nicht unter "Spezialfahrzeuge" zu finden. Wo würdest Du es denn in einem Katalog einsortieren. Da musst Du dich ja irgendwie entscheiden. In einem Katalog kannst Du das nicht unter zwei verschiedenen Kategorien einordnen. (...wenn Du keine Redundanz haben möchtest.)
-
ich hab nur den beitrag von quodi lesbar gemacht. das repräsentiert nicht meine meinung (hätte ich dazuschreiben sollen). letzlich ist die frage ohne eine beschreibung des problems sowieso eher müßig. es kommt doch wie imemr darauf an, was man modellieren will.
-
Wenn man beweisen will dass Mehrfachvererbung geil ist, macht man offenbar die seltsamsten Sachen. Ein schwimmfähiger Panzer wäre dann vermutlich von Amphibienfahrzeug und Panzer abgeleitet? Selbstverständlich zwei mal dann von Landfahrzeug abgeleitet, so wie Amphibienfahrzeug jetzt schon zweimal von Fortbewegungsmittel abgeleitet ist.
Kann man denn überhaupt alles bauen, indem man einfach von den richtigen Basisklassen ableitet? Kann ich Batman von Mensch und Fledermaus ableiten, Chickenwings von Hünchen und Flügeln (hat doch immerhin das Fleisch vom Hünchen und die Form eines Flügels)? Hier sieht man doch schon, dass von Anfang an falsch gedacht wird.
Wie kann man denn den abstrakten Begriff "(operationsgebiet)Fahrzeug" auf die selbe Stufe stellen wie ein konkretes Auto? Ist das Amphibienfahrzeug so speziell schon, dass es nicht mehr neben Landfahrzeug, Wasserfahrzeug, Luftfahrzeug gehört? Wieso IST ein Amphibienfahrzeug überhaupt ein Landfahrzeug? Ein Landfahrzeug kann doch nur auf dem Land fahren und versinkt im Wasser, das kann man doch unmöglich erben wollen?
Ich muss meine Meinung zu Mehrfachvererbung nochmal ändern. Bisher dachte ich nur, man braucht sie nicht. Jetzt weiß ich: sie stellt die komischsten Sachen mit den Leuten an, die sie gerne benutzen wollen.
-
Zu welcher Klasse ein Objekt gehört, bestimmen die Eigenschaften des
Objektes. Amphibienfahrzeuge besitzen Eigenschaften von Landfahrzeugen
(Verbrauch auf 100 km, Anzahl Räder,...) und Eigenschaften von Wasserfahrzeugen
(Anzahl Schrauben, Spitzengeschwindigkeit in Knoten,...) und sind daher folgerichtig als gemeinsame Spezialisierung von "Landfahrzeug" und "Wasserfahrzeug" eingeordnet. Also sollte es von diesen beiden Klassen auch die jeweils relevanten Eigenschaften erben.
"Flugboote" wären analog eine gemeinsame Spezialisierung von "Fluggerät"
und "Wasserfahrzeug".Natürlich kann man alles auch ohne Mehrfachvererbung formulieren, aber
das kann man letztendlich auch mit Turing-Code plus einer geeigneten
E/A-Codierung, was doch kein zwingender Grund ist, alle Programme in Turing-Code
zu schreiben. Wenn Mehrfachvererbung ein Programm durchschaubarer macht und
die Programmiersprache das hergibt, dann spricht nach meiner Ansicht nach nicht viel dagegen, die Mehrfachvererbung auch zu verwenden. Aber das nur nebenbei.Umso mehr - um zurück zur Fragestellung zu kommen - wundert es mich,
daß Java und Ruby, die i.a. als moderner als C++ gelten, auf Mehrfachevererbung
verzichten, andere Sprachen, die nach C++ kamen (Self, IO,...) dagegen nicht
drauf verzichten.
-
Umso mehr - um zurück zur Fragestellung zu kommen - wundert es mich,
daß Java und Ruby, die i.a. als moderner als C++ gelten, auf Mehrfachevererbung
verzichten, andere Sprachen, die nach C++ kamen (Self, IO,...) dagegen nicht
drauf verzichten.Marcus war bisher der einzig schlaue von uns allen: er hat einfach gesagt, warum Java und andere neuere Sprachen nicht dieses eine Feature haben. Und damit war für ihn die Diskussion zu ende. Entsprechend werde ich mich auch hier weiter raus halten, habe keine Lust mehr ein Feature verteidigen zu müssen.
-
Dass Mehrfachvererbung im ganzen Thread bis jetzt ausnahmslos falsch eingesetzt wurde zeigt doch nur, dass dieses Werkzeug ständig in die falschen Hände gerät.
Quodli Z. schrieb:
Zu welcher Klasse ein Objekt gehört, bestimmen die Eigenschaften des
Objektes. Amphibienfahrzeuge besitzen Eigenschaften von Landfahrzeugen
(Verbrauch auf 100 km, Anzahl Räder,...) und Eigenschaften von Wasserfahrzeugen
(Anzahl Schrauben, Spitzengeschwindigkeit in Knoten,...) und sind daher folgerichtig als gemeinsame Spezialisierung von "Landfahrzeug" und "Wasserfahrzeug" eingeordnet. Also sollte es von diesen beiden Klassen auch die jeweils relevanten Eigenschaften erben.
"Flugboote" wären analog eine gemeinsame Spezialisierung von "Fluggerät"
und "Wasserfahrzeug".Durch wiederholen wird es nicht richtiger. Amphibienfahrzeuge verfügen über Verhaltensweisen, die zu den Verhaltensweisen eines Landfahrzeuges im Gegensatz stehen. Was du eigentlich wirklich willst ist, von den Landfahrzeugen ein bisschen was raus zu nehmen, genau das, was du auch für Amphibienfahrzeuge brauchst.
Öffentliche Vererbung ist normalerweise etwas anderes. Du willlst hier nur eine Implementierung erben und noch schlimmer, du willst nur Teile der Implementierung übernehmen und dafür ist die öffentliche Vererbung nicht gedacht. Vererbung heißt konkretisieren, aber ein Amphibienfahrzeug ist keine Konkretisierung eines Landfahrzeugs, eine Konkretisierung wäre "Motorrad" oder "Auto". So wie du es jetzt machst, würde ein schwimmfähiger Panzer dann insgesamt 3mal (!) von "Fortbewegungsmittel" erben. Je mehr Fähigkeiten ein Transportmittel bekommt, desto nochmal öfter erbt es den selben Schrott immer und immer wieder.
Wo liegt die Ursache? Der Begriff "IrgendwasFahrzeug" beschreibt nur, wo sich das Fortbewegungsmittel drauf bewegen kann. Damit steht Amphibienfahrzeug neben Landfahrzeug und Wasserfahrzeug. Wenn schon Mehrfachvererbung dann richtig. Beispielsweise wäre eine richtige Anwendung, Motorboot von "motorisiertes Fahrzeug" und "Wasserfahrzeug" erben zu lassen, zwei unabhängige Klassenhierarchien! Kein Diamond of Death. Wer den Diamanten nicht kennt und beachtet, braucht mir gar nichts über Mehrfachvererbung erzählen.
EDIT: Es ist nicht so gemeint, dass "motorisiertes Fahrzeug" und "Wasserfahrzeug" dann von der selben Klasse "Fahrzeug" erben, sondern sie sollen voneinander unabhängige Konzepte darstellen. Ich nenne sie jetzt beide trotzdem Fahrzeug, aber "motorisiertes" Fahrzeug bringt nur den Motor mit.
-
Ich hab die Lösung, sie ist ganz einfach.
Und man braucht auch gar keine Mehrfachvererbung:template Fahrzeug<class Type> { what ever }
Und mit
Fahrzeug<Kröte> Amphibienfahrzeug;
hat man ein Amphibienfahrzeug!
*scnr*
-
@camper: Danke fürs Wiederherstellen der verschwundenen Blanks!