

Objektorientiertes Programmieren

Vlado Plaga

1 Die Vorteile des objekt-orientierten Programmierens

...werden ganz gut durch den folgenden (von mir hoffentlich richtig
bersetzten) Satz aus ``Thinking in Java''([footnote] Bruce Eckel:
``Thinking in Java. The definitive introduction to object-oriented
programming in the language of the world-wide web''. Full text, updates
and code at http://www.bruceeckel.com)  ausgedrckt:

``Fr Programmierer machen die Eleganz und die Klarheit des Objekt-Modells
und die Macht der objekt-orientierten Werkzeuge und Bibliotheken das
Programmieren zu einer erfreulicheren Aufgabe, und Programmierer erleben
einen Anstieg ihrer Produktivitt''

Die Schwierigkeit besteht darin, dass es laut Eckel schwierig ist,
objekt-orientiertes Programmieren (OOP) zu lernen, also selbst gute,
wiederverwendbare Objekte zu programmieren. Aber dafr stellen erfolgreiche
OOP-Sprachen auch eine Bibliothek gut entwickelter und leicht zu verwendender
Objekte bereit.

2 Das Fortschreiten der Abstraktion\label{sec:abstraktion}

Die Komplexitt der mit einer Programmiersprache lsbaren Probleme
hngt laut Eckel direkt von Grad und Qualitt der Abstraktion der
Sprache ab. Whrend Assembler nur eine leichte Abstraktion der zu
Grunde liegenden Maschine darstellt, sind ``imperative'' Sprachen
(Fortran, Basic und C) Abstraktionen der Assembler-Sprache. Sie sind
zwar grosse Verbesserungen gegenber Assembler, zwingen einen aber
immer noch eine Verbindung zwischen dem Maschinen-Modell (``solution
space'') und dem zu lsenden Problem (``problem space'') herzustellen.
Dadurch entstehen Programme, die schwierig zu schreiben und zu warten
sind.

Der Objekt-orientierte Ansatz geht einen Schritt weiter, indem er Werkzeuge
bereitstellt, die Elemente im ``problem space'' reprsentieren. Und
dies so allgemein, dass der Programmierer nicht auf einen bestimmten
Problem-Typ festgelegt wird (wie es bei Lisp, APL und Prolog der Fall
war). Elemente im ``problem space'' und ihre Entsprechungen im ``solution
space'' sind werden ``Objekte'' genannt (wobei es natrlich auch Objekte
ohne ``problem space''-Entsprechung gibt).

Alan Kay hat die fnf Grundeigenschaften von Smalltalk, der ersten
erfolgreichen Objekt-orientierten Sprache aufgeliste:

1. Everything is an object. Think of an object as a fancy variable;
it stores data, but you can also ask it to perform operations on itself
by making requests. In theory, you can take any conceptual component
in the problem you're trying to solve (dogs, buildings, services,
etc:) and represent it as an object in your program.

2. A program is a bunch of objects telling each other what to do by
sending messages. To make a request of an object, you ``send a message''
to that object. More concretely, you can think of a message as a request
to call a function that belongs to a particular object.

3. Each object has its own memory made up of other objects. Or, you
make a new kind of object by making a package containing existing
objects. Thus, you can build up complexity in a program while hiding
it behind the simplicity of objects.

4. Every object has a type. Using the parlance, each object is an instance
of a class, where ``class'' is synonymous with ``type''. The most
important disinguishing characteristic of a class is ``what messages
can you send to it?''

5. All objects of a particular type can receive the same messages.
This is actually a very loaded statement, as you will see later. Because
an object of type circle is also an object of type shape, a circle
is guaranteed to receive shape messages. This means you can write
code that talks to shapes and automatically handle anything that fits
the description of a shape. This substitutability is one of the most
powerful concepts in OOP.

3 Grundstzlicher Aufbau von Objekten

Einfaches Beispiel aus ``Thinking in Java'': Eine Glhbirne.

Type Name: Light

Interface: on()

           off()

           brighten()

           dim()

