OOP: soll man jetzt alles in ne Klasse packen oder watt?



  • Zeus schrieb:

    Das ist ein schlechter witz.

    Wieso?

    Hat doch alles was du gefordert hast.

    btw. CLOS hat auch kein wirklichen Zugriffsschutz, wenn man keinen Accessor für ein Member definiert, dann kann man immer noch über die Funktion slot-values darauf zugreifen. Dennoch ist CLOS OOP.



  • TactX schrieb:

    GPC schrieb:

    *Plonk* Klar kann man mit C OOP programmieren, schau dir nur mal gtk+ an. Polymorphie z.B. ist auch nur ein Pointer auf eine Tabelle mit Funktionszeigern...

    Ach du Spielverderber 😞 😉

    😃 :p

    Am Ende ist auch der OOP-ste C++ Code Assembler, also kann keiner erzählen, dass man eine Technik von oben nicht auch weiter unten umsetzen kann.



  • Gregor schrieb:

    ...und drehen wir die Diskussion doch mal um: Bisher wurde argumentiert, dass es nicht objektorientiert ist. Was spricht denn dafür, dass es sich um objektorientierte Programmierung handelt? Welche Kriterien werden diesbezüglich erfüllt, welche müssen erfüllt werden?

    Eine Zeile kann nicht Objekt Orientiert sein. Soweit stimmen wir hoffentlich ueber ein.

    Ein Konzept kann OO sein. einfach nur globale Funktionen zu haben ist erstmal nicht OO. Soweit sollten wir ueberein stimmen.

    Betrachten wir aber nun swap(). swap() existiert erstmal garnicht. Es steht nur in der Doku: "um den algorithm sort() verwenden zu koennen muss ein Objekt swap() anbieten".

    Nun denn: kein Problem: es ist statische polymorphie, dh ich brauche kein interface ISwapable. Ich koennte es zwar verwenden, aber da eh alles statisch ist, bringt es mir nichts. Es wuerde mir nur in zusammenhang mit reflection etwas bringen - was wieder etwas komplett anderes ist.

    nun denn: ich definiere in meinem bitmap Objekt eine methode void swap(Bitmap& other);

    alles ist fein. wir nehmen noch ein ISwapable interface dazu:

    class Bitmap : public ISwapable {
    ...
      void swap(Bitmap& other);
    };
    

    wir haben jetzt natuerlich das problem dass wir ploetzlich laufzeit polymorphie brauchen:

    class Bitmap : public ISwapable {
    ...
      void swap(Object& other);
    };
    

    und schon ist die statische typsicherheit dahin.
    mit statischer polymorphie koennen wir aber folgendes machen:

    class Bitmap {
    ...
      void swap(Bitmap& other);
    };
    

    dh, ich habe komplette statische typsicherheit. eben statische polymorphie. einfach nur ein anderes konzept als dynamische.

    ich kann bei beiden varianten dann folgendes machen:

    void foo(ISwapable& a, ISwapable& b) {
      a.swap(b);
    }
    
    template<typename T>
    void foo(T& a, T& b) {
      a.swap(b);
    }
    

    stimmen wir jetzt ueberein dass beide varianten ebenbuertig sind? eine ist statisch, die andere dynamisch.

    nun haben wir aber ein syntaktisches problem:

    int a=1,b=2;
    foo(a,b);
    

    klappt nicht.

    das ist doof. ich will naemlich dass das klappt.

    also verwende ich einen trick: aus Bitmap::swap mache ich ::swap

    class Bitmap {
    ...
    };
    void swap(Bitmap& a, Bitmap& b) {
    ...
    }
    

    das konzept ist komplett identisch mit Bitmap::swap. Ich habe nur die syntax geaendert.

    das nette ist: ich kann jetzt

    void swap(int& a, int& b) {
    ...
    }
    

    machen und mein foo funktioniert ploetzlich auf fuer alle builtins 🙂

    ein anderes nettes konzept, dass mit Java Interfaces nicht geht, sind default implementierungen:

    template<typename T>
    void swap(T& a, T& b) {
      T c=a;
      a=b;
      b=c;
    }
    

    ich koennte zwar in ISwapable swap() eine defaultimplementierung verpassen, aber was wenn wir statt swap() jetzt einfach etwas neues erfinden:

    template<typename T>
    void inc(T& a) {
      ++a;
    }
    

    und schon habe ich fuer mein Bitmap inc() implementiert (vorausgesetzt es gibt einen ++ operator).

    und ich kann inc() jederzeit spezialisieren wenn ich will.

    aber es ist und bleibt nichts anderes als wenn ich jetzt ueberall ein IIncable interface implementiere. Nur dass statische polymorphie hier eben nett ist, waehrend bei sowas dynamische polymorphie einfach zu unflexibel ist.

    was wir hier haben sind nichts anderes als ein interface fuer statische polymorphie.

    ich weiss gregor, dass fuer dich etwas dass nicht existiert (naemlich ein konkretes interface) nicht gueltig ist - aber stell dir diese default implementierungen mit templates als abstrakt vor. dann hast du hier deine interface definition.

    statische polymorphie ist eben etwas anderes als dynamische: da kann man nicht 1;1 die selben konzepte und regeln geltend machen.

    javascript hat zB keine dynamische polymorphie im herkoemmlichen sinn, es gibt ja keine virtuellen methoden und klassen und interfaces sowieso nicht.

    DEvent schrieb:

    Komm du mal runter, nur weil du und volkrat und noch ein paar miteinader einer Meinung ist, heist es nicht das sie stimmt.

    dann benimm dich wie ein erwachsener und mach mal n bisschen nachforschung bevor du ueber ein thema sprichst von dem du nichts verstehst.

    auf deiner hp steht, dass du nur c++, java und c# kennst. na logisch dass du nicht weisst wovon wir hier reden. mag hart klingen, aber schau mal ueber deinen teller rand. hier hast du leute mit weitaus mehr erfahrung was sprach konzepte betrifft, als du sie hast.

    Ich finde es komisch das du ein Sprachfeature hackst und dann behauptest das es nich gibt.

    behaupte ich nicht.
    lies bitte was ich schreibe.

    es geht darum dass ein sprach feature nicht bestimmend sein kann ob der code OO ist oder nicht.

    denn ich kann in assembler OO programmieren. und da habe ich keine sprachfeatures die mir dabei helfen.

    Der Präprozessor ist ein einfacher Textersetzer, hat mit der Sprache C++ nicht viel zu tun. Erst wird alles durch die #defines ersetzt, dann erst kriegt der C++-Compiler den Code, den er kompiliert.

    dann mach ich es per casts.
    auch gut.

    Zeus schrieb:

    Ausserdem hab ich schon auf Javasvript aufgezeigt, dass es Datenkapseln kann. Du hingegen kommst wieder und behauptest das Gegenteil davon.

    lies bitte was ich schreibe.
    und ignorier nicht immer alles was dir nicht in den kram passt.

    JS kann kein private oder aehnliches. es gibt 3 arten ein objekt zu definieren und 2 davon koennen keine private elemente simulieren. eine recht neue art objekte zu definieren kann dies simulieren indem sie scopes ausnuetzt.

    es ist aber nichts was in der sprache vorgesehen ist und schongarnicht von anfang an dabei war.

    in JS verwendet man deshalb auch idR keine private sachen, weil es sich unnatuerlich anfuehlt dort.

    man kann es zwar simulieren, aber das kann ich in C genauso mit static.
    zugriffskontrolle ist kein feature das JS unterstuetzt. zB gibt es keine moeglichkeit ein protected zu simulieren. private widerspricht auch ziemlich dem JS objekt konzept.



  • gucktmal, sogar brainfuck kann oop: http://esoteric.sange.fi/brainfuck/bf-source/prog/oobrain.b

    nee echt jetz allein dass der trhead hier 13 seiten hat zeigt doch dat ihr nix könnt 😕 😮 🙄



  • clan der oop-ritter schrieb:

    Zeus schrieb:

    Zeig mir Datenkapselung in C.

    // lol.h
    #ifndef LOL_H
    #define LOL_H
    
    int get();
    void set(int i);
    
    #endif
    
    // lol.c
    #include "lol.h"
    
    static int zahl;
    
    int get() {
        return zahl;
    }
    
    void set(int i) {
        zahl = i;
    }
    

    Da hast du deine Kapselung du "OOP-Ritter".

    Hab grad zu viel intus um auf Shade einzugehen.
    Aber der Code oben ist ein Witz.
    Wie willst du nun mehrere Objekte erstellen ? Auch wenn du static bei zahl weglässt, kannst du nicht mehrere Objekte habe.

    behaupte ich nicht.
    lies bitte was ich schreibe.

    Du hast geschrieben das es keine Kapselung in C++ gibt, und als Grund hast du deinen Textersetzer genannt #define private public

    statische polymorphie ist eben etwas anderes als dynamische: da kann man nicht 1;1 die selben konzepte und regeln geltend machen.

    Was du statische Polymorphie nennst, nenne ich prozedurales Programmieren. Denn diese statische Polymorphie gab es schon weitaus länger, bevor irgendjemand überhaupt auf den Begriff OOP kahm.
    Nimm den Schlüsselwort namespace weg, was hast du dann? Prozeduren oder Funktionen die global verfügbar sind, die aber als Parameter ein Objekt erwarten.
    Sowas habe ich schon mit Pascal und Basic programmiert.

    Wenn du nun Prozeduren und Funktionen hast, die statt Objekte einen Datenstrom (Stream) erwarten, nennt du es dann datenstromorientierte Programmierung ?



  • @DEvent
    ob wäre das ein Problem.

    //foo.h
    
    struct foo;
    struct foo *new_foo(int bar);
    void delete_foo(struct foo *obj);
    
    //public accessors
    int get_bar(struct foo *obj);
    void set_bar(struct foo *obj, int i);
    int get_baz(struct foo *obj);
    
    //Methoden
    void calc_baz(struct foo *obj);
    
    //foo.c
    #include <stdlib.h>
    
    struct foo {
      int bar;
      int baz;
      int secret;
    };
    
    struct foo *new_foo(int bar) {
      struct foo *obj = malloc(sizeof(struct foo));
      obj->bar = bar;
      obj->secret = 100;
      return obj;
    }
    
    void delete_foo(struct foo *obj) {
      free(obj);
    }
    
    int get_bar(struct foo *obj) { return obj->bar; }
    void set_bar(struct foo *obj, int bar) { obj->bar = bar; }
    int get_baz(struct foo *obj) { return obj->baz; }
    
    void calc_baz(struct foo *obj) { obj->baz = obj->secret * obj->bar; }
    

    Braucht kein Genie um das rauszufinden. Was daran ist nicht OO?

    Btw. habe ich dir bereits aufgezeigt, dass du das C++ Accessor-System ohne #define umgehen kannst. Aber selbst mit #define wäre es ein legaler Weg, da der C++ Standard das erlaubt.



  • Aber selbst mit #define wäre es ein legaler Weg, da der C++ Standard das erlaubt.

    Dann ist der C++ Standard noch schlimmer als ich dachte und ich bin froh mit C++ aufgehört zu haben
    Aber verflucht noch mal ich wollte eigentlich in eine Disco....



  • rüdiger schrieb:

    @DEvent
    ob wäre das ein Problem.

    //foo.h
    
    struct foo;
    struct foo *new_foo(int bar);
    void delete_foo(struct foo *obj);
    
    //public accessors
    int get_bar(struct foo *obj);
    void set_bar(struct foo *obj, int i);
    int get_baz(struct foo *obj);
    
    //Methoden
    void calc_baz(struct foo *obj);
    
    //foo.c
    #include <stdlib.h>
    
    struct foo {
      int bar;
      int baz;
      int secret;
    };
    
    struct foo *new_foo(int bar) {
      struct foo *obj = malloc(sizeof(struct foo));
      obj->bar = bar;
      obj->secret = 100;
      return obj;
    }
    
    void delete_foo(struct foo *obj) {
      free(obj);
    }
    
    int get_bar(struct foo *obj) { return obj->bar; }
    void set_bar(struct foo *obj, int bar) { obj->bar = bar; }
    int get_baz(struct foo *obj) { return obj->baz; }
    
    void calc_baz(struct foo *obj) { obj->baz = obj->secret * obj->bar; }
    

    Braucht kein Genie um das rauszufinden. Was daran ist nicht OO?

    Btw. habe ich dir bereits aufgezeigt, dass du das C++ Accessor-System ohne #define umgehen kannst. Aber selbst mit #define wäre es ein legaler Weg, da der C++ Standard das erlaubt.

    Doch das ist OOP. Zwar ohne die Vorteile von zB Vererbung, aber im Grunde ist es OOP. Es hat Datenkapselung, obwohl was hindert mich daran zB #include foo.c zu schreiben ?

    Aber das ist ja nicht was Shader als OOP bezeichnet.



  • Hab grad zu viel intus um auf Shade einzugehen.
    Aber der Code oben ist ein Witz.

    Ich würde dir generell empfehlen, dass du ein wenig nachdenkst, bevor du irgend etwas antwortest (selbst wenn du was intus hast), denn es war lediglich Datenkapselung gefordert.

    Zwar ohne die Vorteile von zB Vererbung, [...]

    Hast du überhaupt schonmal in Erwägung gezogen, dir die Argumente der anderen auch nur ansatzweise durchzulesen? Im Zuge der Diskussion wurde bereits mehrmals auf ein Dokument verwiesen, dass objektorientierte Programmierung in C genauer beschreibt und so eben auch Vererbung.

    obwohl was hindert mich daran zB #include foo.c zu schreiben ?

    Genau der selbe Bereich im Verstand, der dir auch bei einem #define private public ein seltsames Gefühl in der Bauchgegend verschafft.

    Außerdem lässt sich sowieso eine Verständnisschwäche von OOP erkennen, wenn man auf derartig "konkrete Klassen" wie MenuDatei, MenuBearbeiten, etc.. fixiert ist. 🙄



  • DEvent schrieb:

    Doch das ist OOP. Zwar ohne die Vorteile von zB Vererbung, aber im Grunde ist es OOP.

    Auch das ist möglich. Aber lies dir mal das Buch "OOP with ANSI C" durch (ein Link auf die PDF wurde hier übrigens 2mal gepostet)

    Es hat Datenkapselung, obwohl was hindert mich daran zB #include foo.c zu schreiben ?

    Wie wir gezeigt haben, kannst du auch in anderen Programmiersprachen die Zugriffskontrolle umgehen (selbst wenn du das #define-Beispiel nicht hinnehmen willst, ich habe ein Beispiel ohne #define gezeigt, welches du ja offensichtlich überlesen willst).

    Aber das ist ja nicht was Shader als OOP bezeichnet.

    Weil?

    Aber im Grunde ist es Sinnlos sich mit dir zu unterhalten.



  • clan der oop-ritter schrieb:

    Zeus schrieb:

    Zeig mir Datenkapselung in C.

    // lol.h
    #ifndef LOL_H
    #define LOL_H
    
    int get();
    void set(int i);
    
    #endif
    
    // lol.c
    #include "lol.h"
    
    static int zahl;
    
    int get() {
        return zahl;
    }
    
    void set(int i) {
        zahl = i;
    }
    

    Da hast du deine Kapselung du "OOP-Ritter".

    Sry, das ist Informations Hidding und nicht Kapselung!!!!

    aqivalent mit folgend Code:

    class{
    public:
    int i;
    }
    

    zu

    class{
    private:
    int i;
    }
    

    aber nix OOP.



  • rüdiger schrieb:

    Wie wir gezeigt haben, kannst du auch in anderen Programmiersprachen die Zugriffskontrolle umgehen (selbst wenn du das #define-Beispiel nicht hinnehmen willst, ich habe ein Beispiel ohne #define gezeigt, welches du ja offensichtlich überlesen willst).

    #define private public ist afaik laut Standard verboten. Man darf keine keywords definen. Also fällt der Weg schonmal weg. Das andere was Du geschrieben hast ist natürlich genauso unportabel und undefiniert.



  • für die javaprogrammierer folgt hier ein ansatz, der wo nicht so kompliziert sein tut.

    ein ahnunghaber nimmt ein problem mit OOA auf.
    und ein zweiter ahnunghaber designed das programm mit OOD.
    resultat sind ganz einfache anweisungen und viel UML.
    dann kommen viele nichtanhnunghaber und codieren das.
    die programmierer haben weder die berechtigung noch die möglichkeit,
    am design entscheidendes zu ändern. ob die mit relativ wenig arbeit
    das in java/c++ oder mit mehr arbeit in c/basic machen, ist egal.
    selbst wenn sie ein mit UML entworfenes programm in assembler schreiben (und fast nix anderes macht der compiler am ende), bleibt es objektorientiert.
    also kann man nicht an einem sprachmittel festmachen, ob das programm objektorientiert ist.

    OOA=objektorientierte analyse
    OOD=objektorientiertes design





  • Jester schrieb:

    #define private public ist afaik laut Standard verboten. Man darf keine keywords definen. Also fällt der Weg schonmal weg. Das andere was Du geschrieben hast ist natürlich genauso unportabel und undefiniert.

    mit type-casts bekommt man aber jedes 'private' weg

    volkard schrieb:

    ob die mit relativ wenig arbeit
    das in java/c++ oder mit mehr arbeit in c/basic machen, ist egal.
    selbst wenn sie ein mit UML entworfenes programm in assembler schreiben (und fast nix anderes macht der compiler am ende), bleibt es objektorientiert.

    es gibt auch uml-malprogramme die erzeugen gleich quelltexte, auch in nicht-oo sprachen. da braucht's nocht nicht mal einen, der codes rein hackt...



  • net schrieb:

    Jester schrieb:

    #define private public ist afaik laut Standard verboten. Man darf keine keywords definen. Also fällt der Weg schonmal weg. Das andere was Du geschrieben hast ist natürlich genauso unportabel und undefiniert.

    mit type-casts bekommt man aber jedes 'private' weg

    Zeig mal bitte eine portable, standardkonforme Lösung um das private wegzukriegen. Ich bin gespannt. (Bitte keine Sonderfälle wie ne template-Funktion in der Klasse oder sowas).



  • Jester schrieb:

    Zeig mal bitte eine portable, standardkonforme Lösung um das private wegzukriegen. Ich bin gespannt. (Bitte keine Sonderfälle wie ne template-Funktion in der Klasse oder sowas).

    nö, was ganz einfaches:

    // diese klasse gibt's schon
    class A
    {
     // alles private
     int a;
     int b;      
    };
    
    // diese hilfsstruct braucht man für das casting
    struct B
    {
     // alles public
     int a;
     int b;       
    };
    
    ...
      A a;
      a.b = 1234;         // geht nicht, weil private
     ((B*)&a)->b = 1234;  // geht
    ...
    

    ob's standardkonform ist??? aber es sieht so aus...



  • Sorry Leute, aber
    Objektorientierte Programmierung ist nicht wenn man eine nicht OOP Sprache an mich nehme und Code schreibt, der augenscheinlich die Definition von OOP erfült.
    Den in der Programmierung steht die Sprache in Vordergrund.

    Wenn ihr sagt ich hab eine OO-Umsetztung in prozedualen Programmiersprachen (OOP-like), dann würde ich es akzeptieren, denn eine Umsetztung ist wirklich sehr leicht.

    OOP bringt Konzepte mit sich, um Beschreibung zu tätigen aus der Realen Welt.
    Und bei euren Lösung ist recht technisch, viele Zeiger, funktionen,....

    Der Vorteil ist doch die Einfachheit(ich meine damit nicht dass das Konzept einfach zu verstehen ist), wenn man so die Codebeispiele von ANIS C OOP sieht, bleibt aber nix übrig.



  • Zeus schrieb:

    Denn in der Programmierung steht die Sprache in Vordergrund.

    nee, das wär ja schlimm. die sprache ist nur ein werkzeug. wenn du einen teller suppe auslöffelst steht das stillen deines hungers im vordergrund und nicht der löffel 😉



  • Zeus schrieb:

    Sorry Leute, aber
    Objektorientierte Programmierung ist nicht wenn man eine nicht OOP Sprache an mich nehme und Code schreibt, der augenscheinlich die Definition von OOP erfült.
    Den in der Programmierung steht die Sprache in Vordergrund.

    Ach ja. Wie nennst du denn prozeduralen Code der in einer OOP-Sprache geschrieben ist?

    Zeus schrieb:

    Wenn ihr sagt ich hab eine OO-Umsetztung in prozedualen Programmiersprachen (OOP-like), dann würde ich es akzeptieren, denn eine Umsetztung ist wirklich sehr leicht.

    Eine objektorientierte Umsetzung die der objektorientierten Programmierung quasi ähnlich ist, hm? 🙄
    [/quote]


Anmelden zum Antworten