OOP: soll man jetzt alles in ne Klasse packen oder watt?
-
Shade Of Mine schrieb:
OOP hat nix mit klassen zu tun. klingt komisch, ist aber so.
Wir reden hier ja wohl nicht über OOP, oder? Namespaces haben genausowenig mit OOP zu tun, wie Klassen, in denen lauter statische Methoden anzutreffen sind. In der OOP ist "Schnittstelle" ein genau definierter Begriff, der nicht auf ein swap in irgendeinem Namespace angewandt werden kann. Deshalb frage ich nach der Definition. Auf welchen Schnittstellenbegriff beziehst Du Dich?
-
Gregor schrieb:
Auf welchen Schnittstellenbegriff beziehst Du Dich?
vergiss die namespaces. sie verwirren dich und lenken vom thema ab.
wie wuerdest du folgendes nennen?
du hast 3 Typen: Integer, int, double.
Alle 3 Typen bieten dir folgende operation an:
sqrt()du kannst
a.sqrt();
machen unabhaengig ob a jetzt den Typ Integer, int oder double hat.Wuerdest du jetzt sagen dass Integer, int und double ein interface anbieten dass sqrt implementiert?
Im prinzip schon, oder?
nun stellen wir uns vor das ganze ist nun anders rum:
Integer, int und double sind keine klassen die ein interface implementieren. sondern sie implementieren eine funktion.das selbe prinzip, nur anders rum
exakt das haben wir hier: es sind objekte. es ist polymoprhie. Es ist aber auch statisch. und sqrt gehoert nun eben zu Math. Und ich implementiere das interface indem ich sqrt spezialisiere fuer meinen typen...
-
ich kann nur ein MyInt sqrt(MyInt) anlegen genau wie ich nur ein MyInt::sqrt() anlegen kann. der sprache sichert das ab.
Nein die Sprache sichert es eben nicht ab.
Wenn Entwickler A an einem Modul Bildschirm arbeitet und Entwickler B an Modul Drucker. Beide Entwickler brauchen die Funktion sqrt(double). Entwickler A implementiert nun sqrt(double) steckt es in namespace std. Entwickler B macht genau das selbt.
Am Ende, wenn beide Module in einen Programm verwendet werden gibt es haufenweise Compilerfehler, weil es zig sqrt(double) im namespace std gibt.Wozu war das nun gut?
Anstatt das Entwickler A sein sqrt() in namespace bildschirm und Entwickler B sein sqrt() in namespace drucker reinschreibt, damit es keine Mehrdeutigkeiten gibt.
Deine Methode bietet einfach keineler Vorteile, mehr noch sie verursacht haufen Probleme.
Das selbe ist halt mit Klassen.
Zur besseren Verwaltung gleichartiger Objekte bedienen sich die meisten Programmiersprachen des Konzeptes der Klasse. Klassen sind Vorlagen, aus denen Objekte zur Laufzeit erzeugt werden (Instanzen). Im Programm werden dann nicht einzelne Objekte, sondern eine Klasse gleichartiger Objekte definiert.
Man kann sich die Erzeugung von Objekten aus einer Klasse vorstellen wie das Fertigen von Autos aus dem Konstruktionsplan eines bestimmten Fahrzeugtyps. Klassen sind die Konstruktionspläne für Objekte.
Also du willst neue Eigenschaften hinzufügen. Soetwas macht man aber durch Vererbung. Vererbung heißt aber das die Basis-Klasse inverändert bleibt. Sie wird spezialisiert durch Unterklassen.
Du aber veränderst die Basisklasse ( namespace std ) und speziallisierst sie so. Das ist kein OOP.exakt das haben wir hier: es sind objekte. es ist polymoprhie. Es ist aber auch statisch. und sqrt gehoert nun eben zu Math. Und ich implementiere das interface indem ich sqrt spezialisiere fuer meinen typen...
Deswegen gehört dein sqrt nicht mehr in Math. Dein sqrt gehört in deine Klasse / namespace what ever.
-
Gregor schrieb:
Shade Of Mine schrieb:
OOP hat nix mit klassen zu tun. klingt komisch, ist aber so.
Wir reden hier ja wohl nicht über OOP, oder? Namespaces haben genausowenig mit OOP zu tun, wie Klassen, in denen lauter statische Methoden anzutreffen sind. In der OOP ist "Schnittstelle" ein genau definierter Begriff,
der wesentlich breiter gefaßt ist, als das interface-schlüsselwort.
der nicht auf ein swap in irgendeinem Namespace angewandt werden kann.
doch.
-
DEvent schrieb:
Du aber veränderst die Basisklasse ( namespace std ) und speziallisierst sie so. Das ist kein OOP.
nö. er ändert doch keine klasse namens std. die gibt's doch gar nicht.
-
DEvent schrieb:
Deswegen gehört dein sqrt nicht mehr in Math. Dein sqrt gehört in deine Klasse / namespace what ever.
aber gern.
class Bitmap{ private: char* data; ... public: friend template<> std::swap<Bitmap&>(Bitmap& a,Bitmap& b){ std::swap(a.data,b.data); } };
gefällt die das jetzt besser?
eine klasse ist swappable, wenn sie swap anbietet. dazu muß nix geerbt werden. man muß es auch nirgends anmelden. man baut einfach swap, und dann gehört sie zum klub.
-
Shade Of Mine schrieb:
wie wuerdest du folgendes nennen?
du hast 3 Typen: Integer, int, double.
Alle 3 Typen bieten dir folgende operation an:
sqrt()du kannst
a.sqrt();
machen unabhaengig ob a jetzt den Typ Integer, int oder double hat.Polymorphie würde ich das nennen.
Shade Of Mine schrieb:
Wuerdest du jetzt sagen dass Integer, int und double ein interface anbieten dass sqrt implementiert?
Im prinzip schon, oder?
OMG!!!
Nieeeee. Ich weiß nicht, welchen Schnittstellenbegriff Du hast, bist ja immer noch nicht mit einer Definition herausgekommen, aber wenn in Deiner Definition etwas enthalten ist, das besagt, dass eine Schnittstelle etwas implementiert, dann fände ich das schon sehr sehr komisch. Eine "Schnittstelle" ist doch in jedem Fall etwas, was man unabhängig von einer Implementation definiert.
Shade Of Mine schrieb:
nun stellen wir uns vor das ganze ist nun anders rum:
Integer, int und double sind keine klassen die ein interface implementieren. sondern sie implementieren eine funktion.das selbe prinzip, nur anders rum
Hä? Verstehe ich nicht? Erstens: Was heißt "Implementierung einer Funktion"? Zweitens: Was ist da andersherum?
Shade Of Mine schrieb:
exakt das haben wir hier: es sind objekte. es ist polymoprhie. Es ist aber auch statisch. und sqrt gehoert nun eben zu Math. Und ich implementiere das interface indem ich sqrt spezialisiere fuer meinen typen...
Ich sehe den Zusammenhang zum Rest Deines Beitrags nicht. ...und ich sehe auch immer noch nicht, wie das mit der Definition des Begriffs "Schnittstelle" zusammenhängt. Mir kommt es irgendwie folgendermaßen vor: Du sagst, eine Methode bzw. dessen Signatur kann zu der Schnittstelle einer Klasse gehören. Dann sagst Du, jetzt nehmen wir die Methode da mal raus und organisieren die in einem Namespace mit anderen Methoden gleichen Namens. Dann fragst Du mich, wie man das dann nennt und erwartest als Antwort "Schnittstelle". Das stimmt aber nicht. Das ist keine Schnittstelle. Wie Du selbst sagst, ist es eben etwas ganz anderes. Das ist eine Menge von globalen Funktionen. Eine Schnittstelle ist aus meiner Sicht eine formalisierte Beschreibung (zum Beispiel der Methoden, die die Objekte einer Klasse anbieten). Was Du da hast, ist keine formalisierte Beschreibung mehr, sondern eine Gruppierung ähnlicher Funktionalität für unterschiedliche Typen. ...halt etwas völlig anderes.
-
DEvent schrieb:
Wenn Entwickler A an einem Modul Bildschirm arbeitet und Entwickler B an Modul Drucker. Beide Entwickler brauchen die Funktion sqrt(double). Entwickler A implementiert nun sqrt(double) steckt es in namespace std. Entwickler B macht genau das selbt.
Am Ende, wenn beide Module in einen Programm verwendet werden gibt es haufenweise Compilerfehler, weil es zig sqrt(double) im namespace std gibt.
Wozu war das nun gut?
fuer garnichts. du hast nicht gelesen was ich geschrieben habe.
als 1) mal: "meine" methode ist die, die man laut c++ standard macht.
und 2)sqrt wird nicht von mir erfunden. sqrt ist teil der standard library. sqrt ist fuer eine million typen definiert. ich mach nichts anderes als die ein million und erste spezialisierung zu adden.
das ist wovon ich rede:
es gibt ein interface: sqrt.das habe nicht ich erfunden. ich fuege keine neue funktion hin zu.
-
STL Doc schrieb:
template <class Assignable>
void swap(Assignable& a, Assignable& b);Ehm ok generische Programmierung.
Ehrlich gesagt ich bin total erschlagen, und weiss nicht mehr worüber diskutiert.
Wahrscheinlich tretten sich auch nur paar Programmierparadigmen
-
Gregor schrieb:
Ich sehe den Zusammenhang zum Rest Deines Beitrags nicht. ...und ich sehe auch immer noch nicht, wie das mit der Definition des Begriffs "Schnittstelle" zusammenhängt.
swap() ist eine schnittstelle, ok?
genau wie ISwapable.
Damit meine klasse nun swap() nutzen kann, muss ich die funktion spezialisieren. (ist uebrigens standard c++ - wie gesagt, dass ist nicht meine erfindung oder so, sondern der c++ standard sagt das so).es gibt nun irgendwo diese funktion std::swap() fuer int, double, string,...
nun moechte ich, dass meine klasse Bitmap dieses interface ebenfalls implementiert (normalerweise schreibt man jetzt: impelements ISwapable) und dazu muss ich lediglich die funktion std::swap() spezialisieren.
wie volkard es so schoen geschrieben hat.
Das ist keine Schnittstelle. Wie Du selbst sagst, ist es eben etwas ganz anderes. Das ist eine Menge von globalen Funktionen. Eine Schnittstelle ist aus meiner Sicht eine formalisierte Beschreibung (zum Beispiel der Methoden, die die Objekte einer Klasse anbieten).
jetzt lehnen wir uns zurueck. und betrachten das ganze von neuem:
Meine nicht-schnittstelle ist eine sammlung von globalen abstrakten funktionen (mangels besserem namen: einfach dem vertrag das void swap(T&,T&) die beiden params austauscht. es gibt keine konkrete implementierung (wie auch ISwapable keine konkrete implementierung hat) ist also quasi eine abstrakte funktion).
Ein herkoemmliches java interface ist aber was? eine sammlung von abstrakten public funktionen.
nenn es formalisierte beschreibung von aktionen die ein objekt taetigen kann - aber genau das sind meine abstrakten funktionen auch. sie definieren bestimmte aktionen die ein objekt taetigen kann. zB swap() definiert, dass das objekt "swapable" ist.
Was Du da hast, ist keine formalisierte Beschreibung mehr, sondern eine Gruppierung ähnlicher Funktionalität für unterschiedliche Typen. ...halt etwas völlig anderes.
Ich sehe da keinen unterschied:
um ISwapable zu verwenden muss meine Klasse ISwapable implementieren.
um swap nutzen zu koennen muss ich std::swap spezialisieren.es ist exakt das selbe.
vergiss klassen. klassen haben mit oop nix zu tun.
-
Hmm
Ich seh das so.
Du spezialist die std:swap, in dem du diese Funktion aufrufst und für dich benutzt, richtig?
-> Konkret ist das doch einfach nur ein Funktionsaufruf einer generische Funktion.
Ich hab mal Bjarne Stroustrup "Die C++ Programmiersprache" durchsucht, und als Schnittstellen werden alle benutztbare (also öffentliche) Funktionen bezeichnet, so herausgelesen. Es gibst richtige eigene Definition Oo.
Im gegensatz zu Java werden Schnittstellen als formale Beschreibung beschriben, diese werden mit eine Ableitung konkrete implementiert.
-
Zeus schrieb:
Im gegensatz zu Java werden Schnittstellen als formale Beschreibung beschriben, diese werden mit eine Ableitung konkrete implementiert.
Ok. Wo ist das "formale" daran? Formal heißt für mich in jedem Fall, dass ich ein Sprachmittel zur Verfügung habe, mit dem ich sagen kann: "Das da ist eine Schnittstelle!". Wie ist das in C++ gegeben? Wo ist denn die formale Schnittstellendefinition von swap?
-
lol sry vertipper in text
sollte heissen:
"In Java hingegen"Java hat die Sprachmittel
- Interface-Keyword und
- Implements-Keyword
-
Zeus schrieb:
lol sry vertipper in text
sollte heissen:
"In Java hingegen"Java hat die Sprachmittel
- Interface-Keyword und
- Implements-KeywordAh, ok. Kannst Du nochmal die Stelle im Stroustrup angeben, wo erklärt wird, was ne Schnittstelle bei C++ ist?
-
Ist das nicht viel zu theoretisch und schon eher philosophisch?
Mir ist es eigentlich egal ob es jetzt laut irgendeiner definition als Interface durchgeht oder ich es Pseude-Interface nennen muss.
Worum es geht ist, dass man auf diese Art und Weise genauso abstrakte Aktionen fuer ein Objekt definieren kann wie mit herkoemmlichen Interfaces.
In C++ hat man sowieso viele "Memberfunktionen" ausserhalb der Klasse. Aber zB ein getline() gehoert fuer mich zur Schnittstelle von string.
Schaut euch mal lisp an. Da hat man Objekte komplett ohne Klassen. Da hat man im Prinzip nur eine sammlung von globalen funktionen. Und dennoch hat man OO. In C kann ich auch OO arbeiten - natuerlich fehlen hier viele buildin features von besser ausgepraegten OO sprachen wie zB virtuelle methoden, aber auch dennoch kann ich OO programmieren. Und dann ist das Interface einer Klasse eine sammlung an globalen Funktionen.
Ist natuerlich etwas komplett anderes als das herkoemmliche 08/15 OOP, aber nur weil ich sqrt(a) statt a.sqrt() schreibe ist es doch noch lange nicht etwas komplett anderes...
-
Gregor schrieb:
Ah, ok. Kannst Du nochmal die Stelle im Stroustrup angeben, wo erklärt wird, was ne Schnittstelle bei C++ ist?
S.180 .... wie gesagt, ne richtige Definition ist das leider nicht, aber man kann es ersehen.
-
an sqrt(a) ist nichts objektorientiert, es ist rein funktional
a.sqrt() ist objektorientiert, weil der momentane zustand des objekts a berücksichtigt wird
-
a.sqrt() ist objektorientiert weil es eine Memberfunktion einer Klasse verwendet.
-
Bitte hört auf.
Memberfunktion sind Funktionen die an Objekte gebunden sind.
Klassenfunktionen sind Funktioen die an Klassen gebunden sind, also unsere lieben statische Funktion.Btw:
Klassenfunktionen können sehr wohl über ein Objekt aufgerufen werden. Die Auflösung ist sehr leicht zu realisieren (siehe C#).Python:
sqrt(self) ist aber Objektorientiert....
-
check es endlich schrieb:
an sqrt(a) ist nichts objektorientiert, es ist rein funktional
Ich glaube, in diesem Thread geht es insgesamt nicht so sehr um OOP. Also lassen wir den Aspekt besser mal weg. Die Frage ist doch eher, ob eine Gruppierung ähnlicher Funktionalität, wie Shade sie vorschlägt (alle sqrt's in std oder so), gegenüber einer Bindung der Funktionalität an irgendwelche Typen sinnvoll ist. Wenn man diese Vorgehensweise weiterdenkt, kommt man vermutlich zu dem, was hier mal als "Methodenorientierte Programmierung" vorgeschlagen wurde. Die grundsätzliche Frage ist hier also vielleicht am ehesten "OOP vs. MOP".
Hmmm... wenn ich so darüber nachdenke... das interessiert mich nicht.
Ich glaube, das ist ziemlich weit abseits des eigentlichen Themas des Threads. ...für diese MOP-Richtung ist eine Erweiterbarkeit von Namespaces (oder anderer Sprachmittel, die man zur Gruppierung nutzt) vielleicht relativ wichtig und sinnvoll, das sehe ich ein. Ob MOP insgesamt sinnvoll ist, ist ne andere Frage. Zumindest bietet auch C++ AFAIK keine wirklichen Sprachmittel, um MOP zu unterstützen. So ein Namespace ist da ein Hilfskonstrukt.
@Shade: Ich habe eigentlich auch keine Lust mehr auf diesen Thread und klinke mich deshalb an dieser Stelle aus der Diskussion aus. Ich habe das Gefühl, dass wir ziemlich stark aneinander vorbeigeredet haben. Sorry, falls ich'n bischen schwer von Begriff war.