Der type/class-Name ist Light, die Nachrichten, die man einem Light-Objekt
bermitteln kann sind an, aus, heller und dunkler. Man erzeugt einen
Zeiger([footnote] In ``Thinking in Java'' heissen die Zeiger ``handle''
(Griff, Klinke, Stiel, Bgel))  auf ein Light indem man einen Namen
(lt) fr diesen Bezeichner angibt und man erzeugt ein Objekt vom Typ
Light mit dem new Befehl. Verbunden wird es mit dem Zeiger per = Zeichen.

Light lt = new Light();

lt.on();

4 OOP in Pascal

Eigentlich gehrt Pascal ja auch zu den in \ref{sec:abstraktion} aufgefhrten
``imperativen'' Sprachen. Spter wurde dann ein Objekt-Modell aufgesetzt.
Hat man vorher schon in Pascal programmiert, knnen einem bei der
Bibliothek, mit der wir z.B. mit Herrn Sprenger arbeiten mussten,
manchmal die Haare zu Berge stehen: um einen Tastendruck abzufragen
reicht kein einfaches ``if keypressed'' mehr, sondern man schreibt

program WarteAufTastendruck

uses

  mstiftun;

var

  tastatur: vTastatur;

begin

  new(tastatur);

  tastatur^ .init;

  repeat until tastatur^ .wurdeGedrueckt;

  tastatur^ .gibFrei;

  dispose(tastatur);

end.

Hier kann man schn sehen, dass in OOP einfache Sachen hufig komplizierter
sind als in ``normaler'' Programmierung. Im Falle von Pascal macht
es vermutlich auch wenig Sinn, die vTastatur zu benutzen. 

In Java kmmert man sich brigens nicht mehr selbst um das ``zerstren''
eines Objekts und die Freigabe des Speichers, den es belegt hat. Ein
``garbage collector'' erkennt, wenn der Speicher knapp wird und gibt
dann den Speicher von nicht mehr bentigten Objekten frei. Ausserdem
wird jedes Objekt automatisch initialisiert, man kann natrlich auch
einen eigenen constructor erstellen (oder mehrere, falls der constructor
mal mit und mal ohne Parameterbergabe aufgerufen wird, das heisst
dann ``method overloading'' und wird bei ``Thinking in Java'' in Kapitel
4 behandelt;)

