Objektorientierte Programmierung
Objektorientierte Programmierung (OOP) bezeichnet die Anwendung der Objektorientierung auf die Strukturierung von Computerprogrammen, also die Programmierung. Hierbei werden zusammengehörige Daten und die darauf arbeitende Programmlogik zu Einheiten zusammengefasst, den sogenannten Objekten. Zumindest konzeptionell arbeitet ein Programm dann nicht mehr (wie bei der prozeduralen Programmierung) so, dass sequentiell einzelne Funktionsbereiche eines Algorithmus durchlaufen werden, der dabei eine Anzahl Daten verändert, sondern die Programmlogik entfaltet sich in der Kommunikation und den internen Zustandsveränderungen der Objekte, aus denen das Programm aufgebaut ist.
Vorteile der objektorientierten Programmierung liegen in der besseren Modularisierung des Codes, dadurch bedingt in einer höheren Wartbarkeit und Wiederverwendbarkeit der Einzelmodule, weiterhin in einer höheren Flexibilität des Programmes insgesamt, insbesondere in Bezug auf die Benutzerführung, da Programme dieser Art weniger stark gezwungen sind, dem Benutzer bestimmte Bedienabläufe aufzuzwingen.
Konzepte der objektorientierten Programmierung
Die folgenden Aspekte werden bei der objektorientierten Programmierung betont. Dabei handelt es sich um eine Zusammenstellung von Konzepten, die es für sich genommen auch schon vor der Erfindung der objektorientierten Programmierung gegeben hat:
- Klasse: Eine Klasse definiert, ähnlich eines Typs, die Datentypen der Attributen und der Funktionalität (Verhalten, Methoden) einer Programmeinheit. Klassen sind damit die zugrundeliegenden Definitionen gleicher Sorten von Objekten.
- Objekte: sind Instanzen von Klassen, sie haben einen Zustand, i.e. konkrete Werte für die einzelnen Attribute, Verhalten durch die in der Klasse definierten Methoden, und Identität, d.h. zwei Ausprägungen derselben Klasse sind unterschiedliche Objekte.
- Abstraktion: Jedes Objekt im System kann als ein abstraktes Modell eines Akteurs betrachtet werden, der Aufträge erledigen kann, seinen Zustand berichten und ändern kann und mit den anderen Objekten im System kommunizieren kann, ohne offen legen zu müssen, wie diese Fähigkeiten implementiert sind (vgl. abstrakter Datentyp (ADT)).
- Kapselung: Auch das "Verbergen von Information" genannt, sorgt dafür, dass Objekte den internen Zustand anderer Objekte nicht in unerwarteter Weise lesen oder ändern können; nur den eigenen Methoden eines Objektes soll es erlaubt sein, auf den internen Zustand direkt zuzugreifen. Alle Klassen präsentieren nach außen Schnittstellen, die darüber bestimmen, wie andere Objekte mit ihnen interagieren können. Dies verhindert das Umgehen von Invarianten des Programms.
- Polymorphie: Verschiedene Klassen können auf die gleiche Nachricht unterschiedlich reagieren. Dabei spricht man von Polymorphie.
Wird die Zuordnung von Nachricht zur Reaktion auf die Nachricht erst zur Laufzeit aufgelöst, dann wird dies auch späte Bindung oder dynamische Bindung genannt. - Vererbung: Ermöglicht die Definition neuer Klassen von Objekten auf Basis bereits vorhandener Klassen. Es können neue Attribute oder Methoden hinzugenommen werden oder vorhandene überlagert werden. Eine bestimmte Art der Polymorphie basiert ebenfalls auf Vererbung. Ohne Verwendung von Vererbung spricht man zur Unterscheidung oft auch von objektbasierter Programmierung.
Welche Sprachen erlauben objektorientierte Programmierung?
Grundsätzlich kann man durch strikte Einhaltung bestimmter Regeln in jeder Programmiersprache objektorientiert programmieren, jedoch erleichtern und fördern objektorientierte Programmiersprachen dies ungemein.
Manchmal 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 erzeugen (über Klassendefinitionen) 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.
Die erste bekannte objektorientierte Programmiersprache ist Simula67. Später wurden die Prinzipien dann in Smalltalk weiter ausgebaut, wo die Objektorientierung auch ihren Höhepunkt erfuhr. Ein prominenter Vertreter war Turbo Pascal (ab Version 5.5), die heute bekanntesten sind C++, Java und C#.
Die meisten Programmiersprachen erlauben es, verschiedene Programmiertechniken miteinander zu kombinieren. Manchmal werden dabei bestimmte Prinzipien der objektorientierten Programmierung durchbrochen. Beispielsweise handhaben viele Programmiersprachen das Prinzip der Kapselung nicht ganz so streng und erlauben einen gewissen kontrollierten Direktzugang zu den Interna von Objekten, unter anderem auch durch nicht zur Klasse gehörende Funktionen. Ein Beispiel dafür sind friend-Funktionen in C++. (Auch eine friend-Funktion verletzt jedoch nicht das Prinzip der Kapselung, da sich die Funktion den Zugang zu den Interna nicht selbst verschaffen kann.)
Bezeichnungen
Die Begriffe der objektorientierten Programmierung haben in den verschiedenen Programmiersprachen teilweise unterschiedliche Namen. Folgende Bezeichnungen werden synonym verwendet:
- Basisklasse = Superklasse = Oberklasse
- abgeleitete Klasse = Subklasse = Unterklasse
- Elementfunktion = Methode
- Datenelement = Attribut, Instanzvariable
Geschichte der objektorientierten Programmierung
Denkweise und Begriffe der OOP zeigten sich zuerst in Simula, einer Sprache für Simulationszwecke, die als erste Sprache (damals noch nicht so genannte) objektorientierte Verfahren einführte.
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. Die Programmiersprache 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. Einen ähnlichen Ansatz verfolgt die an Java und C++ angelehnte Sprache C#.
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 (englisch design patterns), Design by Contract und grafische Modellierungssprachen wie UML. Einen immer wichtigeren Stellenwert nimmt die funktionale bzw. aspektorientierte Programmierung ein, bei dem Aspekte von Eigenschaften und Abhängigkeiten beschrieben werden. Erste Ansätze sind beispielsweise in Java mit J2EE oder der abstrakten Datenhaltung über Persistenz-Layer sichtbar.
Andere Programmiertechniken
Andere Programmierparadigmen (die sich zum Teil mit OOP und untereinander nicht ausschließen) sind folgende:
- Aspektorientierte Programmierung
- Attributorientierte Programmierung
- Funktionale Programmierung
- Imperative Programmierung
- Modulare Programmierung
- Logische Programmierung
- Prozedurale Programmierung
- Strukturierte Programmierung
- Subjektorientierte Programmierung
Literatur
- Grady Booch: Object-Oriented Analysis and Design with Applications, Addison-Wesley, ISBN 0805353402
- Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides: Design Patterns: Elements of Reusable Object Oriented Software, Addison-Wesley, ISBN 0201633612
- Bertrand Meyer: Object-Oriented Software Construction, Prentice Hall, ISBN 0136291554
- James Rumbaugh, Michael Blaha, William Premerlani, Frederick Eddy, William Lorensen: Object-Oriented Modeling and Design, Prentice Hall, ISBN 0136298419
- Ivar Jacobsen: Object-Oriented Software Engineering: A Use-Case-Driven Approach, Addison-Wesley, ISBN 0201544350
- Harold Abelson, Gerald Jay Sussman, Julie Sussman: Structure and Interpretation of Computer Programs, The MIT Press, ISBN 0262011530
- Paul Harmon, William Morrissey: The Object Technology Casebook - Lessons from Award-Winning Business Applications, John Wiley & Sons, ISBN 0-471-14717-6
- David A. Taylor: Object-Oriented Information Systems - Planning and Implementation, John Wiley & Sons, ISBN 0-471-54364-0
- Peter Eeles, Oliver Sims: Building Business Objects, John Wiley & Sons, ISBN 0-471-19176-0
- Bernd Oestereich: Objektorientierte Programmierung mit der Unified Modeling Language, Oldenbourg, ISBN 3-486-24319-5