Objektorientierte Programmierung
Objektorientierte Programmierung (OOP) ist eine Methode für das
Strukturieren von Software, bei der "Klassen von Objekten" eine entscheidende Rolle spielen.
Dabei sind diese Objekte Softwarebestandteile, in denen Zustände (Daten) und Verhaltensweisen (Prozeduren, Methoden) zu einer Einheit zusammengefasst sind. Alternative Programmiermethoden sind die Funktionale Programmierung, die Prozedurale Programmierung, die Logikprogrammierung und die Regelorientierte Programmierung.
Welche Sprachen erlauben objekt-orientierte Programmierung?
Prinzipiell kann man durch strikte Einhaltung gewisser Regeln in jeder Programmiersprache objektorientiert programmieren, jedoch erleichtern und fördern objektorientierte Programmiersprachen dies ungemein. In der OOP wird ein Programm als Population miteinander kommunizierender und kooperierender Objekten formuliert. Das ist ein Unterschied zu herkömmlichen prozeduralen Programmiersprachen, bei denen Daten und Prozeduren typischerweise getrennt betrachtet werden. OOP soll Programmierung und Wartung von Programmen und Modulen erleichtern.
Häufig wird dieser Sachverhalt auch so ausgedrückt, dass die OOP den Programmierer dazu anhält, sich in seinem Programm an erster Stelle um die Daten zu kümmern, und in einem zweiten Schritt um die Operationen ("Methoden"), die er für diese spezifischen Daten braucht. Bei prozeduralen Sprachen denkt der Programmierer zuerst über die Prozeduren nach, und dann erst über die Daten, die von den Prozeduren bearbeitet werden. Prozedurale Programmierer schreiben Funktionen und übergeben ihnen dann Daten. Objektorientierte Programmierer definieren Objekte mit Daten ("Attributen") und Methoden und lassen dann Nachrichten an diese Objekte schicken, die dafür sorgen, dass die so angesprochenen Methoden ausgeführt werden.
Kennzeichen der objektorientierten Programmierung
Es gibt eine gewisse Uneinigkeit darüber, was alles genau diejenigen Kennzeichen einer Programmiermethode oder einer Programmiersprache sind, die sie schließlich als "objektorientiert" qualifizieren, aber gleichzeitig gibt es weitgehend Übereinstimmung darüber, dass die nachfolgend aufgezählten Eigenschaften besonders wichtig sind:
- Abstraktion: Jedes Objekt im System verkörpert das Modell eines abstrakten "Arbeiters", der Aufträge erledigen kann, seinen Zustand berichten und ändern kann und mit den anderen Objekten im System kommunizieren kann, ohne offen zu legen, wie diese Fähigkeiten implementiert sind.
- Kapselung: Auch das "Verbergen von Information" genannt, sorgt dafür, dass Objekte den internen Zustand anderer Objekte nicht in unerwarteter Weise ändern können; nur den eigenen Methoden eines Objektes soll es erlaubt sein, auf den internen Zustand direkt zuzugreifen. Alle Sorten von Objekten präsentieren nach außen Schnittstellen, die darüber bestimmen, wie andere Objekte mit ihnen wechselwirken können. Einige Programmiersprachen handhaben das nicht ganz so streng und erlauben einen gewissen kontrollierten Direktzugang zu den Interna von Objekten - was den Abstraktionsgrad einschränkt.
- Polymorphie: Zeiger zu Objekten können es mit sich bringen, dass bei der Auswahl eines konkreten Objektes seine Klasse nicht offensichtlich ist. Trotzdem werden Nachrichten an so selektierte Objekte korrekt der tatsächlichen Klasse zugeordnet. Wenn diese Zuordnung erst zur Laufzeit aufgelöst wird, dann wird dieses Verhalten Polymorphismus (auch: späte Bindung oder dynamische Bindung) genannt.
- Vererbung: Organisiert und erleichtert Polymorphie, indem neue Objekte definiert und erzeugt werden können, die Spezialisierungen schon existierender Objekte sind. Solche neuen Objekte können das vorhandene Verhalten übernehmen und erweitern, ohne dass dieses Urverhalten neu implementiert werden muss. Typischerweise wird das dadurch erreicht, dass Objekte zu Klassen und zu Hierarchien von Klassen gruppiert werden, in denen sich die Gemeinsamkeiten im Verhalten ausdrücken. Vererbung stellt einen Verstoß gegen das Kapselungsprinzip dar, da für eine korrekte Vererbung Detailwissen über die Implementierung der Oberklasse benötigt wird.
Geschichte der objektorientierten Programmierung
Denkweise und Begriffe der OOP zeigten sich zuerst in Simula 67, einer Sprache für Simulationszwecke, die von Ole-Johan Dahl und Kristen Nygaard am Norwegian Computing Centre in Oslo geschaffen wurde. (Erzählt wird, dass sie an Schiffssimulationen gearbeitet hatten. Dabei ergab sich durch die kombinatorische Explosion von Parameterbeziehungen eine verwirrende Vielfalt an Möglichkeiten, wie sich die verschiedensten Attribute der unterschiedlichen Schiffe gegenseitig beeinflussen konnten. So kam die Idee auf, die unterschiedlichen Schiffstypen als Objekte zu klassifizieren, wobei jede Klasse von Objekten für die eigenen Daten und das eigene Verhalten selbst zuständig war.) Diese Begriffe und Verfahren wurden später bei Xerox PARC mit der Sprache Smalltalk verfeinert. Entwickelt wurde diese erste Smalltalk-Version in Simula nun als voll dynamisches System, bei dem man Objekte interaktiv erzeugen und ändern konnte - im Gegensatz zum vorher verwendeten System statischer Programme.
OOP begann Mitte der 1980er Jahre populärer zu werden, hauptsächlich durch den Einfluss von C++, das sich dem Programmierer gegenüber gewissermaßen als syntaktische Erweiterung der Sprache C ausgibt. Weiter gefestigt wurde die Stellung der OOP durch die schnell wachsende Beliebtheit der grafischen Bedienoberflächen, die sich objektorientiert sehr gut programmieren lassen.
Seit dieser Zeit wurden für viele existierende Programmiersprachen objektorientierte Erweiterungen geschaffen, z.B. für Ada, BASIC, LISP, Pascal und andere. Das Hinzufügen dieser Erweiterungen zu Sprachen, die ursprünglich nicht für OOP entworfen wurden, kann zu Problemen mit der Kompatibilität und Wartbarkeit von Code führen. "Rein" objektorientierten Sprachen wiederum fehlen gewisse prozedurale Programmiermöglichkeiten, an die sich viele Programmierer inzwischen gewöhnt hatten. Um diese Lücke zu schließen, wurden verschiedene Versuche unternommen, neue objektorientierte Sprachen zu schaffen, die gleichzeitig "sichere" prozedurale Programmierung erlauben. Bertrand Meyers Eiffel war einer der ersten einigermaßen erfolgreichen Versuche in dieser Richtung, wurde inzwischen aber praktisch von Java verdrängt - hauptsächlich durch die Ausbreitung des Internets, für das Java speziell geeignet ist.
Umfeld
So wie die Techniken der prozeduralen Programmierung durch Verfahren wie die strukturierte Programmierung verfeinert wurden, so gibt es inzwischen auch Verfeinerungen der OOP durch Methoden wie Entwurfsmuster (en: design patterns), Design by Contract und grafische Modellierungssprachen wie UML.