Objektorientierte Programmierung

In diesem Kapitel wird die OOP allgemein erläutert. Für programmiersprachenspezifische Erklärungen siehe:

Klassen

sind so etwas ähnliches wie Rezepte oder Bauanleitungen. Mit Ihnen wird festgelegt, wie ein Objekt herzustellen ist. Dazu müssen zwei verschiedene Dinge definiert werden:

  1. Attribute - Das sind die Eigenschaften, die ein Objekt später haben soll. Beispiele:
    • Klasse Dreieck: Koordinaten der Eckpunkte
    • Klasse Auto: Motorleistung, Anzahl der Türen, Farbe, Baujahr, …
  2. Methoden - Das sind Tätigkeiten, die ein Objekt ausführen können soll. Beispiele:
    • Klasse Dreieck: verschiebeDichNach, berechneDeinenFlaecheninhalt
    • Klasse Auto: fahreLos, bremse, deaktiviereAlarmanlage

Objekte

sind, nun ja, Objekte halt. Sie werden mit Hilfe der Klasse erstellt. Wird eine Klasse Dreieck definiert, so kann man an Hand dieser Klasse beliebig viele Objekte konstruieren. So ähnlich, wie man an Hand eines Backrezeptes beliebig viele Kuchen erstellen kann. Hat die Klasse einen Namen, so braucht man nur noch einen Namen für das Objekt, das man erstellen möchte. Eine Klasse dreieck sei nun gegeben.

  1. Ein neues Objekt namens d1 soll erstellt werden. Dafür wird zunächst diesem Namen die Klasse (als eine Art Datentyp) dreieck zugewiesen. Genauer ist dieser Name nun ein Verweis auf einen Speicherbereich, an dem ein Objekt dieser Klasse gespeichert wird.
  2. Nun wird das Objekt erstellt, indem der Konstruktor der Klasse (evtl. mit Parametern) aufgerufen wird. Das bedeutet, der Speicherplatz für das Objekt wird reserviert und die Methoden zur Verfügung gestellt.
  3. Danach wird dafür gesorgt, dass der angelegte Verweis auf das neue Objekt zeigt.

Dann kann mit Hilfe des Verweises das neue Objekt verwendet werden.

Fehlvorstellung!

Der Ausdruck „ein Schüler der Klasse 8f“ hat rein gar nichts mit dem Ausdruck „ein Objekt der Klasse x“ zu tun! Der Schüler ist Mitglied der Klasse, während ein Objekt nach der Bauanleitung der Klasse konstruiert wird. Ein Objekt ist also kein Mitglied in seiner Klasse!

Wichtiges Zeug für die objektorientierte Programmierung

Kapselung

Um zu verhindern, dass Benutzer von Klassen direkt auf die Daten eines Objektes zugreifen können, werden die Daten in der Klasse gekapselt. Das bedeutet, dass auf die einzelnen Attribute nur über die vom Programmierer vorgesehenen Methoden zugegriffen werden kann. Die Verwaltung der Daten durch eine Klasse kann so nachträglich geändert werden, indem die Methoden entsprechend angepasst werden. Um die Werte der Attribute der Objekte zu ändern müssen daher (meistens) 2 Methoden definiert werden: Die getter- und die setter-Methode. In diesen Methoden können natürlich auch weiter Attribute geändert und weitere Methoden aufgerufen werden.

In manchen Programmiersprachen ist es möglich die getter- und setter-Methoden so zu erstellen, dass ihr Aufruf durch eine scheinbare bloße Zuweisung eines Wertes erfolgt. Bsp.: telefon1.nummer = „0815/4711“ Hier wird scheinbar dem Attribut nummer des Objektes telefon1 lediglich ein neuer Wert zugewiesen. Tatsächlich aber wird die zugehörige setter-Methode aufgerufen und evtl. mehr Code ausgeführt, als lediglich die Neuzuweisung. (Geht in VB, Python; Geht nicht in Java)

Geheimnisprinzip

Die Innereien von Methoden, Klassen, Attributen, Datenstrukturen sollen geheimgehalten werden. Warum, weiß ich nicht mehr.

Konstruktor

Jede Klasse hat einen Konstruktor. Er ist eine Methode, die im Speicher Platz für ein Objekt reserviert und den Verweis auf diesen Speicherplatz zurückgibt. Der Konstruktor wird daher für jedes Objekt genau einmal aufgerufen. Je nach Struktur des Konstruktors, können Parameter übergeben, die sofort in den entsprechenden Attributen gespeichert werden.

Je nach Programmiersprache muss der Konstruktor nicht explizit angegeben werden. Der Compiler erstellt die Methode automatisch. Der Konstruktor ist dann leer, bis auf die Erstellung des Objekts. Dieser Konstruktor steht nicht im Sourcecode, sondern ist nur im compilierten Programm enthalten

Destruktor

In manchen Programmiersprachen muss ein Objekt, nach dem es nicht mehr gebraucht wird, zerstört werden, damit der Speicherplatz wieder freigegeben werden kann. Die Methode dafür nennt man Destruktor.

Überladen

