Dein Webbrowser blockiert JavaScript! Bitte aktiviere JavaScript, um sicher zu stellen, dass die Website richtig funktioniert!

OOP - Objektorientierte Programmierung

Das Konzept der objektorientierten Programmierung hat ihren Anfang in den 80er Jahren gehabt und bildet heute in vielen Programmiersprachen eine gezielte Grundlage komplexe Probleme zu lösen. Dieser Artikel beschäftigt sich mehr mit Theorien als mit exakten Programmierbeispielen. Es ist wichtig die theoretischen Ansätze wenigsten zu kennen und benennen zu können, um z.B. in Fachforen oder Fachbüchern entsprechende Codebeschreibungen, Design Pattern, … zu verstehen und ein Problem anderen Programmierern zu verdeutlichen.

Warum objektorientiertes Programmieren? Warum OOP?

Objektorientierte Programmierung ist ein alternatives Denkmuster zur strukturierten Programmierung. Beide zu vergleichen ist etwas schwierig, aber beide sind fundamentale Denkmuster, fachlich als Paradigma bezeichnet, und existieren gleichberechtigt nebeneinander. Um zu verstehen „Warum?“ OOP Vorteile bietet werden diese beiden Denkmuster kurz miteinander verglichen. Durch den Vergleich werden auch Nachteile ersichtlich. Grundsätzlich haben beide Paradigmen/ Denkmuster ihr eigenes Ziel.

Strukturierte Programmierung: Algorithmen sollen in ihrem Ablauf einfach zu erfassen und zu verändern sein. Der Code soll eine bestmögliche Struktur für Transparenz haben und somit testbar und wiederverwendbar bleiben bzw. dies zu maximieren!

Objektorientierte Programmierung: Jedes Objekt ist eine Instanz einer Klasse. Somit sind diese Objekte eine Menge von miteinander kommunizierenden Programmen. Die Kommunikation erfolgt über Nachrichten (Interfaces) zwischen den Programmen/ Objekten.

Kategorie Strukturierte Programmierung Objektorientierte Programmierung
Programmorganisation organisation hierarchisch hierarchisch ebenfalls möglich, aber nicht Sinn von OOP – hauptsächlich objektorientiert
Programmeinheiten logisch aufgeteilt in Unterprogramme logisch aufgeteilt in Klassen
Programmsteuerung zentral, vom Hauptprogramm aus und weiteres wird in Funktionen und Unterprogrammen zusammengefasst Objekte haben einen Zustand, Definition durch Attribute und Eigenschaften, Methoden der Objekte stellen die Programmlogiken da
Datenverfügbarkeit beschränkt
Objekte können allgemein überall ihre Eigenschafen und Attribute mithilfe einer Methode oder (ungünstig) durch den direkten Zugriff auf die Daten, diese im Programm überall weitergeben

Eine der großen Stärken von OOP ist, dass als Code die reale Welt “nachprogrammiert“ wird. Dabei werden jedoch nicht immer alle möglichen Eigenschaften, Attribute oder Methoden der realen Welt als Code aufgeschrieben. Dies wird durch Identifikation der abzubildenden Objekte unserer Umwelt ermöglicht. Durch die Objekte und ihre Attribute, Eigenschaften und Methoden wird die prozedurale (struktureitre Programmierung) überwunden, wodurch eine bessere realitätsnahe Modellierung möglich wird.

Grundbegriffe der Objektorientierten Programmierung (OOP)

Diese Grundbegriffe werden im Allgemeinen in jedem Online-Forum oder in der Fachlektüre für die Behandlung und Lösung konkreter Aufgaben, Probleme und Design Pattern als gegeben angesehen. Jeder OOP-Programmierer sollte diese kennen!

Abstraktion

Die Abstraktion hilft die benötigten Informationen einzugrenzen, um ein Problem zu lösen. Dabei werden durch die Abstraktion die Programmierer unterstützt sich nicht von Implementierungsdetails ablenken zu lassen. Durch das Abstrahieren eines Objektes werden die äußeren Eigenschaften herausgestellt.

Typisierung

