Performancemythen?



  • Xin schrieb:

    rüdiger schrieb:

    Und einmal mit virtual. Aber wenn du OO von der Deklaration abhängig machst, ist das einfach sehr sehr merkwürdig und ungebräuchlich.

    Merkwürdig, weil ungewohnt. Aber zum merken würdig.
    Ungebräuchlich - stimmt, merkt man an diesem Thread.

    Aber logisch.

    Nein, überhaupt nicht logisch.

    Xin schrieb:

    rüdiger schrieb:

    Das sind zwei verschiedene Paar Schuhe. Daher lies meine Frage. Statisch/Nicht Statisch hat nichts und rein gar nichts mit OOP zu tun.

    Ein direkter Aufruf einer statischen Funktion ist nicht objekt orientiert. Objektorientiert ist, abhängig vom Objekttyp die richtige statische Funktion auszuwählen und aufzurufen.

    Der Aufruf ist doch Abhängig vom Objekt. Bei einem Objekt der Klasse A mit dem Methoden Aufruf foo, wird anhand der Klasse des Objektes der Aufruf entschieden. Egal ob das nun zur Laufzeit statt findet oder zur Compilezeit. Ich versteh nicht, warum du das zwanghaft auf die Laufzeit schieben willst. Macht doch überhaupt gar keinen Sinn dort eine künstliche Barierre einzuführen, die die Mehrheit einfach nicht sieht.

    Xin schrieb:

    rüdiger schrieb:

    Wenn ClassOfA::foo( ClassOfA * ) OOP, wie behauptet wird, so ist printf ebenfalls OOP in Abhängigkeit des ersten Argumentes.

    Was hat das erste Argument damit zu tun?

    Bei statischen, objektzugehörigen Funktionen (das meint also nicht "static"), ist das erste Argument der this-Pointer.

    Jo, bei Methoden hat man irgend wo den this-Pointer noch drin. Egal ob die zur Lauf- oder Compilezeit dispatcht werden.

    Xin schrieb:

    rüdiger schrieb:

    Was der Compiler daraus mag Dir ja egal sein, aber es equivalent zum Sourcecode. Aus einem statischen Funktionsruf wird ohne Compilerfehler kein OOP mehr.

    Aber sicher. Weil der Aufruf im Hintergrund ist egal. Was soll dort den Unterschied machen? Dann sind ja selbst virtuelle Funktionen nicht garantiert OO nach deiner (merkwürdigen!) Definition.

    class A {
    public:
      virtual void foo() { }
    };
    
    class B {
    public:
      virtual void foo() { }
    };
    
    B b;
    b.foo();
    

    daraus wird ja auch ein "statischer Aufruf", zumindest erwarte ich das bei einem guten Compiler. => Kein OO

    Richtig, wie auf den letzten 5-10 Seiten immer wieder beschrieben. Es hat jemand etwas verstanden. 🙂
    Wenngleich eine Optimierung des Compilers zum Entfernen von OOP das uninteressanteste an OOP ist.
    Ein guter Compiler entfernt hier den überflüssigen OOP-Aufruf und schreibt hier einen schnelleren, statischen Funktionsruf ins Executable.

    Benutz bitte nicht das Wort OOP so, auch wenn deine verquirlte Definition davon das Wort zu einem Ersatz von "virtuellen Funktionsaufruf" gemacht hat. Das verwirrt einfach nur.

    Aber zum Thema: Also ist es nicht OOP. Aber eigentlich ist OOP doch eine Methode zu programmieren und Programme zu entwerfen. Nicht etwas, was der Compiler entscheidet.

    Das merke ich, das tut der Rest offenbar auch nicht, aber ich finde es sehr gut, dass Du daraus hier nicht wie der Rest schlussfolgerst, dass mein Ansatz falsch ist. 👍

    Es gibt kein "Falsch" bei Definitionen. Das habe ich ja auch schon erklärt. Ich definiere etwas, also lege ich es damit fest. Ist nur die Frage, ob ich mich dann immer noch mit anderen Menschen verständigen kann, weil diese vielleicht eine andere Definition haben. Wie ich mehrfach sagte: Du kannst auch Grün zu Blau sagen.

    Xin schrieb:

    rüdiger schrieb:

    rüdiger schrieb:

    Es gibt zahlreiche andere Definitionen hier in dem Thread, die ebenfalls "scharf" sind.

    Das wird in dem Thread nicht nur von mir bestritten.

    das es zahlreiche Definitionen hier gibt? Das willst du bestreiten? Das diese "scharf" sind? Schau dir zB die Definition von Overtaker an. Die ist gut. Vielleicht nicht ganz 100% ausgearbeitet. Trifft aber zumindest schon den Nagel.

    Ich habe noch keine saubere Definition hier gelesen. Ich habe viele gelesen, offenbar ist die von Overtaker mir nicht unter den anderen aufgefallen. Ich bestreite hier eine scharfe Definition gesehen zu haben. Viele Definitionen habe ich gelesen und alle behaupten, dass es *die* eine ist, die alle anderen auch haben.
    Kann sein, dass Overtaker da untergegangen ist.
    Lohnt es sich, sie zu suchen? Kann sie meine Frage an Hustbaer beantworten - sonst lohnt es sich icht.

    Welche Frage an Hustbaer? Es lohnt sich die Definition zu suchen, da es die einzige Definition ist, die ich bisher gefunden habe, die wirklich alle Objektsysteme (die ich kenne) einschließt.

    Das ist vielleicht auch der Unterschied zwischen deiner Definition und meiner Definition. Du setzt dich hin und sagst "vom Himmel hinaus": X ist OOP. Alles andere nicht. Ich schaue mir an, was ich über OOP finde und lese und was andere Leute sich darunter vorstellen (oder war ich vermute, was sie sich vorgestellst haben) und versuche dann eine Definition zu treffen, die dem Gerecht wird.

    Ich fürchte einfach, dass du nicht viele OO-Systeme kennst. Da dein statisch/nicht-statisch-Ansatz nur mit C++ funktioniert. In anderen Sprachen wird jeder Funktionsaufruf zur Laufzeit dispatcht. Sind das dann komplett Objektorientierte Sprachen? Ich fürchte nicht...



  • *amateurmoderator : start*

    Die Definition von overtaker ist auf Seite 30.

    *amateurmoderator : ende*



  • Xin schrieb:

    Shade Of Mine schrieb:

    Xin schrieb:

    Wo ist da ein abstraktes Konzept, dass nicht im Sourcecode vorkommt?

    Ich pack den Code hier nochmal rein, damit wir überhaupt sicher sind, dass wir vom gleichen sprechen:

    Shade Of Mine schrieb:

    Mir ist gerade langweilig, deshalb ein kleines Gedankenspielchen:

    class Triangle {
    public:
      void draw();
    };
    
    class Circle {
    public:
      void draw();
    };
    
    template<typename Shape>
    void foo(Shape* s) {
      s->draw();
    }
    

    Das Konzept hier ist Shape. Genau wie in Java oder sonstwo wo man eine abstrakte Klasse/Interface hätte. Lediglich manifestiert es sich nicht direkt im Code in form einer Klasse/Interface sondern viel mehr im Sinne eines abstrakten Konzepts.

    Ich sehe da nichts abstraktes?! Das alles statisch.
    Oder glaubst Du, dass ein Algorithmus dynamisch wird, weil Teile des Programms über ein Template erzeugt wurde?

    Mir ist jetzt nicht klar was Abstraktion mit Dynamik zu tun hat aber eines ist mir klar: Abstraktion passiert im Kopf, nicht im Code.



  • interessantes Statement (Quelle: http://www.cincomsmalltalk.com/userblogs/ralph/blogView?showComments=true&entry=3364027251 )

    Ralph Johnson schrieb:

    Processes in Erlang are objects. At the beginning of my course on OO design, I explain three views of OO programming. The Scandinavian view is that an OO system is one whose creators realize that programming is modeling. The mystical view is that an OO system is one that is built out of objects that communicate by sending messages to each other, and computation is the messages flying from object to object. The software engineering view is that an OO system is one that supports data abstraction, polymorphism by late-binding of function calls, and inheritance.

    (und generell interessant, vor allem für Leute die Erlang noch nicht kennen. Was eigentlich viel interessanter ist, als die OOP Definition von irgend wem...)



  • Habe mal im IRC diskutieren mit dv und dabei ist folgende definition herausgekommen:

    OO eine Denkweise wie man Daten und Methoden gruppieren kann, dabei zeichnet sich die Gruppierung durch die Einteilung in Objekten=Daten+Methoden aus. OOP ist die implementierung von der OO denkweise, die die encapsulation, inheritance, and polymorphism Techniken benutzt.

    Was haltet ihr davon?



  • Dem ersten Satz stimme ich zu, dem zweitem nicht ganz. OOP ist auch ohne Vererbung und Polymorphie moeglich.



  • Dem ersten Satz stimme ich auch nicht wirklich zu. Siehe CLOS.



  • Vorweg, wenn ich im Folgenden von Weltbild spreche, dann beziehe ich das auf die Welt der Programmierung. (Ist eh die einzige Welt in der ich lebe)

    Über die Jahre habe ich mir angewöhnt, Aussagen, die ich nicht begreife um so gründlicher zu lesen. Weil immer dann, wenn jemand etwas sagt was nicht in "mein" Weltbild passt könnte es dafür zwei Gründe geben: Mein Weltbild ist unzureichend oder aber die Aussage ist fehlerhaft.

    Nach immerhin einem viertel Jahrhundert seid ich meine ersten Programme in Computer gehackt habe bilde ich mir nunmal ein das mein Weltbild, wenn auch streckenweise unkonventionell, insgesamt doch recht fundiert ist. (Mal abgesehen davon das ich menschlich halt ein bekanntes Arschloch hier im board bin, aber das ist ein andere Thema)

    Meine Theorie ist, daß alles was ich nicht verstehe eine Chance sein kann, mein Wissen weiter zu fundieren indem ich versuche es zu verstehen, anstatt alles was nicht in "mein" Weltbild passt grundsätzlich als falsch abzulehnen, wodurch ich mir selber letzten Endes die Chance nehmen würde mich weiterzuentwickeln. Dabei kann selbst eine totale Falschaussage mir helfen mein Wissen weiter zu fundieren, denn wie heisst es so schön: Der kluge lernt aus seinen Fehlern, der Weise aus den Fehlern der Anderen.

    Betrachte ich nun Xin's missionarischen Eifer mit dem er sein Weltbild unter die Leute bringt kombiniert mit dem fast schon krankhaft anmutenden Zwang alles andere als Falsch entlarven zu müssen dann werde ich stutzig. Sicher, zum Teil klingen seine Aussagen gar nicht so falsch, streckenweise vor allem am Anfang hatte ich sogar das Gefühl ihm zustimmen zu wollen, aber jeh mehr ich verstehe was er sagen will, desto weniger kann ich dem zustimmen.

    Zwischen den Zeilen lese ich immer eine Grundaussage, die mir sehr bekannt vorkommt weil ich selber lange gebraucht habe um diese zu überwinden. Ich meine die Einstellungen das dann, wenn man sich vom "Mainstream" unterscheidet man ja "besser" ist als der Mainstream. Man ist ja ein Vordenker weil man als einer der Wenigen, vielleicht sogar als Einziger die Wahrheit erkannt hat und alle anderen einfach noch nicht weit genug sind und es deswegen ablehnen.

    Ja, je größer die Ablehnung der Anderen ist, desto mehr sieht man sich sogar in seiner eigenen Meinung bestätigt. Überlegen wir nur mal zurück, die ersten Menschen die behauptet haben die Sonne würde sich um die Erde drehen und nicht umgekehrt wurden damals sogar noch als Ketzer verbrannt. Dabei zeigt die Geschichte doch das sie nur geniale Vordenker waren, Ihrere Zeit weit vorraus. Hätten die anderen nur auf sie gehört, wäre das doch viel besser gewesen.

    Dies mag nur eine INterpretation sein, aber ich werde das Gefühl nciht los das Xin sich als einer dieser Vordenker sieht, gerade _weil_ ein Großteil der Programmierer sein Denkmodell ablehnen.

    Es gibt da aber Problem. Auch heute gibt es noch (oder wieder) Menschen die daran glauben die Sonne würde sich um die Erde drehen, womit sie ja komplett _gegen_ die allgemein verbreitete Meinung stehen die Erde würde sich tatsächlich um die Sonne drehen. Alle Beweise, daß dem nicht so sei wie z.B. der Mondflug und die daraus gewonnenen Erkenntnisse werden kurzerhand als Lügen hingestellt. Die Frage ist nun, sind diese Menschen, die sich ja definitiv vom Mainstream abheben und von sich selber ebenfalls glauben als Einzige die Wahrheit zu sehen, sind das jetzt unsere "Vordenker" ?

    Ich bin in diesem Thread nicht der erste der darauf Hinweis das Quantität keine Aussage über den Wahrheitsgehalt einer Theorie macht. Auch wenn wir alle der gleichen Meinung sind können wir falsch liegen. Aber umgekehrt gilt ebenso, daß auch dann, wenn wir mit unsere Meinung alleine stehen diese falsch sein kann.

    Was mich an Xin stutzig werden lässt ist das Gefühl, daß er gar nciht erst zu versuchen scheint die anderen Standpunkte verstehen zu wollen, weil für ihn ja von vorneherein klar ist das diese falsch sind. Vielmehr geht es ihm nur darum darzustellen _warum_ alle anderen Aussagen falsch und seine doch richtig ist.

    Ich behaupte, keine Seite ist wirklihc falsch. Jeder sieht die Welt mit seinen Augen und wenn die doch sehr ungewöhlnliche Sichtweise von Xin ihm dabei hilft gute Software zu schreiben, well, so be it. Trotzdem wäre es vielleicht ein Denkansatz, daß "die Andern" hier im board vielleicht ebenfalls mit ihrere Sichtweise gar nicht so falsch liegen, das eine gewisse Koexsistenz verschiedener Sichtweisen möglich sein könnte bei der es nicht darum geht, die jeweils andere als "falsch" hinzustellen sondern darum, auch die andere Sichtweise zu begreifen unabhängig davon ob man sie nun für sich selbst annimmt oder nicht.

    Andernfalls lebt man in einer sehr einsamen Welt weil man früher oder später nicht mehr in der Lage ist sich mit den anderen zu verständigen oder sie zu verstehen.

    Naja, sorry für das posting, ich wollte das seit Tagen loswerden.



  • Xin schrieb:

    Ich sehe da in keinerlei Hinsicht irgendwas abstraktes im Sinne von OOP in Deiner Definition.

    Das Konzept "Shape", dass siehst du sehr wohl - denn du willst sofort wie du den Code gesehen hast eine abstrakte Klasse Shape einbauen. Ich behaupte nun: man muss diese abstrakte Klasse nicht einbauen - da sie von der Idee her bereits im Code vorhanden ist.

    abstrakt im Sinne wie "Liebe" ein abstraktes Nomen ist. Nicht abstrakt im Sinne von Java Klassen.

    Shade Of Mine schrieb:

    Das ist dynamisch, aber nicht OOP. Neue Templates ändern nicht die Typen vorhandener Daten.

    Den Typen vorhandener Daten ändert sowieso nichts.

    Shade Of Mine schrieb:

    Stimmt, ich kann das Programm zur Laufzeit umschreiben. Das ist dann nicht mehr statisch, aber wenn ich das Programm umschreibe und so nachträglich OOP einfüge oder zur Laufzeit entferne ist das Ändern des Programms nicht OOP, sondern Reflection.

    Nein. Stell dir einen C++ Interpreter vor.
    Ist #include<foo.h> Reflection? Nein - es passiert nichts was nicht auch zur Compiletime passiert - denn Runtime ist gleich Compiletime.

    Selbstmodifizierender Code ist eine sehr alte Geschichte und gab's schon lange, bevor es mit Reflection standardisierte Interfaces dafür gab. Hier wird allerdings mit keinem Objekt gearbeitet, sondern der Code verändert.

    Wo ziehst du sowas immer her? Habe ich je von Reflection oder Selbstmodifizierendencode gesprochen? NEIN!

    Shade Of Mine schrieb:

    Ähh... hier muss ich leider widersprechen.. Ein Java Interface entspricht einer Klasse ohne Daten und ausschließlich abstrakten Funktionen.

    Danke, aber ich kann besser Java als du.

    Sag mir was der Java Code mit dem Interface mehr kann als die Template Variante.

    Wenn wir von "virtual" reden, dann meinen wir auch das Konzept von virtuellen Funktionen - klar kommt in Java das Wort virtual nicht vor. Aber in JavaScript hast du das komplette Konzept von virtuellen Funktionen nicht. Deshalb auch noch die kleine Frage: kann man in JavaScript Objektorientierte Programme schreiben?

    Ich kann mich nur wiederholen: vergiss bitte Java und C++. Die meisten hier kennen sich mit Java und C++ gut genug aus - vermutlich besser als du - du musst uns also nicht erklären was ein Interface ist.

    Ein großes Problem in dieser Diskussion ist der Punkt, dass dir Wissen fehlt. Bestes Beispiel ist: JavaScript unterstützt keine virtuellen Funktionen. Damit kann kein JavaScript Code in deinen Augen OO sein.

    Wenn wir nun aber folgenden Code betrachten:

    function Lampe(energiequelle) {
      this.quelle = energiequelle;
    }
    
    function Dynamo() {
      this.get_energie = function(){}
    }
    function Atomreaktor() {
      this.get_energie = function(){}
    }
    
    lampe = new Lampe(new Dynamo());
    

    dann macht dieser Code exakt das selbe wie der Java Code:

    class Lampe { public Lampe(Energiequelle e) {} }
    interface Energiequelle { abstract void get_energie(); }
    class Dynamo implements Energiequelle { public void get_energie(){} }
    class Atomreaktor implements Energiequelle { public void get_energie(){} }
    
    lampe = new Lampe(new Dynamo());
    

    Ich kann in JavaScript garkeine "Klasse" Energiequelle einbauen - die Sprache würde es nicht unterstützen - ich müsste hacks verwenden damit das halbwegs gut läuft.

    Was bei diesem Code aber viel wichtiger ist, ist nicht die Implementierung - denn die Implementierung hängt sowieso komplett von der Plattform ab. Mehr dazu weiter unten.

    Das wichtige ist die Idee und die Aussage des Codes. Beide lösen ein Problem:
    Ich habe eine Lampe und habe unendlich viele Energiequellen die ich beliebig kombinieren will.

    Beide Codes lösen diese Problemstellung auf exakt die selbe Art und Weise.

    Erst wird eine Schablone für Lampe Objekte erstellt und in dieser Schablone wird vermerkt dass es Energiequellen gibt. Und es wird ebenfalls vermerkt, wenn die Lampe Energie braucht, muss sie "get_energie" von der Energiequelle aufrufen.

    Beide Codes machen exakt dies. Für Leute wie dich, die nur Java/C++ kennen ist die Idee kein Interface zu haben erschreckend. Für Leute die nur JavaScript kennen ist die Idee ein Interface Energiequelle zu haben erschreckend.

    Man darf hier nie auf die Implementierung oder die Syntax achten - denn unterschiedliche Sprachen sehen unterschiedlich aus. In C++ sähe es uU so aus:

    template<typename Energiequelle>
    class Lampe {
    public:
      Lampe(Energiequelle* e);
    };
    
    class Dynamo { public: void get_energie() {} };
    class Atomreaktor { public: void get_energie() {} };
    

    Und auch hier wird wieder das exakt selbe gemacht. Lediglich die Tools die ich habe um diesen Sachverhalt auszudrücken unterscheiden sich.

    Das ist der essentielle Punkt: virtuelle Funktionen sind eine Technik um ein bestimmtes Problem zu lösen. Nämlich das Problem, dass ich nicht von vornherein weiß welches Verhalten ich will. Ich die Entscheidung über das Verhalten also einer Funktion übergebe die ich während ich meinen Teil des Codes schreibe nicht kenne.

    Wenn ich Lampe schreibe weiß ich, dass ich irgendwie Energie brauche. Ich weiß aber nicht wie ich an Energie ran komme. Ich lagere also "get_energie" aus und packe es in Energiequelle. Ich weiß zu dem Zeitpunkt wo ich Lampe implementiere nicht was es für Energiequellen gibt. Wichtig ist dabei: wenn es endlich Kaltefusion gibt, muss meine Lampe damit laufen.

    Jetzt kann man eben ein Interface Energiequelle nehmen und sagen: jede Energiequelle muss das Interface implementieren - und über dynamisches dispatching erkennt die Plattform auf der ich arbeite welche get_energie() Funktion nun die richtige ist.

    Ich kann aber auch eine andere Technik verwenden. Ich behaupte: "alles was mir mit get_energie() Energie liefert - taugt als Energiequelle". Meine Plattform erkennt Anhand des Typen der Energiequelle (der erst zur Runtime feststeht) welche Funktion "get_energie()" aufgerufen werden muss.

    Exakt das selbe Konzept - lediglich eine andere Implementierung.

    Das bringt mich auf das Problem der Implementierungen im allgemeinen. Wie eine Technik implementiert ist, hängt von der unterliegenden Plattform ab. zB würde ein C++ Compiler dein nutzloses interface "Energiequelle" einfach wegoptimieren da es nur sinnloser Ballast ist und keinen Mehrwert bietet. Wann instanziierungen stattfinden - definiert ebenfalls die Plattform. C++ Templates werden zwar von den aktuellen Compilern während der Compiletime instanziiert. Aber ein C++ Interpreter kompiliert ja zur Laufzeit. Das hat absolut nichts mit Reflection zu tun - es wird ja nichts zur Sprache C++ hinzu erfunden. Es wird lediglich die Compiletime etwas verschoben: nämlich zur Runtime.

    C# funktioniert zB genau so. Generics werden während der Runtime gecheckt und gegebenenfalls neue Generic-Klassen erstellt wenn ein neuer Typ aufgetaucht ist. Da kommt keine Reflection vor - es ist einfach so, dass die Kompilierung größtenteils während der Laufzeit stattfindet.

    Das komplette Konzept von Compiletime vs Runtime ist durch die modernen VMs von .NET und Java auf den Kopf gestellt worden. Kompilierungen finden zur Laufzeit statt - wenn wir also sagen Templates sind statisch, ist das eine Vereinfachung für uns aber kein Gesetz. Template könnten problemlos zur Laufzeit kompiliert werden - wie es zB C++ Interpreter tun. Wann instanziierungen stattfinden hängt also komplett von der Plattform ab auf der man arbeitet.

    Der Punkt auf den ich hinaus will: eine festklammerung an "dynamischen" Sachen um OOP zu definieren muss fehlschlagen, denn heutztage kann _alles_ dynamisch sein. In Sprachen wie JavaScript oder Java findet die Kompilierung auf den meisten Plattformen zur Laufzeit statt.

    Mit Plattform meine ich das System mit dem man entwickelt: zB C++ Compiler und Laufzeitbibliothek. Oder Java-Compiler + Java VM.

    Solange du es nicht schaffst Implementierungen und Konzepte zu trennen - wirst du uns nie verstehen. Das Konzept von Polymorphie kann ich auf unzählige Arten implementieren. Du klammerst dich an der gängigsten Implementierung - virtuelle Funktionen - fest. Aber es ist eben nur ein möglicher Ansatz dieses Konzept zu implementieren.

    Multimethods sind zB eine andere Implementierung der Idee dass sich Hund bellen sollte wenn ich ihm sage "gib_laut" aber eine Katze vielleicht doch "miau" machen sollte.

    C++ Templates stellen eine weitere Möglichkeit da dieses Konzept zu implementieren.

    Alle diese Implementierungen oder Lösungen gehen das selbe Problem an. Sie haben unterschiedliche stärken und schwächen - lösen aber allesamt das selbe Problem.



  • Templates sind keine Interfaces, Templates sind eine Abstraktionsebene höher, so könntest Du mit z.B. Templates Interfaces erstellen.

    Templates sind keine Interfaces. Templates sind wieder eine ganz andere Baustelle.

    Klar, templates sind eine Abstraktionsebene höher, aber für uns spielt das keine Rolle, weil unsere Definition von OOP auch eine Abstraktionsebene höher ist. Unsere Definition befindet sich nicht auf Sprachebene. Wir kennen zwar den Begriff "Abstraktes Interface", aber dieser Begriff ist in seiner implementation nicht definiert.

    Schau dir einmal UML Diagaramme an. Diese visualisieren am ehesten, was wir als OOP bezeichnen. UML wurde dafür entwickelt, um die Abstraktion die bei der OOA und OOD entsteht sinnvoll aufs papier zu bringen. In UML gibt es Objekte und ihre Abhängigkeiten untereinander. Man kann Interfaces erstellen, Objekte vererben, Polymorphie betreiben...Am Ende stellt UML das Graphisch dar, was ich als "Vertrag" bezeichnet habe und andere als das herumreichen von Nachrichten bezeichnen. Es gibt sogar UML interpreter die auf Basis dieser Diagramme und ein paar Codeschnipseln das Programm simulieren können - nicht in der funktionalität, es verarbeitet nichts, aber im Zusammenspiel der Objekte.
    Das wichtige ist aber, dass diese UML Diagramme nur ein Modell sind. Wie man das ganze hinter Umsetzt, ist bei jeder Sprache und jedem Projekt anders. Wichtig ist nur, dass am Ende das Programm mithilfe der Diagramme noch nachvollzogen werden kann. Bei manchen sprachen geht eine 1:1 umsetzung der Objekthierarchie, grundsätzlich also alle sprachen die Vererbung und Kapselung unterstützen. das ist aber noch lange keine pflicht das zu machen.

    pseudouml:

    -----------------|     |---------|  
    |  Klasse1       |     | Klasse2 |
    |----------------|     |---------|
    |  Member        |<----|....     |
    |----------------|     |---------|
    |Klasse1(Member1)|     |         |
    |function()      |     |foo()    |
    |________________|     |---------|
                          /         \
                         /           \
                        /             \
                 |-----------|      |-----------|
                 |Konkret1   |      |Konkret2   |
                 |...        |      |...        |
                 |-----------|      |-----------|
                 |foo()      |      |foo()      |
                 |-----------|      |-----------|
    

    Das ist nach unserer Definition ein Modell für ein OOP Programm. Teste es mal nicht an deiner definition, sondern schau dir das an. Klasse1 hat ein Member das das Interface Klasse2 hat. Es können aber 2 Konkrete Objekte dafür in frage kommen.

    Implementation in C++

    //1
    template<class Klasse2>
    class Klasse1
    {
        private:
            Klasse2 member;
        public:
            Klasse1(const Klasse2& member);
            void function();
    };
    class Konkret1
    {
        public:
            void foo();
    };
    class Konkret2
    {
        public:
            void foo();
    };
    
    ...
    Klasse1<Konkret1> x(Konkret1());
    Klasse1<Konkret2> y(Konkret2());
    
    //2
    class Klasse2
    {
        public:
            virtual void foo()=0;
    };
    class Klasse1
    {
        private:
            Klasse2* member;
        public:
            Klasse1(Klasse2* member)
            void function();
    };
    class Konkret1:public Klasse2
    {
        public:
            void foo();
    };
    class Konkret2:public Klasse2
    {
        public:
            void foo();
    };
    
    Klasse1 x(new Konkret1());
    Klasse1 y(new Konkret2());
    

    Beide Implementationen sind mit dem UML Diagramm problemlos nachvollziehbar. Wann man eine der versionen wählt, ist Situationsabhängig.
    Natürlich sind auch umsetzungen von UML Diagrammen in anderen Sprachen möglich, sogar in C geht das. Die Frage, ob die eine Funktion OOP ist und die andere nicht, lässt sich dann so beschreiben: Gibt es ein Programmmodell, in dem diese Funktion ein sinnvolles Member einer Klasse sein kann(oder bei einem bekannten programmmodell: passt diese Funktion in irgendeine definition?)?

    UML ist leider nicht das maß aller Dinge, weil es auf die Mainstreamsprachen zugeshcnitten ist, andere Sprachen sind damit nicht sehr glücklich, die umsetzungen sind zwar möglich, aber bestimmte Sachen kann man in UML nicht darstellen, die in diesen Sprachen möglich sind, zb dynamisches ändern des Interfaces durch hinzufügen von methoden(oder in C++ vererben von typlisten um eine dynamische Menge von Interfaces zu vererben).

    //nachtrag Deswegen wurde UML auch bisher nicht genannt. Der Prozess beginnt im Kopf, wie man es visualisiert ist jedem selbst überlassen, oder wird mit dem team abgesprochen. es ist auch möglich, dass es nur kurze notizen dazu gibt, oder kommentare im Programmcode,oder ...

    //nachtrag2:
    Wann ist ein Code nicht OO, immerhin kann man bei genügend großem willen überall ein Modell finden:

    Es ist schwer zu sagen: diese funktion ist nicht OO. Das ist klar. Aber man kann sagen: die Verwendung dieser Funktion ist nicht OO,oder der funktionskern. Beispiel STL algorithmen. Prinzipiell könnten sie alle member eines Interfaces mit namen "Container" sein. Jeder container hat dann zb sein sort.

    Auch die Argumente der funktion sind Objekte. Ein iterator ist ein konzept, selbst wenn er in dieser implementation ein zeiger ist, tut das keinen Abbruch.
    Auch die übergebenen funktoren sind ein Konzept und streng genommen auch OO.

    Aber die verwendung ist funktionale programmierung:

    std::vector<int> vec;
    ...
    //alle member mithilfe einer lambda funktion quadrieren und das Ergebnis in einen neuen vector kopieren
    std::vector<int> sqares;
    std::transform(vec.begin(),vec.end(),std::back_insert_iterator<vector<int> >(squares),_1*=_1);
    

    oder das hier:

    a.foo()
    b=a.bar();
    if(a.doSth())
    {
        b.blub();
        a.setBar(b);
    }
    ...
    

    das ist ganz klar prozedurale Programmierung, weil man angibt was das programm in welcher reihenfolge zu tun hat- selbst wenn jede aufgerufene funktion virtuell ist. Aber jede funktion und jedes Objekt hierbei ist OOP.

    //nachtrag3:
    wenn //1 kein OOP für dich ist, was ist es eigentlich dann?



  • Zum Thema Definition von OOP: http://lambda-the-ultimate.org/node/2386 [...]

    edit: Ups, Duplikat. Ihr schreibt aber auch wirklich viel und lang hier 😉



  • @bashar siehe rüigers post 🙂



  • Xin schrieb:

    Du beantwortest die Frage damit, dass Du die Frage wiederholst und statt ein Fragezeichen einen Punkt setzt.
    Die Frage war nach dem "Warum".

    Zu behaupten, dass Methoden Funktionen sind, die ein implizites Argument (this) haben, nicht interessiert, ändert die Programmierweise nicht.
    Sich die Augen zuzuhalten ist keine sinnvolle Antwort.

    Es gibt keinen unterschied zwischen
    Integer Integer::plus( Integer * this, Integer b )
    und
    Integer plus( Integer a, Integer b ).

    Die eine Funktion heißt "Integer::Plus", die andere "plus" und beide sind statisch.

    Du willst also behaupten, weil eine Sprache wie C++ das Sprachkonstrukt intern anderst behandelt, habe dies Auswirkungen auf die Definition OO?



  • Xin schrieb:

    Stimmt, wenn Du so interpretierst, wie Du grade aufgeführt hast, dann zieh auch die Konsequenzen aus Deiner Aussage und bestätige, dass jedes Assemblerprogramm objektorientiert ist. Und natürlich auch alle C Programme, die Daten in beliebiger Art (eben Objekte) verarbeiten.

    Deine Art zu schließen ist nicht nur leicht unlogisch sondern völlig verquer. Du ignorierst manche Dinge, erfindest andere hinzu und belegst dadurch "zweifelsfrei" irgendwelche Dinge, die nie zur Diskussion standen. Ich bin mir allerdings noch nicht sicher, ob Du dies aus mangelndem Sachverstand tust (was man Dir natürlich nicht direkt vorwerfen kann) oder mit Absicht (was in der Tat sehr unhöflich wäre).



  • Tim schrieb:

    Was haben wir hier eigentlich. Wir haben zwei Parteien: Die eine hat eine schwammige, unpräzise Definition von OOP, die andere eine harte, präzise. Was mich dabei aber wundert ist, dass in einem Forum mit den übelsten Pedanten, ANSI-Standard-Fetischisten und undefined-behaviour-Propheten eben die unexakte, schwammige Definition besser angenommen wird. Müssten diese nicht alle (den Matheloser Jester mal ausgenommen) den Weg der peinlichst genauen Definition gehen? Woher kommt das? Liegt es vielleicht letzten Endes doch daran, dass die präzise Definition einfach nur unbrauchbar ist, weil sie einfach zu speziell ist?
    Mir kommt es so vor, als definiert jemand "Speiseeis" als "Mischung aus Wasser und Milch in festem Aggregatszustand mit Zucker und Zartbitterschokoladepartikeln mit definierter Größe", während der Pöbel das einfach nur als "na Eis halt" definiert. Bei der ersten Definition ist eindeutig, dass Stracciatella gemeint ist. Der Pöbel hingegen kann sich theoretisch die Zunge am Trockeneis einfrieren, aber sollte da nicht schon längst der "common sense" eingesetzt haben?

    Der Vergleich ist ein guter Ansatz, hinkt allerdings etwas, da er unvollständig ist.
    Xin definiert was ein Objekt ist und darauf aufbauend Objekt-Orientierung. Bei deinem Stracciatella-Beispiel lässt du ihn aber nur die zugrunde liegende Entität definieren - mithin also nur was ein Objekt ist. Die Definition des aufbauenden Konzepts - Objekt-Orientierung - fehlt dagegen vollständig. Der Vergleich muss aber schon vollständig sein, also:
    Speiseeis (Entität) = Objekt (Entität)
    Speiseeis (Konzept) = Objekt-Orientierung (Konzept)

    Die korrekte Analogie lautet also "Speiseeis" ist eine "Mischung aus Wasser und Milch in festem Aggregatszustand mit Zucker und Zartbitterschokoladepartikeln mit definierter Größe" (Entität) und "dient direkt zum Verzehr" (Konzept). Wobei das Konzept etwas kürzer ausfallen kann, da es auf der Entität aufbaut. Und jetzt sieht man auch schon den Unterschied zur "mystischen" (siehe Bashar) Definition "na Eis halt". Denn mit der präzisen Definition kann man sinnvoll arbeiten.
    Du bist der Meinung "Zartbitterschokoladepartikeln mit definierter Größe" sei zu speziell für Speiseeis? Kein Problem. Man renne zum nächsten Eisverkäufer und zeige auf, dass das Konzept "Speiseeis" auch von anderen Entitäten erfüllt wird, welche bis auf den Streitpunkt "Zartbitterschokoladepartikeln mit definierter Größe" den Merkmalen der definierten Entität entsprechen.

    Die mystische Definition, "na Eis halt", bekommt dagegen sofort das Eis auf zugefrorenen Seen vorgeworfen und versucht sich dann mit "gesundem Menschenverstand" zu verteidigen. Letzterer ist in einer Definition allerdings inakzeptabel, da beliebig und willkürlich.
    Vielleicht wird das ja für Informatiker verständlicher, wenn man sich folgenden Code durch den Kopf gehen lässt:

    int main() {
       int mystik;
       return 4 + mystik;
    }
    

    Die Variabel "mystik" hat bei Ausführung des Programms (Interpretation der Definition) zwar sehr wohl einen konkreten Wert - nur welchen bei dir, welchen bei mir, welchen morgen und welchen gestern, das ist die Frage.
    Das sollte jetzt sogar jemand verstehen, der nicht einmal auf die Idee kommt, dass es auch nicht-mathematische, wissenschaftliche Definitionen gibt 😉



  • Du bist der Meinung "Zartbitterschokoladepartikeln mit definierter Größe" sei zu speziell für Speiseeis? Kein Problem. Man renne zum nächsten Eisverkäufer und zeige auf, dass das Konzept "Speiseeis" auch von anderen Entitäten erfüllt wird, welche bis auf den Streitpunkt "Zartbitterschokoladepartikeln mit definierter Größe" den Merkmalen der definierten Entität entsprechen.

    und genau das machen wir die ganze zeit, wir zeigen auf alles andere worauf das passt, und uns wird endgegengehalten: "hat keine Zartbitterschokoladenpartikel mit definierter Größe".

    Zumal der Vergleich in diesem Fall lauten müsste: ein Fahrzeug ist alles, was ein lenkrad hat.
    Wir verweisen im folgenden auf ein Flugzeug, das wie wir alle wissen, einen Steuerknüppel besitzt, und uns wird gesagt, dass es kein Fahrzeug sein kann, da ein Fahrzeug ein lenkrad besitzt.
    Dann verweisen wir auf ein Fahrrad, und uns wird gesagt, dass es kein lenkrad hat, Schiffe haben auch kein lenkrad, also auch kein Fahrzeug.
    Und der gesunde Menschenverstand sagt einem: das einzige was eigentlich wirklich damit definiert werden kann, ist ein Auto.

    Ich frag mich nur was passiert, wenn wir dann ein pc-lenkrad aufführen. ist dann ein Pc ein Fahrzeug?



  • otze schrieb:

    und genau das machen wir die ganze zeit, wir zeigen auf alles andere worauf das passt, und uns wird endgegengehalten: "hat keine Zartbitterschokoladenpartikel mit definierter Größe".

    Schau dir die Analogie noch einmal genau an. Zartbitterschokoladenpartikel gehören zur Entitätsdefinition. Der Großteil des Theaters hier dreht sich aber um die Konzept-Definition welche Laufzeit-Polymorphie verlangt.



  • minhen schrieb:

    Xin definiert was ein Objekt ist und darauf aufbauend Objekt-Orientierung.

    Hm, das muß ich bis jetzt überlesen haben. Wo definiert er, was ein Objekt ist? Soweit ich das überblicke verwendet er diesen Begriff als Blackbox. Im Gegenzug haben hier einige schon erklärt was ein Objekt sein soll und das Konzept OOP dann dadurch beschrieben, dass Objekte verwendet werden. Zudem unterscheiden wir uns in der Auslegung des Begriffs "Beziehung zwischen Objekten". Für Xin muß diese Beziehung (warum auch immer) Vererbung bedeuten. Andere wollen da auch Komposition und Aggregation dazuzählen. Was ist daran nun unpräzise und mystisch?



  • minhen schrieb:

    Der Großteil des Theaters hier dreht sich aber um die Konzept-Definition welche Laufzeit-Polymorphie verlangt.

    Es geht eben gerade darum, dass sie dies nicht verlang. 😉



  • @minhen xin hat mich doch vor 5(?) Seiten gefragt, wieso ich denn Objekt definiere, das ist doch nicht nötig.

    //edit Seite 25

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


Anmelden zum Antworten