Favour Composition over Inheritance - Aber Wann?
-
Du hast einen Vorschlag ohne Vererbung gebracht mit "In C++ würde ich das über freie Funktionen und Templates machen.". Und ich zeige dir ein C++ Beispiel wo dieser Ansatz zu virtuellen templates führen muss: immer dann, wenn Polymorphie im Spiel ist. Das Problem hast du nicht, wenn du direkt ableitest, sofern es in dem Kontext möglich ist.
Die Frage die FCoI impliziert: nämlich, "Wann braucht man Vererbung?" ist nicht pauschal lösbar. Man kann nicht sagen: "In Sprache X machst du das so". Bevor die Sprache ins Spiel kommt ist das eine Frage des Softwareentwurfs. Danach kommen erst die möglichen Implementationen ins Spiel.
-
otze schrieb:
Du hast einen Vorschlag ohne Vererbung gebracht mit "In C++ würde ich das über freie Funktionen und Templates machen.". Und ich zeige dir ein C++ Beispiel wo dieser Ansatz zu virtuellen templates führen muss: immer dann, wenn Polymorphie im Spiel ist. Das Problem hast du nicht, wenn du direkt ableitest, sofern es in dem Kontext möglich ist.
Die Frage die FCoI impliziert: nämlich, "Wann braucht man Vererbung?" ist nicht pauschal lösbar. Man kann nicht sagen: "In Sprache X machst du das so". Bevor die Sprache ins Spiel kommt ist das eine Frage des Softwareentwurfs. Danach kommen erst die möglichen Implementationen ins Spiel.
a) Können freie Funktionen nicht virtuell sein, weshalb Dein Beispiel etwas am von mir Geschriebenen vorbei geht.
b) Wollte ich auf die Standardalgorithmen und die Container hinweisen, wo Du Compilezeitpolymorphie hast. Aus sicht der Standardalgorithmen ist alles, was sich wie ein Randomaccess-Iterator verhält auch ein... nun ja Randomaccess-Iterator. Auch wenn Du nichtbla.puh()
schreibst.
-
otze schrieb:
Die Frage die FCoI impliziert: nämlich, "Wann braucht man Vererbung?" ist nicht pauschal lösbar. Man kann nicht sagen: "In Sprache X machst du das so". Bevor die Sprache ins Spiel kommt ist das eine Frage des Softwareentwurfs. Danach kommen erst die möglichen Implementationen ins Spiel.
Danke, das lief mir grad naemlich wieder in die Falsche Richtung.
-
Tachyon schrieb:
a) Können freie Funktionen nicht virtuell sein, weshalb Dein Beispiel etwas am von mir Geschriebenen vorbei geht.
Dann geht deine erste Antwort aber an meinem Post vorbei:
Wenn die Implementation aber so schön ist, dass du überall dort, wo du ein Array hast, auch einen Ringpuffer verwenden könntest, dann spricht das deutlich für Vererbung.
//edit (heute editiere ich zu viel...)
Mir geht es eigentlich nicht um den Gegensatz zwischen dynamischer<->statischer Polymorphie. Das ist für mich ein reines Implementationsdetail. Wenn der Softwareentwurf es zulässt, eine polymorphie zur Compilezeit aufzulösen, dann implementiert man das so. Wenn es nicht geht, dann geht es nicht. Die Sprachgegebenheiten sind da zweitrangig vor dem Entwurf.
-
otze schrieb:
[...]ohne Vererbung gebracht [...] immer dann, wenn Polymorphie im Spiel ist.
Merkst was?
Was Tachyon meinte ist eben, dass er eben NICHT den Ansatz über eine vererbte oder vererbbare Klasse gehen würde, sondern über templates. Ohne Vererbung und ohne dass Vererbung für irgendwann später vorgesehen wäre, und dementsprechend ohne dass es irgendwann zu virtuellen Methoden kommen müsste.
C++ als Multi-Paradigmensprache hat genau da einige Fallstricke, im Vergleich zu "rein objektorientierten" Sprachen wie Java oder C#: in letzteren ist so ziemlich alles vererbbar und geerbt (mindestens von Object). In C++ heißt eine Klasse noch lange nicht, dass es was mit Vererbung auch nur zu tun hat. Es gibt genügend Klassen, die by design implizit nicht für Vererbung geeignet sind. Dann gibt es Klassen, die (private) Vererbung als eine Art der Kompositoin mit engerer Bindung benutzen, und Klassen, die die Mechanismen von Vererbung in Zusammenhang mit Templates benutzen, und es gibt Klassen, die tatsächlich als Teil einer echten objektorientierten Vererbungshierarchie anzusehen sind, wie man sie im Lehrbuch findet. Diese Vielfältigkeit macht es vor allem Ein- und Umsteigern in C++ nicht unbedingt einfach. Sie ist auch der Grund, warum das FCoI der CleanCoder die afaik häufiger aus dem "saubereren" Umfeld der Java/C#-Ecke kommen, im C++-Kontext nicht so blindlings angewandt werden kann.
-
pumuckl schrieb:
otze schrieb:
[...]ohne Vererbung gebracht [...] immer dann, wenn Polymorphie im Spiel ist.
Merkst was?
Was Tachyon meinte ist eben, dass er eben NICHT den Ansatz über eine vererbte oder vererbbare Klasse gehen würde, sondern über templates. Ohne Vererbung und ohne dass Vererbung für irgendwann später vorgesehen wäre, und dementsprechend ohne dass es irgendwann zu virtuellen Methoden kommen müsste.
C++ als Multi-Paradigmensprache hat genau da einige Fallstricke, im Vergleich zu "rein objektorientierten" Sprachen wie Java oder C#: in letzteren ist so ziemlich alles vererbbar und geerbt (mindestens von Object). In C++ heißt eine Klasse noch lange nicht, dass es was mit Vererbung auch nur zu tun hat. Es gibt genügend Klassen, die by design implizit nicht für Vererbung geeignet sind. Dann gibt es Klassen, die (private) Vererbung als eine Art der Kompositoin mit engerer Bindung benutzen, und Klassen, die die Mechanismen von Vererbung in Zusammenhang mit Templates benutzen, und es gibt Klassen, die tatsächlich als Teil einer echten objektorientierten Vererbungshierarchie anzusehen sind, wie man sie im Lehrbuch findet. Diese Vielfältigkeit macht es vor allem Ein- und Umsteigern in C++ nicht unbedingt einfach. Sie ist auch der Grund, warum das FCoI der CleanCoder die afaik häufiger aus dem "saubereren" Umfeld der Java/C#-Ecke kommen, im C++-Kontext nicht so blindlings angewandt werden kann.
Ja das wird es wohl sein, das heisst wir koennen abschliessend sagen, das meine Frage im C++ Bereich nicht so einfach zu beantworten waere wie im Java/C# Bereich.
Damit ist auch alles geklaert fuer mich
-
Firefighter schrieb:
Ja das wird es wohl sein, das heisst wir koennen abschliessend sagen, das meine Frage im C++ Bereich nicht so einfach zu beantworten waere wie im Java/C# Bereich.
Damit ist auch alles geklaert fuer mich
So ein Unsinn, Objektorientiertung funktioniert in C++ genauso wie in C# oder Java.
Du gibts zu wenig Informationen, um die Frage beantworten zu können. In welcher Beziehung stehen die Personen und vor allem: Was können sie tun (welche virtuellen Methoden gibt es)?
-
Firefighter schrieb:
Aktuell sollen wir ein Projekt fuer die Uni machen wo wir ne einfache Personenhierachie einer Universitaet darstellen sollen (Personen, Studenten, Beschaeftigte, Professoren). Eigentlich ist das ein Paradebeispiel fuer Vererbung, jedoch wollte ich mich mal von der Vererbung loesen und Versuchen es mit Komposition zu loesen.
Ich seh eine Klasse Person und drei Rollen (Studenten, Beschaeftigte, Professoren).
-
Zeus schrieb:
Firefighter schrieb:
Aktuell sollen wir ein Projekt fuer die Uni machen wo wir ne einfache Personenhierachie einer Universitaet darstellen sollen (Personen, Studenten, Beschaeftigte, Professoren). Eigentlich ist das ein Paradebeispiel fuer Vererbung, jedoch wollte ich mich mal von der Vererbung loesen und Versuchen es mit Komposition zu loesen.
Ich seh eine Klasse Person und drei Rollen (Studenten, Beschaeftigte, Professoren).
Hätte ich erst mal auch so gesagt. Bis jetzt wurde ja noch nicht mal angegeben, ob irgendeiner von denen was besonderes kann bzw. für was die überhaupt da sind.
-
Wuerde es mehr Informationen geben, haette ich die euch sicherlich gegeben oder?
TyRoXx schrieb:
Firefighter schrieb:
Ja das wird es wohl sein, das heisst wir koennen abschliessend sagen, das meine Frage im C++ Bereich nicht so einfach zu beantworten waere wie im Java/C# Bereich.
Damit ist auch alles geklaert fuer mich
So ein Unsinn, Objektorientiertung funktioniert in C++ genauso wie in C# oder Java.
Ich wollte auch gar nicht ausdruecken das es mit C++ so nicht geht, aber wir haben ja in der Diskussion davor festgestellt das es Sprachabhaengig ist und schon Unterschiede macht ob ich nun in C++ oder C#/Java unterwegs bin.
-
Ich hab mir die Aufgabe nochmal eben durchgelesen und sehe gerade das sich die Klassen eigentlich nicht durch Funktionalitaet unterscheiden sondern nur durch Attribute. Da bin ich ja der Meinung das mir Vererbung nicht wirklich was nutzt.
Wenn ich keine Unterschieden im Verhalten habe sondern nur in Eigenschaften koennte man das ganze ja dann doch als Komposition aufziehen oder nicht? Ich meine Polymorphie bringt mir ja dann nicht mehr wirklich was wenn ich nen Zeiger auf ne Person irgendwo hin uebergebe und ich keine spezialisierten Funktionen habe, hab ich ja eh nur Information ueber die Personenattribute.Die Aufgaben unseres Dozenten sind nicht wirklich sinnvoll
-
Firefighter schrieb:
Ich hab mir die Aufgabe nochmal eben durchgelesen und sehe gerade das sich die Klassen eigentlich nicht durch Funktionalitaet unterscheiden sondern nur durch Attribute. Da bin ich ja der Meinung das mir Vererbung nicht wirklich was nutzt.
Ne, gerade dafür ist Polymorphie Da: Nach außen gleiches Verhalten, aber intern anderes Verhalten (oder andere Attribute).
Dinge die von Person erben verhalten verhalten sich ja gerade auch wie Personen und nicht anders. Sonst wären sie gerade keine Personen.
-
Firefighter schrieb:
Ich hab mir die Aufgabe nochmal eben durchgelesen und sehe gerade das sich die Klassen eigentlich nicht durch Funktionalitaet unterscheiden sondern nur durch Attribute. Da bin ich ja der Meinung das mir Vererbung nicht wirklich was nutzt.
So ist es.
Und ohne Vererbung kannste endlich die "Typen" ändern. Wenn ein Student plötzlich zum Mitarbeiter wird, ist das mit Vererbung gar nicht darstellbar, weil Objekte in C++ ihren Typ nicht ändern können. Und Qs Hiwi ist zwanglos darstellbar ohne irgendwelche Diamanten(Übersetzungsfehler, muß natürlich Rauten heißen).
Natürlich zu den Kosten des Risikos, daß sich das Verhalten vielleicht im Laufe des Programms doch ändert und Du Dir dann virtuelle Methoden wünschen würdest.
Firefighter schrieb:
Die Aufgaben unseres Dozenten sind nicht wirklich sinnvoll
Ich denke, wir sind uns einig, daß er Vererbung sehen will.
-
Tachyon schrieb:
Firefighter schrieb:
Ich hab mir die Aufgabe nochmal eben durchgelesen und sehe gerade das sich die Klassen eigentlich nicht durch Funktionalitaet unterscheiden sondern nur durch Attribute. Da bin ich ja der Meinung das mir Vererbung nicht wirklich was nutzt.
Ne, gerade dafür ist Polymorphie Da: Nach außen gleiches Verhalten, aber intern anderes Verhalten (oder andere Attribute).
Dinge die von Person erben verhalten verhalten sich ja gerade auch wie Personen und nicht anders. Sonst wären sie gerade keine Personen.Jaja das ist ja klar. Aber will ich meistens nicht unterschiedliches Verhalten im Sinne von unterschiedliche Implementierte Funktionen oder aehnliches die ich dann ueber einen Basiszeiger aufrufen kann und somit das Verhalten des jeweiligen Objektes(Student, Professor usw) zu erhalten. Nur gibt es bei dieser Aufgabe keinerlei solche "Verhalten" die von Klasse zu Klasse unterschiedlich sind.
-
volkard schrieb:
Ich denke, wir sind uns einig, daß er Vererbung sehen will.
Da hast du mit Sicherheit Recht. Nur ist die Frage ob ich ihm das aus praesentiere
-
Firefighter schrieb:
Jaja das ist ja klar. Aber will ich meistens nicht unterschiedliches Verhalten im Sinne von unterschiedliche Implementierte Funktionen oder aehnliches die ich dann ueber einen Basiszeiger aufrufen kann und somit das Verhalten des jeweiligen Objektes(Student, Professor usw) zu erhalten. Nur gibt es bei dieser Aufgabe keinerlei solche "Verhalten" die von Klasse zu Klasse unterschiedlich sind.
Besser immer Quoten, auf wen Du antwortest. Ich nehme an, Du hast hier den Tachyon angesprochen und gefragt.
-
Oeehh, ja klar, werd ich gleich beheben.
-
Firefighter schrieb:
Jaja das ist ja klar. Aber will ich meistens nicht unterschiedliches Verhalten im Sinne von unterschiedliche Implementierte Funktionen oder aehnliches die ich dann ueber einen Basiszeiger aufrufen kann und somit das Verhalten des jeweiligen Objektes(Student, Professor usw) zu erhalten. Nur gibt es bei dieser Aufgabe keinerlei solche "Verhalten" die von Klasse zu Klasse unterschiedlich sind.
Vererbung muss ja nicht gleich Polymorphie beinhalten. Wenn die 3 spezialisierten Typen von Person erben, kannst Du alle 3 spezialisierten Typen an all den Stellen benutzen, an denen nur eine Person erwartet wird. Das geht auch ohne Laufzeitplymorphie. Wenn die 3 spezialleren Typen nun aber Person aggregieren, dann würde das nicht mehr gehen.
Außerdem hat es rein vom Modell her einen schalen Beigeschmack, wenn ein Student eine Person hat, aber keine Person ist. Gespaltene Persönlichkeit?
-
Kannst du die Aufgabenstellung mal posten?
Denn gerade bei Personen und ihren Rollen kann es etwas tricky werden was die korrekte Lösung ist.
-
Klaro gerne:
http://www.harald-brandenburg.de/prog2/ueb/9/Aufgabe9.pdfDas einzige was sich in meinen Augen unterscheidet ist die Sortierung die er am Ende will, ja und das hat ja nun recht wenig mit den Personen zu tuen, sondern das werd ich als Strategie anbieten.