Der Typ ist eine genaue Charakterisierung der gemeinsamen Eigenschaften einer Menge von Einheiten gesehen auf ihre Struktur und ihr Verhalten. Dabei wird die Typisierung erzwungen, um damit Objekte unterschiedlicher Typen den Austausch untereinander nicht ohne weiteres zu ermöglichen. Bei Objekten wird der Typ durch die Signatur und die Semantik der Methodenaufrufe bestimmt. Durch diese Einschränkung können Übergaben, die zu einen Fehler führen würden, zwischen unterschiedlichen Typen bereits zur Übersetzungszeit festgestellt werden.

Durch diese Überprüfungen und Bedingungen kann es eine Typhierarchie geben, die auch als eine Typvererbung (Subtyping) bezeichnet wird.

Objekt

Ein Objekt ist eine Zusammenfassung von Funktionalitäten und die dafür benötigten Daten. Vorstellen kann man sich dies wie eine Kapsel (fachlich Kapselung). Mithilfe mehrerer Kapselungen können mehrere reale Objekte aus unserer Umwelt in Form von Code abgebildet werden. Dieser entstandene Code kann für den Zweck der Datenverarbeitung eingesetzt werden. Dies wird durch die logische Gruppierung von Eigenschaften, Methoden und Attributen erreicht. Ebenfalls sollte auf die Daten eines Objektes nur durch Methoden zugegriffen werden können, sodass unerlaubte Änderungen ausgeschlossen werden.

Klasse

Eine Klasse stellt den Bauplan (englisch Blueprint) für ein Objekt zur Verfügung. Dieser Bauplan wird mithilfe der Abstraktion durch die Programmierer erstellt. Die vorher erfolgte Gruppierung logisch zusammenhängender Informationen zu einem Objekt werden als Code in einer Klasse abgebildet. Dieser Code wird zur Programmlaufzeit als Objekt erzeugt. Also wird aus dem Bauplan ein “reales“ Objekt. Eine Klasse legt durch ihren Code fest, wie sich ein Objekt zur Laufzeit verhalten soll. Dies kann auch als Softwarekonstruktion eines Objektes bezeichnet werden.

Hinweis: Ebenfalls kann der Begriff „Objekttyp“ auch als völlig gleichwertiger Begriff und Bedeutung für den Begriff „Klasse“ verwendet werden.

Instanz

Eine Instanz bezeichnet ein erzeugtes Objekt. Da eine Klasse nur den Bauplan bzw. Definition für ein Objekt liefert können endlich viele gleiche Objekte in einer Laufzeitumgebung erzeugt werden. Die Begrenzung für die Anzahl beliebig vieler erzeugter Objekte, also beliebig vieler Instanzen, gibt im Grunde die physische Hardware-Speicher-Begrenzung vor. Die Fließbandproduktion eines Rasierers könnte so interpretiert werden, dass jeder der zusammenbauenden Rasierer auf dem Fließband nach ein und demselben Bauplan (Klasse) gebaut (erzeugt) wird.

Kapselung

Eine Klasse ist die Realisierung eines Objektes als eine “Kapsel“. Eine Kapselung ist also das innere einer Klasse, also der geschriebene Code und bildet das Gegenstück zur Abstraktion, da das Innere verborgen ist. Dabei wird durch die Kapselung das innere sauber durch Schnittstellen (Interfaces) vom Äußerem (Sicht von außen) getrennt. Der Zugriff auf das innere erfolgt über öffentliche Eigenschaften, Methoden und Attribute. Somit kann das innere der Kapsel nur über definierte Schnittstellen ausgegeben oder verändert werden. Die innere Struktur bleibt von außen verborgen und ist dadurch wie in einer Kapsel geschützt und kann von außen nicht verändert werden.

Wiederverwendbarkeit (Modularisierung)

Es wird einige Programmierer geben die prozeduralen Ansätze den Klassenansätzen vorziehen würden. Die Wiederverwendbarkeit von geschriebenen Klassen ist meist bei komplexen Anwendungen leichter als die Wiederverwendung einer Prozedur als Unterprogramm. Da die Klasse in sich gekapselt ist. Sie kann wie eine Blackbox betrachtet werden. Dabei spielt für die Programmierer nur das was hinein geht und was am Ende wieder rauskommt eine Rolle. Somit ist es möglich die gleiche Klasse an unterschiedlichen Stellen innerhalb einer Anwendung wiederzuverwenden, als auch in jeder weiteren neuen Anwendung die Klasse in das Projekt zu importieren, um diese zu verwenden oder auch nur leicht anpassen zu müssen. Dadurch wird Redundanz innerhalb einer Anwendung vermieden und die Wartbarkeit deutlich erhöht.