Wie man auch in Pascal sinnvoll Objekt einsetzen kann, zeigt ein Beispielprogramm
([footnote] ObjectDemo
- bewegt unterschiedliche Objekte (c) Erik Krause, Freiburg `95. Beispielprogramm
zum Artikel OBJEKTE aus DOS-Trend. Zu finden auf http://host4u.upws.net/personal/vlado) .
Das Programm benutzt Vererbung und die Eigenschaft, dass Objekte vom
selben Typ die gleichen Nachrichten verstehen (siehe Alan Kay, 5.).
Im Beispielprogramm werden verschiedene Objekte (Kreise, Quadrate,
Pixelwolken) auf dem Bildschirm bewegt. Das Hauptprogramm ist winzig:

for i:= 0 to ObjCount-1 do { jede Menge Objekte.. }

  case Random(5) of { ..per Zufall ausgewhlt } 

    0: Objects[i]:= New(PCircle, Init); 

    1: Objects[i]:= New(PSquare, Init); 

    2: Objects[i]:= New(PCloud, Init); 

    3: Objects[i]:= New(PCross, Init); 

    4: Objects[i]:= New(PXign, Init); 

  end; {case} 

repeat { die Hauptschleife tut nichts weiter.. } 

  for i:= 1 to ObjCount-1 do { ..als fr alle Objekte die Methode Move} 

    Objects[i]^.Move; { ..des gemeinsamen Vorfahren aufzurufen } 

until KeyPressed or { bis eine Taste gedrckt } 

      (MouseOk and MouseMoved); { oder die Maus bewegt wird } 

for i:= 1 to ObjCount-1 do { alle Objekte.. } 

  Dispose(Objects[i], Done); { vom Heap entfernen }

``Die Hauptschleife tut nichts weiter als fr alle Objekte die Methode
Move des gemeinsamen Vorfahren aufzurufen...'' und schon bewegen sich
Kreise, Dreiecke, Pixelwolken, Kreuze und Xe in verschiedenen Farben.

Borland-Pascal-Hilfe zu ``procedure New(var P: Pointer [ , Init: Constructor
]);'':

``Speziell fr die objektorientierte Programmierung wurde die Syntax
von New so erweitert, dass als zweiter Parameter ein Konstruktor zur
Instantiierung einer dyna\-mi\-schen Objekt-Variablen bergeben werden
kann. In dieser Form der Deklaration ist P eine Zeigervariable auf
ein Objekt und Construktor ein Aufruf der Konstruktor-Methode dieses
Objekttyps.''

Man htte also genauso gut schreiben knnen:

begin

  new(PCircle);

  PCircle^ .init;

end;

Alle Objekte stammen von TBouncer ab:

PBouncer = ^TBouncer; { Zeiger auf.., fr dynamische Deklaration } 

TBouncer = object { Das Ausgangsobjekt, Vorfahre aller anderen } 

  Size: integer; { Grsse ist allen gemeinsam (und quadratisch) } 

  Origin, Delta: TPoint; { auch Position und Geschwindigkeit } 

  constructor Init; { muss gebaut werden } 

  destructor Done; virtual([margin] In Pascal mssen vererbbare Methoden
virtual sein) ; 

  procedure Move; virtual; { "weiss" wie es sich zu bewegen hat } 

  procedure Draw(Show: boolean); virtual; { abstrakt, fr Move }

end;

PColorBouncer = ^TColorBouncer; 

TColorBouncer = object(TBouncer) { erster Nachkomme, immernoch abstrakt
} 

  Color: byte; { hat zustzlich Farbe } 

  constructor Init; { ..die initialisiert werden muss } 

  procedure CalcDraw(var x1, y1, x2, y2: integer); { neue Koordinaten
} 

end;

Hier die Deklaration eines Kreises und eines Quadrats:

PCircle = ^TCircle; 

TCircle = object(TColorBouncer) { was anschauliches: ein Kreis } 

  Radius: integer; { hat einen Radius } 

  constructor Init; { der berechnet werden mchte } 

  procedure Draw(Show: boolean); virtual; { kann sich zeichnen } 

end; 

PSquare = ^TSquare; 

TSquare = object(TColorBouncer) { ein Quadrat, erbt alles restliche
} 

  procedure Draw(Show: boolean); virtual; { muss sich nur zeichnen knnen
} 

end;

Das Vererben in Pascal luft also mit ``Erbe = object(Vorgnger)''.

Werden im abgeleiteten (erbenden) Objekt Methoden definiert, die der
Vorgnger schon hatte, so wird beim Aufruf der Methode im abgeleiteten
Objekt nur der neue Code ausgefhrt. Um explizit die alte Version
aufzurufen (die natrlich ``virtual'' gewesen sein muss, um berhaupt
vererbt zu werden) gibt es in Pascal inherited (ererbt). Das kommt
zwar im Beispiel nicht vor, sollte man aber vielleicht trotzdem wissen.

5 Ende

Dieses Dokument wurde erstellt mit LyX. Im Tutorium gibt's einige Seiten
Philosophie dazu...

Here's a summary:

TeX: Typesetting language with macro capability.

LaTeX: Macro package built upon TeX\@.

LyX: Visual, WYSIWYM([footnote] what you see is what you mean)  word-processor
that uses LaTeX in all its glory to do its printing.

The idea of this section was to try and explain why LyX works somewhat
differently from other word processors. The reason is simple: LyX
uses LaTeX as its printing backend. Just like LaTeX, LyX focuses on
the context of your writing --- what you are typing. The computer
then handles how it should look.

Oh --- one last thing. LaTeX is pronounced like TeX is. It rhymes with
``hey blech.''([footnote] or ``ha blech'', depending on how you pronounce
your ``a''s\ldots{})  Usually. Lamport says in his book, though, that
``lay-tecks is also possible''. ``LyX,'' on the other hand, is pronounced
``licks.'' Or ``lucks,'' or ``looks,'' depending on what country you're
from\ldots{}