Benötigt man beim Aufruf einer Methode verschiedene Möglichkeiten der Parameterübergabe, so kann man die Methode überladen. (Nicht in Python!?1)) Die einfachste Möglichkeit wäre, die Methode mehrfach zu notieren. Der Hauptunterschied besteht dann in den anzugebenden Parametern, an Hand derer der Compiler auch erkennen kann, welche Mehotde genutzt werden soll, da der Name ja gleich ist. Beispiel Konstruktor: Konstruktion von Objekten einmal ohne die Angabe von Parametern und einmal mit der Angabe von Werten. Der Name des Konstruktors ist beides Mal der gleiche. Lediglich die Parameterübergabe unterscheidet sich.

Vererbung

Angenommen ein Programm für einen Gebrauchtwagenhändler soll erstellt werden. Da sehr unterschiedliche Fahrzeugtypen verwaltet werden sollen, soll auch für jeden Typ eine eigene Klasse erstellt werden. Unmittelbar klar ist jedoch auch, dass die Fahrzeuge einige Gemeinsamkeiten haben. (Fahrgestellnr, Vorbesitzer, Preis, TÜV, ASU, Steuerklasse, …) Damit diese Gemeinsamkeiten nicht für jede Fahrzeugtypklasse neu erstellt werden müssen, kann zunächst eine (Ober-)Klasse fahrzeug erstellt werden, die genau diese Gemeinsamkeiten schon beinhaltet. Beim Erstellen einer neuen (Unter-)Klasse transporter wird angegeben, dass sie die (Ober-)Klasse fahrzeug beerbt. Nun werden sämtliche Attribute und Methoden dieser Klasse vererbt und müssen nicht nochmal implementiert werden. Neue Attribute und neue Methoden können in gewohnter Weise zugefügt werden.

Überschreiben

Wird eine Methode geerbt aber in anderer Weise benötigt, so kann sie überschrieben werden. Überschreiben heißt im Prinzip neu schreiben oder ersetzen. Die Bezeichnung überschreiben ist nur insofern gehaltvoller, als dass wichtig ist, dass der Name der Methode erhalten bleibt.

Polymorphie

Verschiedene Unterklassen derselben Oberklasse haben durch die analoge Vererbung diverse Methoden gleichen Namens erhalten. Dies wird mit Polymorphie bezeichnet. Der Vorteil liegt darin, dass verschiedene Objekte gleich behandelt werden können. Auch wenn die Implementierung der jeweiligen Methoden unterschiedlich ist, bleibt der Name gleich. Wird beispielweise eine Methode verkaufen implementiert, so kann darauf geachtet werden, dass für Verkauf eines LKWs ein LKW-Führerschein verlangt wird, während beim Motorrad der entsprechende Motorradführerschein notwendig ist. Trotzdem wird in beiden Fällen die Methode den Namen verkaufen behalten.

Modifier für Methoden und Attribute

public, static, private, friendly, abstract, final, native, synchronized, strictfp

Vielzukurzunddaherfalscherläuterungen:

  • public - Methoden/Attribut in allen anderen Klassen verwendbar
  • static - Ein Attribut/Eine Methode für alle Objekte einer Klasse. Wird deren Wert geändert, so ist er für alle Objekte geändert. Die Methoden können Instanziierung genutzt werden. (Math.cos() z.B.) static-Methoden dürfen nur auf static-Datenelemente zugreifen und dürfen nicht überschrieben werden.
  • private - Methode/Attribute ist nur innerhalb der jeweiligen Klasse verwendbar.
  • friendly - Methode/Attribut ist überall innerhalb des Paketes verwendbar.
  • abstract - Methode wird nicht implementiert. Sie muss in einer Unterklasse implementiert werden. Darf nur in einer abstrakten Klasse stehen.
  • final - Methoden können nicht überschrieben werden. Attribute sind Konstanten. (Nur Großbuchstaben bitte.)

Und dann gibt's noch:

  • native - (Nur Java!?) Bindet Code anderer Programmiersprachen ein.
  • synchronized - braucht man bei threads. Es kann nur einen geben…
  • volatile - bei unsynchronisierten threads passt der Compiler besser auf diese Datenelemente auf, die von anderen threads verändert werden können.
  • strictfp - (Nur Java!?) Methoden mit erweiterter Gleitpunktdarstellung.
1)
Ja, korrekt. In Python gibt es das Überladen von Methoden nicht, d.h. man muss dann zwei Methoden mit unterschiedlichem Namen definieren. Beim Konstruktor geht das natürlich nicht. Eventuell könnte man sich mit dem Datentyp NoneType behelfen, da Datentypen in Python ja zur Laufzeit verändert werden können und somit der Konstruktor entweder mit wirklichen oder mit „leeren“ Parametern aufgerufen wird.
Cookies helfen bei der Bereitstellung von Inhalten. Durch die Nutzung dieser Seiten erklären Sie sich damit einverstanden, dass Cookies auf Ihrem Rechner gespeichert werden. Weitere Information
Falls nicht anders bezeichnet, ist der Inhalt dieses Wikis unter der folgenden Lizenz veröffentlicht: CC Attribution-Noncommercial-Share Alike 4.0 International