Was ist der 'Witz' bei der OOP?

Von: , Frage gestellt am Sa, 11. Feb 2006

Hallo,


vor vielen Jahren habe ich programmieren gelernt, zuerst PASCAL, dann C, dann mit Teilen aus C++.

Jedenfalls habe ich das Denken in Prozeduren gelernt, und ich schreibe alles, was ich brauche, in C. Mitunter benutze ich auch Klassen für bestimmte Teile eines Programms (der Ordnung halber), und schreibe dazu eine Schnittstelle für die Funktionsaufrufe, um im Rest des Programms keine gemischte Syntax zu haben.

Ich nehme zwar an, daß es bei der OOP um mehr geht als bloß um Ordnung oder Übersichtlichkeit, fürchte aber, ich habe dieses "mehr" nie verstanden (offengesagt zum Teil aus Aversion, weil ich es immer unangenehm fand, OOP-Quelltext zu lesen, oder mich mit MFC o. ä. zu beschäftigen).

Wer kann mir kurz erklären, wofür die OOP eigentlich wirklich gut ist bzw. warum es sich lohnt, das zu lernen?


Grüße,

I.

10 Antworten zu dieser Frage

  1. Antwort von nach einer Stunde 0 hilfreich
    Re: Was ist der 'Witz' bei der OOP?

    Hallo,

    bei der prozeduralen Programmierung sind die Prozeduren "allwissend", das heißt, jede Prozedur darf auf alles zugreifen. Das heißt aber auch, bei einer Änderung muss jede Prozedur wenigstens überprüft werden, ob sie betroffen ist. DIe Änderung an einer Prozedur kann damit gewaltige Folgen haben.

    Bei der Objektorientierung verteilst du die Verantwortung im System. Jedes Objekt hat sieht nur einen winzigen Ausschnitt des Ganzen. Änderungen, die ein Objekt betreffen, kann man deshalb in diesem Objekt lösen. (Z.B. Datenbank: Ein Objekt weiß, wie es erstellt wird. Kein anderer weiß das sonst. Und keiner will es sonst wissen. Änderungen an der DB werden deshalb nur noch in den Objekten, die daraus erstellt werden geändert.)

    Vorteil: Man kann Softwareprojekte leichter ändern, große Teile der Software können wiederverwendet werden, Fehler sind einfacher zu finden.

    UND: man kann in einer schönen Programmiersprache, nämlich Java, programmieren!

    Gruß

    Peter [Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

    • Antwort von nach 4 Stunden 0 hilfreich
      Re^2: Was ist der 'Witz' bei der OOP?

      Hallo, Änderungen, die ein Objekt betreffen, kann man
      deshalb in diesem Objekt lösen.
      Vorteil: Man kann Softwareprojekte leichter ändern, große
      Teile der Software können wiederverwendet werden
      Soweit zur Theorie ;)

      In der Praxis ist es nach meiner bisherigen Erfahrung in der OOP
      so, dass recht umfangreiche Vererbungshierarchien bestehen, also
      Klassen mit Unterklassen. Gibt es nun größere Änderungswünsche
      müssen dann im schlimmsten Fall alle Klassen der
      Vererbungshierarchie angepasst werden. Dabei muss man letzlich auch
      wissen, welche Teile der Vaterklasse von den Kindklassen wie
      verwendet wird. Kurz, die Vererbung verletzt das Geheimnisprinzip
      und macht Softwareänderungen schwierig. Fehler sind einfacher zu finden
      Auch hier habe ich wieder Einwände ;)

      Um die Klassen wiederverwendbar zu machen, kommen
      insbesondere in der GUI-Programmierung Beobachter-Muster
      zum Einsatz. Damit kann sich grob gesagt jede beliebige
      Klasse nach Anmeldung Nachrichten von einer anderen Klasse
      senden lassen. Da diese Beziehungen aber erst zur Laufzeit
      geknüpft werden, ist es sehr schwierig, das (Fehl-)Verhalten
      von Komponenten näher zu untersuchen und die Fehlerquelle
      unter allen möglichen Kandidaten auszumachen.

      Diese Probleme bestehen in der prozeduralen Programmierung
      allerdings auch oder sogar in verschärfter Form, sowie noch
      einige andere mehr, siehe z.B. auch die Diskussion des gleichen
      Themas in http://www.wer-weiss-was.de/cgi-bin/forum/showarticl...
      .

      Ich wollte durch die kritischen Untertöne nur anklingen lassen, dass
      die OOP kein Allheilmittel für alle Programmierprobleme ist.

      Gruß,
      -Andreas (Java-/C-/Perl-/Tcl-Programmierer)

      • Antwort von nach einem Tag 0 hilfreich
        Re^3: Was ist der 'Witz' bei der OOP?

        Vorteil: Man kann Softwareprojekte leichter ändern, große
        Teile der Software können wiederverwendet werden
        Soweit zur Theorie ;)

        In der Praxis ist es nach meiner bisherigen Erfahrung in der
        OOP
        so, dass recht umfangreiche Vererbungshierarchien bestehen,
        also
        Klassen mit Unterklassen.
        Daraus ergibt auch noch ein Performance-Problem:

        1. Beim Erzeugen eines Objekts werden dann zig Funktionen Aufgerufen um das Objekt zu initialisieren. Wenn man Pech hat sind die alle noch in unterschiedlichen Bibliotheken hinterlegt....
        2. Beim Freigeben eines Objekts geschieht das Selbe nochmals.
        3. Eine einfach aussehende Zuweisung:
        Obj1 = Obj2
        löst die selbe Lawine an Aufrufen aus. Am Ende wundert sich dann einer, wieso seine Datenbank unbrauchbar ist.

        MfG Peter(TOO)

    • Antwort von nach einem Tag 0 hilfreich
      Re^2: Was ist der 'Witz' bei der OOP?

      Hallo Auchfalls,
      bei der prozeduralen Programmierung sind die Prozeduren
      "allwissend", das heißt, jede Prozedur darf auf alles
      zugreifen. Das heißt aber auch, bei einer Änderung muss jede
      Prozedur wenigstens überprüft werden, ob sie betroffen ist.
      DIe Änderung an einer Prozedur kann damit gewaltige Folgen
      haben.
      Das kommt aber sehr auf die Disziplin des Programmieres an.

      Bei meinen C-Programmen wird das ganze Problem zuerst einmal in Module zerlegt.
      Dann besteht jedes Modul aus der normalen xxx.C- und einer xxx.H-Datei. Alles was von aussen zugänglich ist steht in der xxx.H. Zudem ist alles was nach aussen hin nicht öffentlich sein soll in xxx.C als "static" declariert.

      Leider muss ich gerade ein Projekt bearbeiten, bei welchem man sich nicht an diese Regeln gehalten hat. Da sind einfach irgendwo im Quelltext "extern"-Verweise auf Variablen und Prototypen von Funktinen wild verstreut, wo man etwas gerade benötigte. Bei Modulen mit 4000-Zeilen ist das etwas unübersichtlich.......

      MfG Peter(TOO)

  2. Antwort von nach einem Tag 0 hilfreich
    Re: Was ist der 'Witz' bei der OOP?

    Hallo,


    danke für Eure bisherigen Antworten.

    Also während bei "klassischem" C der Quelltext in Module, einzelne Quelltextdateien, unterteilt werden kann, so daß eine Funktion nur das "sieht", was in im gleichen Modul steht oder global deklariert und mittels Headerdateien zugänglich gemacht wurde - ist die OOP also eine Art von Ausweitung dieses Prinzips: die Funktion "sieht" nur das, was in der gleichen Klasse steht oder mittels Vererbung zugänglich gemacht wurde. Also:

    Klasse ist wie Modul bzw. Quelltextdatei,

    und

    include-Mechanismus ist wie Vererbung.

    Weiters, man kann mit Moduln und Headerdateien mehr oder weniger diszipliniert umgehen, und wenn diszipliniert, erreicht man dasselbe wie mit der OOP, nämlich abgekapselte (im Modul als "static" deklarierte) Variablen und Funktionen, und man kann in einem kleinen Bereich Änderungen durchführen, ohne sich um das restliche Programm zu kümmern.

    Soweit habe ich es bisher verstanden. Ist das im Grunde schon alles, was die OOP bietet, oder gibt es etwas, das nur mit OOP und anders nicht oder nur schwer geht?


    Grüße,

    I.

    • Antwort von nach 2 Tagen 0 hilfreich
      Re^2: Was ist der 'Witz' bei der OOP?

      Hallo, Weiters, man kann mit Moduln und Headerdateien mehr oder
      weniger diszipliniert umgehen, und wenn diszipliniert,
      erreicht man dasselbe wie mit der OOP, nämlich abgekapselte
      (im Modul als "static" deklarierte) Variablen und Funktionen,
      und man kann in einem kleinen Bereich Änderungen durchführen,
      ohne sich um das restliche Programm zu kümmern.
      Streng genommen müsstest Du sagen, dass die
      Prozeduren (oder Funktionen) in C die "Objekte"
      sind. Denn diese sind
      - vollständig gekapselt,
      - erhalten Nachrichten (aktuelle Parameter). Soweit habe ich es bisher verstanden. Ist das im Grunde schon
      alles, was die OOP bietet, oder gibt es etwas, das nur mit OOP
      und anders nicht oder nur schwer geht?
      "Vererbung", als "NEU" ist ein "ALT", geht so mit
      include nicht, höchstens "NEU" hat ein "ALT".

      Ansonsten kannst Du in C eine Tabelle von Funktions-
      zeigern in eine struct packen und diese (Funktionen)
      dann "objektorientiert" aufrufen. Um das aber schmerz-
      frei und klar machen zu können, nimmt man aber besser C++,
      da ist das schon eingebaut ;-)

      Insbesondere die Initialisierung wäre in
      C sehr häßlich anzusehen, in C++ geschieht
      die Initialisierung der "Funktionszeiger"
      (heisst jetzt "Memberfunktionen") "deskriptiv"
      während der Deklaration der Klasse.

      Letztlich dient die ganze OOP'erei dazu, seinen
      Code klar und übersichtlich zu halten; so daß
      dann an Wiederverwendung überhaupt erst zu
      denken ist!

      <rant>
      Ausser bei Java, da wir OOP derart zum Prinzip
      gemacht, dass es hin und wieder schwer fällt,
      vor lauter Objekt-Syntax-Zeilenrauschen noch
      etwas vom eigentlichen Problem zu erkennen ;-)
      </rant>

      Grüße

      CMБ

    • Antwort von nach 2 Tagen 0 hilfreich
      Re^2: Was ist der 'Witz' bei der OOP?

      Hallo I.,

      danke für Eure bisherigen Antworten.

      Also während bei "klassischem" C der Quelltext in Module,
      einzelne Quelltextdateien, unterteilt werden kann, so daß eine
      Funktion nur das "sieht", was in im gleichen Modul steht oder
      global deklariert und mittels Headerdateien zugänglich gemacht
      wurde - ist die OOP also eine Art von Ausweitung dieses
      Prinzips: die Funktion "sieht" nur das, was in der gleichen
      Klasse steht oder mittels Vererbung zugänglich gemacht wurde.
      Also:
      Du denkst immer noch prozedural und nicht OO ;-)

      OO geht im Prinzip von den Variablen aus, welche halt etwas komplexer sind und Objekte genant werden.

      Also etwas vereinfacht:

      Du deklarierst eine "int" Variable.
      Bei OOP sind nun automatisch alle Operationen welche für dieses Objekt definiert sind mit dieser Variablen verbunden (also in diesem Beispiel "-+/*%" aber auch Funktionen wie atoi() oder itoa() ).
      Du kannst dann statt:

      short i;
      char *s;
      ......
      i = atoi(s);

      einfach:
      i = s;
      schreiben. Da atoi() im Objekt hinterlegt ist, kann der Compiler aus den unterschiedlichen Typen automatisch erkennen, welche Funktion zur Konvertierung aufgerufen werden muss.
      OK, bei einem int macht das noch keine Vorteile, aber wenn du ein kompliziertes struct hast ......

      Hinzu kommt, dass man auch die einfachen Operatoren wie z.B. "+" überladen kann, also als Name für eine eigene Funktion verwenden kann.
      Dann geht auch statt
      s = strcat(s1,s2);
      auch
      s = s1 + s2;

      Nehmen wir mal die "gebräuchlichen" imaginären Zahlen als kleines Beispiel:

      typedef struct
      {
      float real;
      float imag;
      } imaginär;
      


      Da dieses struct öffentlich zugänglich sein muss, kannst du nicht verhindern, dass ein Programmierer an den beiden Elementen selber rumpfuscht. In OO kannst du die ganze Geschichte kapseln, sodass keiner mehr an real und imag rumpfuschen kann, obwohl jeder ein Object des Typs "imaginär" erzeugen kann. Zudem ist dann auch im Object abgelegt wie es z.B. ausgedruckt wird.
      Somit kannst du jederzeit die Deklaration von float in double ändern. Oder du baust das ganze komplett um und verwendest eine eigene Exponential-Darstellung:
      typedef struct
      {
      long long mantisse;
      long long exponent;
      } myfloat
      typedef struct
      {
      myfloat real;
      myfloat imag;
      } imaginär;
      

      Für den Anwender des Objekts ist nicht sichbar wie "imaginär" intern aufgebaut ist.

      OK, soweit die Theorie, in der Praxis kann man alle Konzepte misbrauchen !!!
      Nur weil eine Sprache ein "goto" kennt, muss man es ja nicht verwenden.

      MfG Peter(TOO)

      • Antwort von nach 2 Tagen 0 hilfreich
        P.S.

        Hallo I.,

        Vielleicht solltest du einmal ein kleines C++-Prgramm nehmen und es in C übersetzen. Aus hystorischen Gründen kann das eigentlich jeder C++-Compiler noch heute. Anfangs war C++ als eine Art Präprozessor ausgelegt, welcher C-Code produzierte.

        MfG Peter(TOO)



Keine passende Antwort gefunden? Jetzt eigene Frage stellen!