In diesem Artikel möchte ich dir detailliert und leicht verständlich erklären, was man unter der objektorientierten Programmierung versteht.
Gerade als Programmier-Einsteiger, wenn man noch auf der Suche nach einer passenden Programmiersprache für sich ist, hört man den Begriff "Objektorientierte Programmierung" sehr häufig, kann damit aber nichts anfangen. Auch ich selbst hatte das Konzept der objektorientierten Programmierung in meinen Programmieranfängen nicht wirklich verstanden und musste mir das Wissen hierfür mühsam zusammensuchen.
Ich möchte dir das Verstehen und das Durchdringen des Konzepts jetzt allerdings wesentlich einfacher gestalten, und zwar musst du hierfür einfach nur diesen Artikel lesen.
Inhaltsverzeichnis
Was ist die objektorientierte Programmierung?
Die objektorientierte Programmierung (kurz: OOP) ist ein sogenanntes Programmierparadigma. Das Wort Paradigma kommt im täglichen Sprachgebrauch nicht allzu häufig vor, weshalb ich es dir kurz in eine einfachere Sprache übersetzen möchte. Programmierparadigma bedeutet übersetzt nichts anderes als Programmierstil. Es handelt sich bei der objektorientierten Programmierung also um eine Denkweise, die man als Programmierer an den Tag legt, wenn man mit einer objektorientierten Sprache wie beispielsweiße C# oder Java programmiert.
Weil die Objektorientierung dem menschlichen Denken sehr ähnelt, kann dieser Programmierstil von einem menschlichen Programmierer auch sehr intuitiv angewendet werden. Es ist also ein für Menschen einfach zu verstehen und anzuwendendes Konzept, da es an unser natürliches menschliches Denken angelehnt ist.
Konzept der objektorientierten Programmierung
Sehen wir uns dieses Konzept nun also mal im Detail an. Alles in der objektorientierten Programmierung wird durch sogenannte Objekte abgebildet. Jedes „Teil“ das also in einem Programm existiert, wird durch ein Objekt beschrieben.
Damit das Ganze nicht so abstrakt bleibt, veranschaulichen wir uns das Konzept direkt an einem Beispiel:
Angenommen du möchtest ein Spiel programmieren, in welchem es Unteranderem einen Hund geben soll, der in dieser Spielwelt herumläuft. Solltest du dieses Szenario nun mit einer objektorientierten Programmiersprache umsetzen wollen, so ist der Hund nichts anderes als ein Objekt.
Gehen wir nun wieder in die Realität und überlegen uns, wie der Mensch einen Hund in der Wirklichkeit wahrnimmt. Der Großteil würde jetzt sagen, dass der Mensch einen Hund als ein Tier bzw. ein Lebewesen wahrnimmt. Das ist natürlich vollkommen richtig, aber auf einer noch höheren Abstraktionsebene, ist ein Hund auch in der Wirklichkeit für den menschlichen Verstand nichts anderes als ein Objekt in der großen weiten Welt. Genauso sind auch Bäume, Autos, Tische und andere Menschen, nichts anderes als Objekte.
Objekte sind also kurz gesagt alle physisch vorstellbaren Dinge, die in unserem Raum existieren.
Und in der objektorientierten Programmierung ist es eben genauso. Alle vorstellbaren Dinge, die im Programm existieren, werden durch Objekte beschrieben. Soll in einem Spiel ein Hund abgebildet werden, so wird dieser durch ein eigenes Hund-Objekt verkörpert. Möchte man in einem Spiel einen Menschen darstellen, so wird dieser durch ein Mensch-Objekt verkörpert. Ein Haus wird durch ein Haus-Objekt verkörpert und so weiter. Ich denke, dass der grundsätzliche Ansatz der Objektorientierung dir nun klar geworden sein sollte.
Der Grundsatz der objektorientierten Programmierung lautet also:
Alles wird durch einzelne separate Objekte beschrieben.
Aufbau von Objekten
Da das allgemeine Konzept nun ausführlich erklärt wurde, können wir im Folgenden mehr ins Detail gehen und uns den Aufbau von Objekten ansehen.
Eigenschaften
Jedes Objekt besitzt sogenannte Eigenschaften (manchmal auch als Attribute bezeichnet). Diese Eigenschaften dienen dazu, das Objekt zu beschreiben.
Greifen wir hierfür noch mal das Beispiel mit dem Computerspiel von zuvor auf. Wir nehmen jetzt mal an, dass in der Spielwelt neben dem Hund von zuvor, auch noch mehrere Häuser stehen sollen. Jedes dieser Häuser wird dann logischerweise wieder durch ein extra Haus-Objekt dargestellt. Sind in der Spielwelt also 20 Häuser vorhanden, so gibt es 20 einzelne Haus-Objekte.
Jedes dieser Häuser hat nun eine Reihe von Eigenschaften, die das jeweilige Haus beschreiben. Nehmen wir mal an, dass ein Haus-Objekt folgende Eigenschaften besitzt:
Das Haus hat dann somit in unserer Spielwelt 8 Zimmer, 10 Fenster, ist blau angestrichen, wurde im Jahr 1990 gebaut und der Besitzer ist Max Mustermann. Diese Eigenschaften beziehen sich jetzt auf dieses eine ganz bestimmte Haus-Objekt.
Das zweite Haus in der Spielwelt wird nun durch ein weiteres Haus-Objekt beschrieben. Auch dieses hat wieder die gleichen Eigenschaften, aber diese sind nun mit eigenen Werten belegt, die das Haus 2 entsprechend beschreiben:
Das zweite Haus hat dann somit in der Spielwelt 6 Zimmer, 9 Fenster, ist grün angestrichen, wurde im Jahr 1945 gebaut und der Besitzer ist Peter Müller.
Und so könnte man jetzt die verbleibenden 18 Häuser unserer Spielwelt auch noch mithilfe von eigenen Objekten und entsprechenden Eigenschaften beschreiben. Du kannst im Übrigen beliebig viele Haus-Objekte erzeugen, solange du den dafür nötigen Speicher zur Verfügung hast.
Methoden (Funktionen)
Objekte besitzen jetzt aber nicht nur die eben vorgestellten Eigenschaften, sondern auch noch sogenannte Methoden (Funktionen). Mithilfe dieser Methoden können die Objekte gewisse Funktionalitäten ausführen, was sehr viel Sinn macht, denn ansonsten wären alle Objekte sehr langweilig, könnten nichts tun und würden lediglich existieren.
Methoden stellen den Objekten neben den Eigenschaften jetzt also auch noch Funktionalität zur Verfügung.
Ein Haus-Objekt könnte beispielsweiße die heizen()-Methode besitzen. Sobald diese Methode ausgeführt wird, könnte beispielsweiße die Heizung des Hauses angesteuert und aktiviert werden. Auch eine alarm()-Methode wäre vorstellbar, die bei potenziellen Einbrüchen die Alarmanlage des Hauses aktiviert. Du siehst also, Objekte können zahlreiche Methoden besitzen, welche sinnvolle Funktionalität implementieren.
Eine Methode enthält also Code, durch welchen eine Funktionalität realisiert wird.
Fassen wir den Aufbau von Objekten also noch mal abschließend zusammen. Ein Objekt ist ein physisches „Etwas“ innerhalb eines Programms, dass durch Eigenschaften beschrieben wird. Außerdem können Objekte auch Funktionalität besitzen, welche durch Methoden ausgedrückt werden.
Klassen
Da du die objektorientierte Programmierung nun vom Konzept und zudem auch den Aufbau von Objekten kennst, möchte ich nun auf die sogenannten Klassen zu sprechen kommen. Solltest du mit einer objektorientierten Sprache arbeiten, dann wirst du nämlich zwangsläufig auch immer mit Klassen konfrontiert werden. Doch was sind Klassen eigentlich?
Klassen sind Baupläne für Objekte.
Veranschaulichen wir uns dies anhand der Haus-Objekte aus dem vorherigen Beispiel. Jedes dieser Objekte hatte ja die gleiche Anzahl und Art von Eigenschaften, die aber alle mit unterschiedlichen Werten belegt wurden. Beispielsweiße gab es die Eigenschaft „Farbe“, die beim Haus-Objekt 1 mit dem Wert „blau“ und beim Haus-Objekt 2 mit dem Wert „grün“ belegt wurde.
Dass die Anzahl und Art der Eigenschaften bei jedem der Haus-Objekte gleich war, ist kein Zufall, denn alle Haus-Objekte haben den gleichen Bauplan zugrunde liegen. Und dieser Bauplan wird in der Programmierung als Klasse bezeichnet.
Die Klasse implementiert also die verschiedenen Eigenschaften, die später ein oder mehrere Objekte vom Typ der Klasse aufweisen sollen. Jedes Objekt, welches wir innerhalb unseres Codes dann auf Basis dieses Bauplans erschaffen, besitzt die in der Klasse vorgegebenen Eigenschaften. Welche konkreten Werte die Eigenschaften besitzen, ist dann aber objektabhängig.
Klassen geben mit den Eigenschaften und Methoden also den Grundaufbau eines Objekts vor und man definiert mit ihnen eigene Typen.
Fassen wir das Ganze also noch mal kurz zusammen:
Bevor man in einem Programm Objekte vom Typ Haus erzeugen kann, muss man zunächst mal die Klasse Haus definieren. Damit wird der Bauplan für die späteren Haus-Objekte vorgegeben. In dieser Klasse legt man also noch keine Werte fest, sondern nur die Eigenschaften und Methoden, die ein Haus-Objekt später besitzen soll. Erst wenn man dann konkret von dieser Klasse ein Objekt erzeugt, belegt man dessen Eigenschaften mit konkreten Werten.
Auch die Methoden werden auf die gleiche Art und Weise zunächst in der Klasse definiert. Alle Objekte, die wir dann von der Klasse erzeugen, besitzen automatisch diese Methoden und können diese auch aufrufen.
Zusatz: Klassen können wiederverwendet werden. Wenn wir in unserem aktuellen Programm beispielsweiße die Klasse Haus möglichst unabhängig von anderen Klassen entwickeln, dann könnten wir diese Klasse Haus auch in einem vollkommen anderen Projekt wiederverwenden. Man kann Code, den man einmal geschrieben hat, also immer wiederverwenden.
Vererbung
In der objektorientierten Programmierung gibt es noch ein weiteres sehr wichtiges und extrem nützliches Konzept, nämlich das Konzept der Vererbung. Schon mal vorweg: Dadurch wird die Programmierung von objektorientierten Programmen stark erleichtert.
Die objektorientierte Programmierung ermöglicht es nämlich, Klassen zu vererben. Bei der Vererbung übernimmt eine Klasse alle Eigenschaften und Methoden einer anderen Klasse. Dadurch kann man eine bereits bestehende Klasse erweitern, ohne diese Klasse nachträglich verändern zu müssen.
Sehen wir uns das Konzept mal anhand eines kleinen Beispiels an:
Wir definieren für unser Programm eine Klasse mit dem Namen Säugetier. Die Klasse besitzt zwei Eigenschaften, nämlich einmal den Namen des Säugetiers und einmal das Geschlecht des Säugetiers. Zudem besitzt jedes Säugetier auch zwei Methoden, nämlich essen() und trinken().
Mit dieser Klasse könnten wir jetzt bereits Objekte vom Typ Säugetier erzeugen. In vielen Fällen würde dies aber keinen Sinn machen, denn wenn wir ein Objekt erzeugen möchten, dann in der Regel ein spezifischeres, nämlich ein konkretes Säugetier wie beispielsweiße eine Katze oder einen Hund.
Aus diesem Grund definiert man jetzt sowohl für die Katze als auch für den Hund eine extra Klasse und lässt diese dann von der Klasse Säugetier erben.
Dadurch erreicht man, dass die Grundeigenschaften aller Säugetiere, bereits in der Klasse Säugetier definiert werden. Die spezifischere Klasse Hund erbt diese ganzen Grundeigenschaften dann von der Klasse Säugetier und erweitert diese um für den Hund spezifische Eigenschaften und Methoden.
Ein Hund kann beispielsweiße bellen, weshalb man diesem hierfür eine extra Methode bereitstellen sollte. Man muss also in der Klasse Hund lediglich noch die Methode bellen() definieren. Der Code für die Grundeigenschaften wird vererbt und muss somit nicht mehr in die Klasse Hund geschrieben werden.
Sollte man nur Objekte vom Typ Hund benötigen, so könnte man natürlich auch die Grundeigenschaften direkt in der Klasse Hund definieren und dann auf die Oberklasse Säugetier verzichten. Doch sobald man jetzt mehrere Säugetiere definiert, macht das Ganze Sinn. Denn wenn wir jetzt beispielsweiße auch noch eine Klasse Katze definieren, können wir auch diese von der Klasse Säugetier erben lassen, und müssen nur noch die für Katzen spezifischen Eigenschaften und Methoden definieren.
Wir haben also zwei Klassen definiert (Hund, Katze) und mussten den Code für die Grundeigenschaften nur EINMAL schreiben. Wenn man jetzt 20 verschiedene Säugetiere benötigt, dann spart man es sich somit, den gleichen Code 20-mal zu schreiben.
Die Vererbung ist also ein Konzept, um Klassen zu erweitern. Dadurch wird die Programmierung vereinfacht, da Code nicht wiederholt neu geschrieben werden muss und man gewisse Abstraktionsebenen einführen kann.