Performancemythen?



  • Xin schrieb:

    Wenn Du als mathematisch geschulter Mensch "schwammig" als mathematisch akzeptabel beschreibst, dann habe ich den Verdacht, dass der recht umfangreiche Anteil Deines Studiums Mathematik dadurch zustande kam, weil Du die Matheschein nie beim erstenmal bekommen hast. Das ist allerdings eine reine Mutmaßung, keine Behauptung.

    War mir fast klar, dass jetzt sowas in der Art kommt. Ich weiß was ich kann. Du bist nicht in der Position das in Frage zu stellen. Dementsprechend ist meine Motivation Dir jetzt irgendwas zu beweisen ziemlich gering. Aber ich kann natürlich meinerseits Vermutungen über Deinen mathematischen Bildungsstand tätigen sowie Deine Erfahrung in logischem Schließen. Über meine Studienleistungen bewahre ich jetzt einfach mal stillschweigen... wäre der Abschluß zu gut, dann bin ich ja völlig unbrauchbar und hab nur auswendig gelernt, ist er zu schlecht bin ich gleich doof. Und notfalls war's halt einfach ne Billiguni. Auf diese Kindereien hab ich einfach keinen Bock.



  • Ich versuch mal eine weniger schwammige definition aufzustellen(ich hab kein mathematisches Studium und bin kein Diplominformatiker, darum: kreuzigt mich nicht).

    Die Objektorientierte Programmierung versucht die Eigenschaften, abhängigkeiten und interaktionsmöglichkeiten von Objekten zu abstrahieren und als programmcode zu modellieren. Die OOP versucht somit, die Denkweise des Menschen direkt als programmcode umzusetzen.

    Ein Objekt ist eine Abstraktion eines Physischen oder logischen Gegenstandes. Objekte zeichnen sich dadurch aus, dass sie Zustände und logische Abhängigkeiten untereinander besitzen. Diese Abhängigkeiten können in Form von Vererbung,Komposition oder Interaktion ausgedrückt werden. Der Zustand eines Objektes ist gekapselt und die kontrolle über ihn obliegt allein dem Objekt.

    //edit hmm lange nicht komplett. schwer zu definieren. wie bringt man zb rein, dass Funktionen als Objekte augefasst werden können oder dass sogar der Programmcode selbst ein Objekt ist?



  • Xin schrieb:

    Wenn Du als mathematisch geschulter Mensch "schwammig" als mathematisch akzeptabel beschreibst, dann habe ich den Verdacht, dass der recht umfangreiche Anteil Deines Studiums Mathematik dadurch zustande kam, weil Du die Matheschein nie beim erstenmal bekommen hast. Das ist allerdings eine reine Mutmaßung, keine Behauptung.

    Dafür bekommst du inf *lol*-Punkte. Echt.



  • Shade Of Mine schrieb:

    Xin schrieb:

    Die Frage 1: Ich programmiere kein Lisp, ich kann dazu keine brauchbare Meinung vertreten. Ich habe mal Google angeworfen, dort wird LISP nachgesagt, dass es wohl OOP kann. Da ich Lisp nicht programmiere und für die Antwort hier auch nicht mal eben schnell lerne, kann ich dazu aber nichts sagen. Ich sehe aber auch nicht, warum grade LISP hier eine große Rolle spielen sollte.

    OK, das ist der Beweis: du kennst nur C++/Java und baust darauf deine kleine OO Welt auf.

    Es beweist, dass ich kein brauchbare Erfahrung in LISP habe, um damit zu argumentieren.

    Shade Of Mine schrieb:

    Macht also keinen Sinn mehr zu diskutieren. Deshalb kleiner Tip an dich: schau dich mal um welche OO Features OO ohne Klassen zu programmieren - siehe zB JavaScript. Man kann sich zwar Objekte so hinbiegen dass sie ein bisschen wie Klassen wirken, aber man verliert dadurch soviel was JS einem bieten kann.

    Ich habe OO in JS programmiert, um SVG Dokumente zu bearbeiten und habe dafür u.a. grafische Elemente programmiert, wie Buttons, Listenwidgets usw.

    Shade Of Mine schrieb:

    Frage 2: Kommt auf die Implementierung an, ich sehe kein Problem mit Prototypen oder Klonen von Objekten.

    Aber man hat keine virtuellen funktionen.

    Wo steht, dass man virtuelle Funktionen oder Klassen für OOP braucht?
    Man braucht eine Methode, um OOP umzusetzen und das geht in C++ in der Regel mit virtuelle Methoden.
    Man könnte auch z.B. Funktionszeiger verwenden. Es reicht jedenfalls nicht "plain classes" zu nehmen.

    Shade Of Mine schrieb:

    Frage 3: Überlade in C++ mal z.B. operator +(). Die ist abhängig von zwei Datentypen. Quasi eine Multimethode. Trotzdem ist operator +() keine virtuelle Methode, sondern poplige Überladung.
    Lass es mich anders ausdrücken. Virtuelle Funktionen sind besser als Multimethoden aus dem gleichen Grund warum Steine besser als Hosen sind. Beides hat nichts miteinander zu tun.

    Geil. Du weisst nicht was multimethoden sind aber versuchst mitzureden 😉
    multimethoden dispatchen zur laufzeit wenn nötig.

    Ich war in dem Moment bei Überladen in etwa der Form:

    bool operator =( BasisObjekt & lhs, BasisObjekt &rhs )
    

    so dass die OO-Möglichkeiten über virtuelle Basisobjekte realisiert würden.
    Mea culpa.

    Wie ich schon zuvor schrieb: sobald man sich irgendwo einen Irrtum erlaubt, wird es als ultimativer Beweis gewertet. Ich seh's positiv: Ich habe sehr viele Antworten geschrieben, ohne mir Fehler zu erlauben.
    Im Verhältnis liege ich damit weiterhin recht gut.

    Shade Of Mine schrieb:

    Die übliche Definition ist also Deiner Aussage nach, dass es nicht genau zu definieren ist. Und damit ist die Mehrzahl dann zufrieden?
    Klasse Definition.

    Exakt. Weil es eine Denkweise und keine technik ist.

    weil...

    Ich lese immer nur Behauptungen und "Du hast nicht recht".

    Shade Of Mine schrieb:

    Und genau das ist der Punkt: eine Sprache ist nicht OO sondern ein Programm. C++ unterstützt OO features wie vererbung, polymorphie aber man muss nicht OO programmieren. in der tat sind die meisten C++ programme nicht rein OO.

    Rein "OO"? Was ist denn reines "OO"?
    Ist das sowas wie "Anfänger OO" und "Experten OO", was ich hier schon lesen musste?
    Entweder ist es "OO" oder nicht "OO".
    Abgesehen davon, dass es bei Dir auch schmutziges OO zu geben scheint, unterscheidest Du wenigstens zwischen OO-Sprache - sie es nicht gibt - und OO-unterstützende Sprachen. Wir sind uns diesbezüglich also einig.

    Shade Of Mine schrieb:

    Der Spaß heißt Reflection. Falsche Baustelle.

    Nein, ein sehr relevanter Punkt: wie dynamisch muss Polymorphie sein damit sie polymorphie ist?

    Ich sehe hier keine Relevanz. Begründe, warum Du sie siehst.
    Für OO muss ich zur Laufzeit auf überschriebene Funktionen zugreifen können, die objekt orientiert ausgewählt werden. Ich muss die Funktionen aber nicht zur Laufzeit austauschen können. Das ist die Baustelle von Reflection.

    Shade Of Mine schrieb:

    Bei wikipedia wird zB überladung bereits zur polymorphie gezählt. ist es nicht interessant dass deine definition nicht die einzig mögliche ist?

    Überladung gehört zur Polymorphie. Das entspricht meiner Definition.
    Überladung ist ein Part der Polymorphie, der nicht für OOP notwendig ist.
    Das Überschreiben hingegen ist notwendig. Das könnte ein Grund sein, warum man zwischen Überschreiben und Überladen unterscheidet?

    Shade Of Mine schrieb:

    zumal du ausser C++ und Java nichts kennst

    *smile*
    Das lohnt einen Kommentar einfach nicht.

    Shade Of Mine schrieb:

    Ich kann dir wirklich nur ans herz legen deinen horizont zu erweitern. Sprachen wie Self und LISP lernen dir ein komplett neues verständnis von OOP. Deshalb verstehst du uns hier auch nicht. Wir sind von dem Klassen denken komplett weg. Und ohne Klassen keine Vererbung und keine virtuellen Funktionen.

    Vererbung und virtuelle Funktion geht problemlos ohne Klassen, aber nicht ohne Klassifizierung.
    C hat keine Klassen und man kann trotzdem OOP verwenden.

    Damit Klassifizierung einfacher zu beschreiben ist, hat man in C++ Klassen.

    Lies meine Postings, alles schon längst beschrieben.



  • Xin schrieb:

    Exakt. Weil es eine Denkweise und keine technik ist.

    weil...

    Ich lese immer nur Behauptungen und "Du hast nicht recht".

    Hä?

    "Das ist ein Apfel" -- "Weil?" Was soll man denn dadrauf antworten? Es ist nicht logisch, dass ein Apfel "Apfel" heißt... es ist einfach so.



  • Xin schrieb:

    Entweder ist es "OO" oder nicht "OO".

    klingt sehr vereinfacht. warum muss alles schwarz oder weiß sein? kann nicht etwas grau sein?

    in c++ habe ich zB programme die teilweise aus reinem C code bestehen - weil es eben alter Code ist, der nach und nach an C++ angepasst wird. Ist jetzt alles OO oder sind nur teile OO oder ist garnichts OO?

    Abgesehen davon, dass es bei Dir auch schmutziges OO zu geben scheint, unterscheidest Du wenigstens zwischen OO-Sprache - sie es nicht gibt - und OO-unterstützende Sprachen. Wir sind uns diesbezüglich also einig.

    Was ist schmutziges OOP?
    Ich betone doch die ganze Zeit, dass OO deine Denkweise ist. Also gibt es in meinen Augen auch keine OO Sprachen.

    Wenn du JS programmiert hast - dann erklär mir mal fix wieso du dort keine OO hast. Oder hast du sie doch - wenn ja, dann widersprichst du dir ja, weil es in JS keine virtuellen Funktionen gibt. Es gibt kein dynamisches dispatchen.

    Ich sehe hier keine Relevanz. Begründe, warum Du sie siehst.
    Für OO muss ich zur Laufzeit auf überschriebene Funktionen zugreifen können, die objekt orientiert ausgewählt werden. Ich muss die Funktionen aber nicht zur Laufzeit austauschen können. Das ist die Baustelle von Reflection.

    Warum?
    Ich rede nicht von austauschen zur Laufzeit. Ich rede einfach nur von Laden von Klassen zur Laufzeit. Warum ist es Polymorphie wenn ich die Klassen die es gibt doch eh statisch vor mir habe? Wo trennst du ab wann etwas zu statisch für Polymorphie wird.

    Nehmen wir das Shape-Circle-Triangle Beispiel. So wirklich toll dynamisch ist es nicht, weil ich ja nur Circle und Triangle habe. Warum ist es dennoch Polymorphie? Schließlich stehen die Klassen zur Compiletime fest die es gibt. Wirklich dynamisch wäre es erst, wenn man zur Laufzeit unendliche neue Klassen nachladen würde.

    Worauf ich hinaus will ist: du ziehst einen Trennstrich den es nicht mehr gibt. Moderne VMs wie Java und .NET erlauben es die Compiletime der Runtime gleichzusetzen. Es gibt keine "das ist statisch" und "das ist dynamisch" Situationen mehr. Denn die Kompilierung findet während der Laufzeit statt und ich kann jederzeit neue Elemente nachladen.

    Shade Of Mine schrieb:

    Überladung gehört zur Polymorphie. Das entspricht meiner Definition.
    Überladung ist ein Part der Polymorphie, der nicht für OOP notwendig ist.
    Das Überschreiben hingegen ist notwendig. Das könnte ein Grund sein, warum man zwischen Überschreiben und Überladen unterscheidet?

    Nach welchen Gesichtspunkten trennst du Polymorphie? Einfach wie du lustig bist...? Du sagst wunderschön dieser Teil ist OO, dieser Teil nicht - aber erklär echt mal wie du JS siehst: es gibt keine Vererbung, keine Polymorphie - es gibt dort nur Objekte.

    Vererbung und virtuelle Funktion geht problemlos ohne Klassen, aber nicht ohne Klassifizierung.
    C hat keine Klassen und man kann trotzdem OOP verwenden.

    Vererbung ist für dich also auch Object Cloning?



  • otze schrieb:

    Ich versuch mal eine weniger schwammige definition aufzustellen(ich hab kein mathematisches Studium und bin kein Diplominformatiker, darum: kreuzigt mich nicht).

    Keine Sorge, der Versuch ist nicht strafbar. 😉

    Wenn Du OOP definierst, warum definierst Du dann, was ein Objekt ist und was man damit machen darf und was nicht?

    Wir sind uns einig, dass ein Objekt "irgendein Ding" ist. Belassen wir es doch dabei, wo liegt der Vorteil sich einzuschränken?
    Damit der Computer Objekte unterscheiden kann, benötigt ein Objekt eine Typinformation, darum leitet sich in Java alles von Object ab und für RTTI benötigt man in C++ ein Objekt, dass mindestens einen virtuellen Destruktor enthält. Objekte ohne virtuellen Destruktor haben diese Information nicht, können aber trotzdem "irgendein Ding" beschreiben, sind also Objekte.

    Um sich am Objekt orientieren zu können, benötigt man etwas, woran man sich orientieren kann. Das kann die VTable sein, die erstellt wird, sobald man die erste virtuelle Funktion erstellt.
    Man kann Objekte aber auch unterscheiden, in dem man jedem Objekttyp eine ID verpasst und danach entscheidet. Das ist sehr unschön, aber darüber lässt sich OOP realisieren.
    Man kann auch jedem Objekt Funktionspointer mitgeben, die - abhängig vom Objekt - angeben, wo man hinspringt. Die müssen objekttypabhängig initialisiert werden und obwohl sie vom (statischen) Typ abhängig sind, finden sie sich nicht in einer statischen Jumptable, sondern im Objekt.

    Für Multimethoden gilt das gleiche: Der Objekttyp muss im Objekt bekannt sein. Statt über Jumptable zu gehen, untersucht man die ObjektTypen und entscheidet sich dann für die passende Funktion.

    In allen Fällen wird abhängig vom Objekttyp gehandelt. Das alles ist OOP. Und das ist auch die Definition von OOP:
    "OOP liegt vor, wenn Objekte sich abhängig von ihrem Objekttyp verhalten und nicht abhängig vom ReferenzTyp, der auf das Objekt zeigt.":

    #include <iostream>
    
    class Tier 
    { 
      public: 
        void GibLaut() { std::cout << "Hallo!"; }   // mit virtual wäre es OOP.
    }; 
    
    class Katze : public Tier 
    { 
      public: 
        void GibLaut() { std::cout << "Miau"; } 
    };
    
    int main( void )
    {
      class Tier * tier  = new Katze(); 
      tier->GibLaut();  
    }
    

    Jester schrieb:

    Xin schrieb:

    Exakt. Weil es eine Denkweise und keine technik ist.

    weil...

    Ich lese immer nur Behauptungen und "Du hast nicht recht".

    Hä?

    "Das ist ein Apfel" -- "Weil?" Was soll man denn dadrauf antworten? Es ist nicht logisch, dass ein Apfel "Apfel" heißt... es ist einfach so.

    OOP ist eine Technik. Ich habe ausführlich erklärt warum. Grade eben wieder. Es geht also doch.



  • Xin schrieb:

    In allen Fällen wird abhängig vom Objekttyp gehandelt. Das alles ist OOP. Und das ist auch die Definition von OOP:
    "OOP liegt vor, wenn Objekte sich abhängig von ihrem Objekttyp verhalten und nicht abhängig vom ReferenzTyp, der auf das Objekt zeigt.":

    Und warum genau ist dann die Definition
    "Objekt orientierung bedeutet sich an den Objekten zu orientieren [was das verhalten des Programmes betrifft]" falsch?

    Du wandelst dich langsam doch noch in die richtige Richtung - auch wenn dasn eine 180° Kurve ist.

    Nichts anderes als das sagen wir hier die ganze Zeit: OOP ist eine Denkweise in der das Objekt das Zentrum dastellt. Ich brauche dafür aber keine dynamische Polymorphie - ich kann das auch mit statischer machen - solange das Objekt das Zentrum ist, das Objekt das verhalten festlegt.

    PS:
    deine Definition impliziert dass es Typen und Referenzen gibt - 2 Sachen die ich nicht unbedingt voraussetzen würde um ein OO Programm zu haben.



  • Xin schrieb:

    "OOP liegt vor, wenn Objekte sich abhängig von ihrem Objekttyp verhalten und nicht abhängig vom ReferenzTyp, der auf das Objekt zeigt.":

    Das ist aber unlogisch. Ein Objekt muss sich immer so verhalten, wie der Referenztyp der auf es zeigt, denn der Referenztyp gibt die definition darüber, was das Objekt ist. Du kannst das Objekt nicht anders verwenden als der Referenztyp zulässt, und der Objekttyp darf sich niemals anders verhalten als das was die zusicherungen erlauben.

    Im Zuge dieser Definition ist es völlig egal, ob sich nun der Referenztyp selbst um das verhalten kümmert, oder ob in anderes Objekt diese Arbeit erledigt, es gilt immer "pacta sunt servanda"- verträge müssen eingehalten werden. Solange dies gilt ist es für den aufrufer nebensächlich, was passiert, er fordert einen vertrag ein, und das Objekt kümmert sich darum, das er eingehalten wird.

    Am Ende ist OOP nicht mehr als das. Ich halte mich an bestehende Verträge mit den Objekten und tue das, was mir erlaubt wird, aber erstelle meinerseits neue Verträge, an die sich andere Objekte halten müssen.



  • Dieser Thread hat Kult-Potenzial. 👍



  • Shade Of Mine schrieb:

    Xin schrieb:

    In allen Fällen wird abhängig vom Objekttyp gehandelt. Das alles ist OOP. Und das ist auch die Definition von OOP:
    "OOP liegt vor, wenn Objekte sich abhängig von ihrem Objekttyp verhalten und nicht abhängig vom ReferenzTyp, der auf das Objekt zeigt.":

    Und warum genau ist dann die Definition
    "Objekt orientierung bedeutet sich an den Objekten zu orientieren [was das verhalten des Programmes betrifft]" falsch?

    Es geht um die Algorithmen, die abhängig vom Objekttyp zur Laufzeit unterschiedliche Funktionen aufrufen.
    Ich weiß jetzt nicht, in welchem Zusammenhang Du den Satz grade zitierst oder schreibst. Solange sich nur Programmierer an Objekten orientieren, nicht aber die Algorithmen, ist er falsch.
    Wenn Du statt "Objekten" "Objekttypen" meinst, wäre ich für die Ablehnung von Referenztypen dankbar, denn dann wären solche Threads überflüssig.

    Shade Of Mine schrieb:

    Nichts anderes als das sagen wir hier die ganze Zeit: OOP ist eine Denkweise in der das Objekt das Zentrum dastellt. Ich brauche dafür aber keine dynamische Polymorphie - ich kann das auch mit statischer machen - solange das Objekt das Zentrum ist, das Objekt das verhalten festlegt.

    Du brauchst keine dynamische Polymorphie, das habe ich nie behauptet.
    Ich sagte, dass "virtual" dynamische Polymorphie benötigt.
    Und dynamische Polymorphie braucht zwangsläufig Vererbung.
    Vererbung geht nur mit Klassifizierung, in C durch Klassen.
    Schlussfolgerung: für OOP-Unterstützung von C++ benötigst Du Klassifizierung, Vererbung, dynamische Polymorphie (also virtual).

    Und ich sagte mehrfach, dass virtual nicht für OOP benötigt wird. Verzichtest Du auf virtual, wirst Du von C++ auch nicht unterstützt und musst Du Deine Objektorientierung selbst implementieren. Also statische Jumptables aufwendig nachprogrammieren oder die in C häufig (fehleranfällige) verwendete Möglichkeit nehmen:

    void oop_function( char * object )
    {
      if     ( object[0] == 1 ) printf( "%s\n", &object[1] );
      else if( object[0] == 2 ) printf( "%c\n",  object[1] );
      else if( object[0] == 3 ) printf( "%d\n",  object[1] );
      ...
    }
    

    Das ist schwer zu warten, sieht scheiße aus und ist langsam. Es ist aber trotzdem OOP, weil abhängig vom Objekt (das auch keine "class" sein muss) unterschiedliche Funktionen gerufen werden.
    Das ist etwa das Level von Multifunktionen, lediglich ist ausformuliert, was ein Compiler übersetzen würde.
    Und es ist verdammt gut, dass diese ausgeschriebene Form von OOP heutzutage verpöhnt ist - es ändert aber nichts daran, dass es eine Form von objektorientierte Programmierung ist.

    In C++ würde ich die Objekte klassifizieren und die Sache über virtual functions regeln, weil C++ OOP unterstützt, damit lässt es sich besser warten, sieht es nicht mehr scheiße aus und wird schneller. (alles schon geschrieben...)

    Das x-Mal gepostete Tier => Katze Beispiel, ist ohne virtual nicht OOP, weil egal ist, mit welchem Objekt Tier::GibLaut() gerufen wird, es kommt Hallo raus.



  • otze schrieb:

    Xin schrieb:

    "OOP liegt vor, wenn Objekte sich abhängig von ihrem Objekttyp verhalten und nicht abhängig vom ReferenzTyp, der auf das Objekt zeigt.":

    Das ist aber unlogisch. Ein Objekt muss sich immer so verhalten, wie der Referenztyp der auf es zeigt, denn der Referenztyp gibt die definition darüber, was das Objekt ist.

    Falsch.
    Ein Referenztyp gibt an, was das Objekt ist oder, zu welcher Oberklasse er zugeordnet wird.

    BITTE schau Dir das Tier <-> Katze Beispiel an, kompilier es.

    Das Objekt ist eine Katze, aber handelt nicht wie eine Katze. Es ist nicht Objektorientiert, weil nach dem Referenztyp (Tier) entschieden wird Tier::GibLaut() aufzurufen, statt Katze::GibLaut().

    otze schrieb:

    Du kannst das Objekt nicht anders verwenden als der Referenztyp zulässt, und der Objekttyp darf sich niemals anders verhalten als das was die zusicherungen erlauben.

    Doch kannst Du, denn genau das ist, was Objektorientierung ausmacht.



  • Xin schrieb:

    Doch kannst Du, denn genau das ist, was Objektorientierung ausmacht.

    Also wirklich, billiger geht es nicht: Gerade klärst Du ihn erst darüber auf, was ein Referenztyp wirklich ist, und jetzt trittst Du hier noch nach. 🙄

    Xin schrieb:

    Das x-Mal gepostete Tier => Katze Beispiel, ist ohne virtual nicht OOP, weil egal ist, mit welchem Objekt Tier::GibLaut() gerufen wird, es kommt Hallo raus.

    Im Bereich der minimalen Voraussetzungen "meiner" Definition kommt man aber gar nicht in die Verlegenheit, Klassen abzuleiten.

    Natürlich ist Dein Beispiel eins objektorientierter Programmierung- aber nicht wegen der Verwendung von virtual, sondern weil Du Dich entschlossen hast, statt wild verstreuter Daten und Funktionen eine Klasse zu programmieren (Verzeihung, "zu schreiben", eine Klasse ist ja kein Algorithmus) und sie dazu zu benutzen, ein Programm zu formulieren, das mit Objekten arbeitet, die die so definierten Eigenschaften haben. Ich sehe nicht, was daran nun schwammig ist (wer soll das übrigens behauptet haben?).

    Xin schrieb:

    Es ist aber trotzdem OOP, weil abhängig vom Objekt (das auch keine "class" sein muss) unterschiedliche Funktionen gerufen werden.

    Ich merke mir als intellektuelle Höhepunkte von und für heute:
    1. Klassen müssen keine Objekte sein (logisch, den U-Boote tanzen nicht)
    2. Der folgende Codeschnipsel ist OOP, weil abhängig vom Objekt verschiedene Funktionen gerufen werden:

    class Katze
    {
      public:
        void GibLaut() { std::cout << "Miau"; }
    };
    
    class Hund
    {
      public:
        void GibLaut() { std::cout << "Wau"; }
    };
    
    Katze k;
    Hund h;
    
    h.GibLaut();
    k.Giblaut();
    

    Zu einer anderen Frage von Dir: Als geübter Definierer sollte schon klar sein, daß Einzelteile einer Definition ggf. auch definiert sein müssen. Wenn Du OOP definierst, mußt Du also automatisch auch O, O und P definieren. Und im Prinzip können wir jetzt schon aufhören, weil Du die Definition von O dazu genutzt hast, "meine" Definition für viel zu allgemein zu erklären. "mutwillig falsche Interpretation".



  • Xin schrieb:

    Es geht um die Algorithmen, die abhängig vom Objekttyp zur Laufzeit unterschiedliche Funktionen aufrufen.
    Ich weiß jetzt nicht, in welchem Zusammenhang Du den Satz grade zitierst oder schreibst. Solange sich nur Programmierer an Objekten orientieren, nicht aber die Algorithmen, ist er falsch.

    Dass man da so einfach trennen kann... Schliesslich schreibt der Programmierer ja den Algorithmus und ich kann mir schwer vorstellen dass der Programmierer das Verhalten vom Objekt vorgeben lässt dies aber nicht in den Algorithmus einbaut. Irgendwie widerspricht sich da etwas.

    Wenn Du statt "Objekten" "Objekttypen" meinst, wäre ich für die Ablehnung von Referenztypen dankbar, denn dann wären solche Threads überflüssig.

    Typen sind ein Konzept dass einige Sprachen nicht wirklich haben.

    Du brauchst keine dynamische Polymorphie, das habe ich nie behauptet.
    Ich sagte, dass "virtual" dynamische Polymorphie benötigt.
    Und dynamische Polymorphie braucht zwangsläufig Vererbung.
    Vererbung geht nur mit Klassifizierung, in C durch Klassen.
    Schlussfolgerung: für OOP-Unterstützung von C++ benötigst Du Klassifizierung, Vererbung, dynamische Polymorphie (also virtual).

    Aber das alles ist komplett uninteressant. Wir alle wissen welche Features C++ bietet. Die Frage ist: definieren diese Feature OOP. Lass C++ und Java einfach mal ruhen. Nur weil virtual in C++ sinnvoll ist um gute dynamische Polymorphie zu erreichen bedeutet dass nicht, dass virtual OOP definiert. Und es geht hier um OOP und nicht um C++.

    Ich behaupte weiterhin: diese Features sind Ausdrucksformen - ein paar von vielen Möglichen.

    Und ich sagte mehrfach, dass virtual nicht für OOP benötigt wird.

    Du sagst aber dynamische Polymorphie ist nötig für OOP und statische Polymorphie ist kein Teil der OOP. Genau das hinterfrage ich hier.

    Das x-Mal gepostete Tier => Katze Beispiel, ist ohne virtual nicht OOP, weil egal ist, mit welchem Objekt Tier::GibLaut() gerufen wird, es kommt Hallo raus.

    Und genau das ist nicht wahr:

    class Hund {
    public:
      void gib_laut() { cout<<"wau wau"; }
    };
    
    class Katze {
    public:
      void gib_laut() { cout<<"miau"; }
    };
    
    template<typename Tier>
    void foo(Tier* t) {
      t->gib_laut();
    }
    

    voila - das Objekt bestimmt das Verhalten.

    Die Frage ist: warum lässt du das nicht als OOP gelten? Vermutlich weil es statisch ist und schon zur Compiletime feststeht. Nun, was wenn ich einen C++ Interpreter hernehme - dann steht alles erst zur Laufzeit fest.



  • Xin schrieb:

    Falsch.
    Ein Referenztyp gibt an, was das Objekt ist oder, zu welcher Oberklasse er zugeordnet wird.

    BITTE schau Dir das Tier <-> Katze Beispiel an, kompilier es.

    das ohne virtual? ich kenne das ergebnis. und nun? Das ist auch das, was mir das interface zusichert. Nichts magisches, nichts ungewöhnliches. Es gibt einen laut zurück, und den habe ich verlangt. Das Objekt hat das Interface eingehalten. Und gleichzeitig auch nicht, aufgrund des logischen Fehlers. Das passiert aber oft, nennt man Bug. damit mein ich nicht, dass kein "Miau" ausgegeben wird, sondern "Hallo". Als Mensch erwarte ich nicht unbedingt, dass ein tier reden kann, ausser natürlich ich bin der Meinung, dass der Mensch biologisch ein Tier ist, für sicher 60% der menschen ist das aber höchst befremdlich.

    Das Objekt ist eine Katze, aber handelt nicht wie eine Katze. Es ist nicht Objektorientiert, weil nach dem Referenztyp (Tier) entschieden wird Tier::GibLaut() aufzurufen, statt Katze::GibLaut().

    Das ist aber nur logisch falsch, denn der Referenztyp kann diese Aufgabe ebenso erfüllen.

    class Tier
    {
        private: 
            string laut;
        public:
            Tier():laut("Hallo"){}
            Tier(const string& laut):laut(laut){}
    
            void gibLaut(){std::cout<<laut<<"\n";}
    };
    class Katze: public Tier
    {
        public:
            Katze():Tier("Miau"){}
    };
    
    int main()
    {
      Tier* tier  = new Katze();
      tier->GibLaut();  
    }
    

    Das Ergebnis gibt das was wir erwarten. Das objekt verhält sich dem Vertrag entsprechend und gibt uns den geforderten laut zurück. logisch und semantisch korrekt 👍
    Ist das nun OOP?

    mal davon ab: wenn wir das Objekt nicht selbst erstellen würden, könnten wir sogar(nach der philosophischen diskussion ob der Mensch auch ein Tier ist) zum Schluss kommen, dass "Hallo" durchaus korrekt ist, was meine Meinung verstärkt, dass der Vertrag das wichtige an der OOP ist, kein virtual.



  • Vielleicht erstmal Begrifsklärung Polymorphie:

    Beispiel Coercion-Polymorphie:

    void foo (double x)
    {}
    
    double bar = 0.0;
    foo (bar);
    
    int baz = 0;
    foo (baz);
    

    foo lässt sich mit Objekten verschiedenen Typs aufrufen.

    Überladungs-Polymorphie:

    void foo (double x)
    {}
    void foo (int x)
    {}
    
    double bar = 0.0;
    foo (bar);
    
    int baz = 0;
    foo (baz);
    

    foo lässt sich mit Objekten verschiedenen Typs aufrufen.

    Parametrische Polymorphie:

    template<typename T>
    void foo (T x)
    {}
    
    double bar = 0.0;
    foo (bar);
    
    int baz = 0;
    foo (baz);
    

    foo lässt sich mit Objekten verschiedenen Typs aufrufen.

    ...

    Einzig bei der Inklusions-Polymorphie wird dann dynamisch entschieden.

    struct X {
       virtual void foo() {}
    };
    struct Y : X {
       virtual void foo() {}
    };
    
    X x;
    Y y;
    
    X * bar = x;
    
    bar->foo();  // ist jetzt leider die C++-Syntax. Cooler wäre eine Sprache, die die Syntax foo(bar) verwenden würde
    
    bar = y;
    
    bar->foo();
    


  • Erkenntnisgewinnbringende Diskussion schrieb:

    <ZENSIERT-1> weißte warum Pferde Pferde heißen?
    <ZENSIERT-2> pferde sind nicht objektorientiert.
    <ZENSIERT-1> weil sie auf der erde stehen, wären sie in der luft hießen sie Pflufte!
    <ZENSIERT-3> pferde sind grasorientiert.
    <ZENSIERT-1> völlig klar!
    <ZENSIERT-1> ich habe jetzt ausführlich erklärt warum Pferde Pferde heißen!
    <ZENSIERT-4> ZENSIERT-1: aber sehr schwammig
    <ZENSIERT-5> sehr sehr schwammig
    <ZENSIERT-4> die Pferde orientieren sich doch gar nicht an der Erde!
    <ZENSIERT-5> das ist also dein verstaendnis von mathematik
    <ZENSIERT-6> ZENSIERT-1: Nein, Pferde heissen nur so weil sie virtuelle Methoden haben. Sonst wären es ja Pferdbirnen 😉
    <ZENSIERT-5> schaem dich ZENSIERT-1
    <ZENSIERT-1> ZENSIERT-4: ich verlasse mich da auf das Fundament der Logik, wenn ihr mir nicht glaub könnt ihr auch gleich Bildzeitung lesen!



  • @Helium: Ist das ein scherz-Posting?

    Helium schrieb:

    Beispiel Coercion-Polymorphie:

    Das ist keine Polymorphie, es wird nur gecastet (implizit). Ist das gleiche, wie wenn ich fuer alle Typen eine eigene Funktion schreibe. Gut, dass das der Compiler fuer mich uebernimmt.

    Helium schrieb:

    Überladungs-Polymorphie:

    WTF, siehe oben.

    Helium schrieb:

    Parametrische Polymorphie:

    Das ist das gleiche wie die beiden oberen Beispiele. Der Compiler uebernimmt fuer mich die Drecksarbeit.

    Helium schrieb:

    Einzig bei der Inklusions-Polymorphie wird dann dynamisch entschieden.

    Und das ist OOP.

    Shade Of Mine schrieb:

    klingt sehr vereinfacht. warum muss alles schwarz oder weiß sein? kann nicht etwas grau sein?

    Sind wir in der Politik? Bundertrojaner ist gut und nur ein wenig schlecht, sieht das doch mal (hell-)grau und nicht so schwarz.

    Shade Of Mine schrieb:

    Warum?
    Ich rede nicht von austauschen zur Laufzeit. Ich rede einfach nur von Laden von Klassen zur Laufzeit. Warum ist es Polymorphie wenn ich die Klassen die es gibt doch eh statisch vor mir habe? Wo trennst du ab wann etwas zu statisch für Polymorphie wird.

    Wenn man nur mit dem Interface arbeitet und Instanzen fuer dieses Interface dynamisch mittels Reflection nachlaed, dann sehe ich das als OOP. Man koennte es auch mittels C++ Interpreter machen, der neue Templates erzeugt. Aber nur Templates, einmal kompiliert und danach nie wieder, ist keine OOP.

    Shade Of Mine schrieb:

    call mal bitte basisklasse::mach_was aus der "abgeleiteten" klasse

    Das hat mich auch gewundert. Wie macht man das in JS?

    Also als Beispiel:
    Ich habe ein array, der Zahlen aufnehmen kann. Wie erweitere ich jetzt die .add() Methode, ohne die Methode gleich neu schreiben zu muessen? Das weis ich bis Heute nicht, wie das in JS geht.

    Shade Of Mine schrieb:

    "Objekt orientierung bedeutet sich an den Objekten zu orientieren [was das verhalten des Programmes betrifft]" falsch?

    Bin ich der einzige, der bei diesem Satz schmunzeln musste? Substantiv X Verb Y ist wenn Substantiv X[...] Verb Y. Also: Wenn mein Computer am rechnen ist, bedeutet dass, das mein Computer am rechnen ist. Ist logisch hundert pro richtig, aber irgendwie mit null Aussage.

    Und was heist sich an Objekten zu orientieren? - Das heist Objekt Orientiert zu sein.

    Btw, auf meine Frage, wieso die Zusammenfassung von Daten und Methoden das coolste ist, wurde noch nicht eingegangen?



  • DEvent schrieb:

    @Helium: Ist das ein scherz-Posting?

    Nein, es ist ein sehr wahres Posting um zu zeigen, dass es mehr als nur C++/Java gibt.

    Shade Of Mine schrieb:

    Warum?
    Ich rede nicht von austauschen zur Laufzeit. Ich rede einfach nur von Laden von Klassen zur Laufzeit. Warum ist es Polymorphie wenn ich die Klassen die es gibt doch eh statisch vor mir habe? Wo trennst du ab wann etwas zu statisch für Polymorphie wird.

    Wenn man nur mit dem Interface arbeitet und Instanzen fuer dieses Interface dynamisch mittels Reflection nachlaed, dann sehe ich das als OOP. Man koennte es auch mittels C++ Interpreter machen, der neue Templates erzeugt. Aber nur Templates, einmal kompiliert und danach nie wieder, ist keine OOP.

    Was wenn ich die Templates zur Laufzeit kompiliere?
    Ich rede auch nicht von Interfaces oder Reflection. Ich rede einfach nur davon, dass statisch ein Begriff ist, den es nicht mehr gibt. Ich kann _alles_ zur Laufzeit machen. Ich kann Klassen zur Laufzeit erstellen, Templates etc. Vergiss Java. Vergesst es einfach - das hat nichts mit Java oder Reflection zu tun, sondern damit dass wann etwas passiert mit der Implementierung des Features zusammen hängt, nicht mit dem Feature selber.

    Beispiel: ein C++ Interpreter.

    Euer Problem ist: ihr bezieht OOP direkt auf eine Implementierung. Vor 20 Jahren konnte sich keiner denken, dass man zur Laufzeit kompiliert - heute ist das Standard: siehe Java. In 10 Jahren haben wir komplett neue Techniken zur Implementierung von solchen Features. Templates sind heute vielleicht noch etwas statisches - aber in C# zum Beispiel, sind die richtig dynamisch im Sinne von: wird zur Laufzeit die Klasse erstellt. Ist es jetzt dynamisch oder statisch?

    Oder Generics in Java - sie fühlen sich an wie statische c++ Templates (in vieler Hinsicht) aber sie sind intern über Laufzeit Casts implementiert.

    Das hat mich auch gewundert. Wie macht man das in JS?

    Es geht nicht.
    Man löst solche Sachen in JS anders - man hat andere Tools.



  • Shade Of Mine schrieb:

    Vor 20 Jahren konnte sich keiner denken, dass man zur Laufzeit kompiliert

    smalltalk wurde auch schon vor 30 jahren zur laufzeit kompiliert.
    überhaupt versteh ich nicht wieso ihr (Xin) immer von c++ ausgeht, gerade wo c++ nur die klempnerversion von objektorientierter programmierung bereitstellt.


Anmelden zum Antworten