Die Modularisierung hilft große komplexe Probleme in kleinere Teilprobleme zu zerlegen. Diese sind überschaubarer und leichter zu lösen. Dabei werden logisch zusammengehörende Abstraktionen gebündelt und als ein Modul zusammengefasst. Dadurch ergeben sich Abhängigkeiten zwischen unterschiedlichen Programmteilen.

Vererbung

Eine echte Vererbung ermöglicht es Klassen zu definieren, die von einer oder mehrerer anderer Klassen abhängig sind. Dies wird auch als Implementierungsvererbung bezeichnet. Dabei werden die Schnittstellen, Eigenschaften, … und der dahinterliegende Code vom Nachkommen übernommen. Durch dieses Prinzip wird es möglich Unterklassen zu bilden die allen Code von ihrer Oberklasse/ Superklasse vollständig erben können. Da die Unterklasse ein Nachkommen der Superklasse ist, kann diese auch neue Eigenschaften, Methoden, … hinzufügen als auch geerbte Eigenschaften, Methoden verstecken, indem diese überschrieben (overwrite) werden. Alle vererbten Klassen und die Unterklasse bilden bei der Erzeugung eines Objektes eine gemeinsame Bauplan-Kollektion/ Bauplanbuch.

Dabei wird die Vererbung auch als kind-of oder is-a Teil bezeichnet. Dies ist eine Hierarchieform als „Art-von“ einer anderen Klasse.

Polymorphie

Durch OOP wird die Vielgestaltigkeit (Polymorphie), also verschiedene Formen anzunehmen, für eine Methode für unendlich viele unterschiedliche Objekte möglich. Damit ist gemeint, dass es mehr als einen Typ für Variablen und ihre Werte, unterschiedliche Operanden eines Operators und verschiedene Parameter für Funktionen geben kann. Jedes dieser möglichen unterschiedlichen Objekte kann die Ausführung anders interpretieren und somit unterschiedlich ausführen. Dabei bleibt es jedoch für das aufgerufene Objekt ein und dasselbe.

Die Polymorphie kann dies nur da sie sehr eng mit der Vererbung verknüpft ist. Daraus ergibt sich die Fähigkeit von Unterklassen Eigenschaften und Methoden mit dem gleichen Namen, jedoch mit unterschiedlichen Implementierungen, zu definieren und dann auch später aufzurufen. Dies wird auch als Overloading bezeichnet. Also die Möglichkeit z.B. eine Funktion gleichen Namens mehrfach zu definieren, aber mit unterschiedlichen Parametern und Operantentypen. Dies gibt es auch für Subklassen, die eine Vererbung der übergeordneten Klasse besitzen. Ebenfalls gibt es die Cast-Operatoren, die dafür sorgen, wie in bestimmten Fällen ein unpassender Typ in einen passenden Typ automatisch konvertiert/ umgewandelt werden kann.

Generizität

Dieser Begriff beschreibt ein Konzept für eine höhere Flexibilität für die Typisierung. Dabei werden die Begriffe von Klasse und Typ jedoch vermischt.

Nebenläufigkeit

Dies beschreibt das mehrere aktive Träger durch mehrere Prozessoren parallel ausgeführt werden.

Sichtbarkeit einer Klasse

Für das Verbergen und nicht verbergen von Bestandteilen einer Klasse müssen die Attribute, Methoden, … über ein Sichtbarkeits-“Merkmal“ verfügen. Diese werden als Modifier bezeichnet. Diese geben eine Beschreibung über die Sichtbarkeit wieder. Dabei können im Allgemeinen die folgenden fünf Modifier verwendet werden: public, protected, private, internal und internal protected. Wie diese verwendet werden, macht sich ggf. besser mit exakten Codebeispielen. Deswegen werden diese in diesem Blogbeitrag nicht weiter erläutert.