Algorithmen und Datenstrukturen Werner Struckmann Wintersemester 2005/06 5. Objektorientierte Algorithmen 5.1 Objekte und Klassen 5.2 Vererbung 5.3 Abstrakte Klassen 5.4 Objektorientierte Softwareentwicklung Einführung Das objektorientierte Paradigma der Algorithmenentwicklung hat verschiedene Wurzeln: ◮ Realisierung abstrakter Datentypen ◮ rechnergeeignete Modellierung der realen Welt (objektorientierte Analyse) ◮ problemnaher Entwurf von Sofwaresystemen (objektorientiertes Design) ◮ problemnahe Implementierung (objektorientierte Programmierung) 5.1 Objekte und Klassen 5-1 Grundlagen der Objektorientierung Klassen Begriffswelt des Modellierenden Person Patient Mitarbeiter Arzt Chefarzt Krankenhaus Mitarbeiter Patienten Schwestern Verwaltung Ärzte Prof. Dr. Sauerbruch Dr. Quincy Fr. Müller Objekte/Instanzen 5.1 Objekte und Klassen Realität 5-2 Objekte Ein Objekt ist die Repräsentation eines Gegenstands oder Sachverhalts der realen Welt oder eines rein gedanklichen Konzepts. Es ist gekennzeichnet durch ◮ eine eindeutige Identität, durch die es sich von anderen Objekten unterscheidet, ◮ statische Eigenschaften zur Darstellung des Zustands des Objekts in Form von Attributen, ◮ dynamische Eigenschaften in Form von Methoden, die das Verhalten des Objekts beschreiben. 5.1 Objekte und Klassen 5-3 Beispiele für Objekte ◮ Eine Person mit Namen „Müller“ und Geburtsdatum „12.12.1953“ (Attribute mit Belegungen) und Methode „alter(): int“. ◮ Eine rationale Zahl mit Zähler und Nenner (Attribute) und Methoden „normalisiere()“ und „addiere(r: RationaleZahl)“ Es findet in der Regel eine Abstraktion statt. Gewisse Aspekte (zum Beispiel das „Gewicht“ einer Person) werden nicht berücksichtigt. Der Zustand eines Objekts zu einem Zeitpunkt entspricht der Belegung der Attribute des Objekts zu diesem Zeitpunkt. Der Zustand eines Objekts kann mithilfe von Methoden erfragt und geändert werden. 5.1 Objekte und Klassen 5-4 Methoden ◮ Methoden sind in der programmiersprachlichen Umsetzung Prozeduren oder Funktionen, denen Parameter übergeben werden können. ◮ Der Zustand eines eine Methode ausführenden Objekts (und nur der dieses Objekts) ist der Methode im Sinne einer Menge globaler Variablen direkt zugänglich. Er kann daher sowohl gelesen als auch verändert werden. 5.1 Objekte und Klassen 5-5 Objektmodelle ◮ Wertbasierte Objektmodelle: In diesem Modell besitzen Objekte keine eigene Identität im eigentlichen Sinn. Zwei Objekte werden schon als identisch angesehen, wenn ihr Zustand gleich ist. Für zwei Objekte zur Datumsangabe d1 = „6.12.1986“ und d2 = „6.12.1986“ gilt in diesem Modell d1 = d2 . ◮ Identitätsbasierte Objektmodelle: Jedem Objekt innerhalb des Systems wird eine vom Wert unabhängige Identität zugeordnet. Zwei Objekte für Personen p1 = „Müller, 12.12.1953“ und p2 = „Müller, 12.12.1953“ sind in diesem Modell nicht identisch: p1 , p2 . 5.1 Objekte und Klassen 5-6 Kapselung und Geheimnisprinzip Objekte verwenden das Geheimnisprinzip und das Prinzip der Kapselung. Sie verbergen ihre Interna ◮ Zustand (Belegung der Attribute), ◮ Implementierung ihres Zustands, ◮ Implementierung ihres Verhaltens. Objekte sind nur über ihre Schnittstelle, also über die Menge der vom Objekt der Außenwelt zur Verfügung gestellten Methoden, zugänglich. Man spricht von den Diensten des Objekts. 5.1 Objekte und Klassen 5-7 Nachrichten Objekte interagieren über Nachrichten: ◮ Ein Objekt x sendet eine Nachricht n an Objekt y . ◮ y empfängt die Nachricht n von x . ◮ Innerhalb einer Programmiersprache wird dieser Vorgang meist durch einen Methodenaufruf implementiert. ◮ Nachrichten (Methodenaufrufe) können den Zustand eines Objektes verändern. ◮ Ein Objekt kann sich selbst Nachrichten schicken. 5.1 Objekte und Klassen 5-8 Beziehungen zwischen Objekten Objekte können in Beziehungen zueinander stehen. ◮ Die Beteiligten an einer Beziehung nehmen Rollen ein. Rolle des Arztes: „behandelnder Arzt“, Rolle des Patienten: „Patient“. ◮ Ein Objekt kann mit mehreren Objekten in der gleichen Beziehung stehen. Rolle von Arzt: „behandelnder Arzt“, Rolle von Patient 1: „Patient“, Rolle von Patient 2: „Patient“. ◮ Nachrichten können nur ausgetauscht werden, wenn eine Beziehung besteht. ◮ Beziehungen können sich während der Lebenszeit eines Objekts verändern. 5.1 Objekte und Klassen 5-9 Klassen ◮ Objekte besitzen eine Identität, verfügen über Attribute und Methoden, gehen Beziehungen zu anderen Objekten ein und interagieren über Nachrichten. ◮ Es gibt in der Regel Objekte, die sich bezüglich Attribute, Methoden und Beziehungen ähnlich sind. Daher bietet es sich an, diese Objekte zu einer Klasse zusammenzufassen. 5.1 Objekte und Klassen 5-10 Klassen Patient name: String geburtsdatum: Date diagnose: String p1: Patient name: Müller“ ” geburtsdatum: 03.01.1987 diagnose: Grippe“ ” 5.1 Objekte und Klassen p2: Patient name: Meier“ ” geburtsdatum: 06.12.1986 diagnose: Husten“ ” p3: Patient name: Schulz“ ” geburtsdatum: 22.09.1993 diagnose: Kleinwuchs“ ” 5-11 Klassen Eine Klasse ist die Beschreibung von Objekten, die über eine gleichartige Menge von Attributen und Methoden verfügen. Sie beinhaltet auch Angaben darüber, wie Objekte dieser Klasse verwaltet (zum Beispiel erzeugt oder gelöscht) werden können. ◮ Klassendefinitionen sind eng verwandt mit abstrakten Datentypen. Sie legen Attribute und Methoden der zugehörigen Objekte fest. ◮ Objekte einer Klasse nennt man auch Instanzen dieser Klasse. ◮ Beziehungen (Assoziationen) zwischen den Objekten werden auf Klassenebene beschrieben. Ein Konstruktor ist eine Methode zum Erzeugen von Objekten. 5.1 Objekte und Klassen 5-12 Klassenvariable und -methoden ◮ Es gibt Attribute von Klassen, die nicht an konkrete Instanzen gebunden sind. Diese heißen Klassenvariable oder statische Variable. In dieser Sprechweise werden instanzgebundene Attribute auch als Instanzvariable bezeichnet. ◮ Klassenvariable existieren für die gesamte Lebensdauer einer Klasse genau einmal – unabhängig davon, wie viele Objekte erzeugt wurden. ◮ Neben Klassenvariablen gibt es auch Klassenmethoden, d. h. Methoden, deren Existenz nicht an konkrete Objekte gebunden ist. Klassenmethoden werden auch statische Methoden genannt. 5.1 Objekte und Klassen 5-13 Vererbung ◮ Häufig gibt es Klassen, die sich in Attributen, Methoden und Beziehungen ähnlich sind. Beispiel: Zahl, natürliche Zahl, ganze Zahl, rationale Zahl. 5.2 Vererbung ◮ Man versucht, zu ähnlichen Klassen eine gemeinsame Oberklasse zu finden, die die Ähnlichkeiten subsumiert und ergänzt die Unterklassen nur um die individuellen Eigenschaften. ◮ Eine Unterklasse erbt die Attribute und Methoden der Oberklasse. 5-14 Vererbung Person name: String geburtsdatum: Date Patient name: String geburtsdatum: Date patientenNr: Integer diagnose: String 5.2 Vererbung Arzt Gemeinsamkeiten name: String geburtsdatum: Date mitarbeiterNr: Integer fachrichtung: String 5-15 Vererbung ◮ ◮ ◮ 5.2 Vererbung B erbt alle Attribute und Methoden von A und fügt in der Regel weitere hinzu. AO A ist die Basisklasse (Oberklasse) und B die abgeleitete Klasse (Unterklasse). B B ist eine Spezialisierung von A und A eine Generalisierung von B. 5-16 Vererbung und Polymorphismus ◮ „Jede Instanz b ∈ B ist auch ein a ∈ A.“ ◮ Einfachvererbung: Jede abgeleitete Klasse besitzt genau eine Vaterklasse. ◮ In Java: class B extends A { ... } AO B Eine Variable vom Typ einer Basisklasse kann während ihrer Lebensdauer sowohl Objekte ihres eigenen Typs als auch solche von abgeleiteten Klassen aufnehmen. Dies wird als Polymorphismus bezeichnet. 5.2 Vererbung 5-17 Vererbung 5.2 Vererbung ◮ Eine Unterklasse erbt von ihrer Oberklasse alle Attribute und Methoden und kann diese um weitere Attribute und Methoden ergänzen. ◮ „Erben“ heißt: Die Attribute und Methoden der Oberklasse können in der Unterklasse verwendet werden, als wären sie in der Klasse selbst definiert. 5-18 Vererbung ◮ Vererbungen können mehrstufig sein. ◮ Jede abgeleitete Klasse erbt die Attribute und Methoden der jeweiligen Oberklasse. ◮ Es entstehen Vererbungshierarchien. AO BO C 5.2 Vererbung 5-19 Vererbung ◮ Vererbungshierarchien können sehr komplex sein. ◮ Sie lassen sich durch azyklische gerichtete Graphen darstellen. A F O X22 B 22 22 22 22 22 2 C D F O X22 E 5.2 Vererbung 22 22 22 22 22 2 F G 5-20 Verdecken von Variablen 5.2 Vererbung ◮ Eine Unterklasse kann eine Variable deklarieren, die denselben Namen trägt, wie eine der Oberklasse. ◮ Hierdurch wird die weiter oben liegende Variable verdeckt. ◮ Dies wird häufig dazu benutzt, um den Typ einer Variablen der Oberklasse zu überschreiben. ◮ In manchen Programmiersprachen gibt es Konstrukte, die den Zugriff auf verdeckte Variable ermöglichen (in Java: Verwendung des Präfixes „super“). 5-21 Überlagern von Methoden 5.2 Vererbung ◮ Methoden, die aus der Basisklasse geerbt werden, dürfen in der abgeleiteten Klasse überlagert, d. h. neu definiert, werden. ◮ Da eine Variable einer Basisklasse Werte von verschiedenen Typen annehmen kann, entscheidet sich bei überlagerten Methoden im Allgemeinen erst zur Laufzeit, welche Methode zu verwenden ist: Dynamische Methodensuche. ◮ Wird eine Methode in einer abgeleiteten Klasse überlagert, wird die ursprüngliche Methode verdeckt. Aufrufe der Methode beziehen sich auf die überlagernde Variante. ◮ In manchen Programmiersprachen gibt es Konstrukte, die den Zugriff auf überlagerte Methoden ermöglichen (in Java: Verwendung des Präfixes „super“). 5-22 Modifikatoren Mithilfe von Modifikatoren können Sichtbarkeit und Eigenschaften von Klassen, Variablen und Methoden beeinflusst werden. ◮ Die Sichtbarkeit bestimmt, ob eine Klasse, Variable oder Methode in anderen Klassen genutzt werden kann. ◮ Eigenschaften, die über Modifikatoren gesteuert werden können, sind z. B. die Lebensdauer und die Veränderbarkeit. Beispiele für Modifikatoren in Java sind: public, protected, private, static, final, . . . 5.2 Vererbung 5-23 Mehrfachvererbung AX11 B 11 11 11 11 11 1 F C 5.2 Vererbung ◮ Eine Klasse kann im Allgemeinen mehrere Oberklassen besitzen. In diesem Fall spricht man von Mehrfachvererbung (multiple inheritance) im Gegensatz zur Einfachvererbung (single inheritance). ◮ Problematisch ist die Behandlung von Konflikten, wenn gleichnamige Attribute oder Methoden in verschiedenen Oberklassen definiert werden. ◮ Mehrfachvererbung ist in Java nur für Schnittstellen erlaubt. 5-24 Abstrakte Methoden ◮ Eine Methode heißt abstrakt, wenn ihre Deklaration nur die Schnittstelle, nicht aber die Implementierung enthält. Im Gegensatz dazu stehen konkrete Methoden, deren Deklarationen auch Implementierungen besitzen. ◮ Java: Die Deklaration einer abstrakten Methode erfolgt durch den Modifikator abstract. Anstelle des Rumpfes steht lediglich ein Semikolon. ◮ Abstrakte Methoden können nicht aufgerufen werden, sie definieren nur eine Schnittstelle. Erst durch Überlagerung in einer abgeleiteten Klasse und durch Angabe der fehlenden Implementierung wird eine abstrakte Methode konkret. 5.3 Abstrakte Klassen 5-25 Abstrakte Klassen ◮ Eine Klasse, die nicht instanziiert werden kann, heißt abstrakte Klasse. Klassen, von denen Objekte erzeugt werden können, sind konkrete Klassen. ◮ Jede Klasse, die mindestens eine abstrakte Methode besitzt, ist abstrakt. ◮ Java: Eine Klasse ist abstrakt, wenn sie mindestens eine abstrakte Methode enthält. Die Deklaration einer abstrakten Klasse erfolgt ebenfalls durch den Modifikator abstract. ◮ Java: Es ist erforderlich, abstrakte Klassen abzuleiten und in der abgeleiteten Klasse eine oder mehrere abstrakte Methoden zu implementieren. Die Konkretisierung kann über mehrere Stufen erfolgen. 5.3 Abstrakte Klassen 5-26 Schnittstellen ◮ Java: Eine Schnittstelle (Interface) ist eine Klasse, die ausschließlich Konstanten und abstrakte Methoden enthält. ◮ Java: Zur Definition einer Schnittstelle wird das Schlüsselwort class durch das Schlüsselwort interface ersetzt. ◮ Java: Alle Methoden einer Schnittstelle sind implizit abstrakt und öffentlich, alle Konstanten final, statisch und öffentlich. Redundante Modifikatoren dürfen angegeben werden. ◮ Java: Ein Interface darf keine Konstruktoren enthalten. 5.3 Abstrakte Klassen 5-27 Generizität ◮ Unter Generizität versteht man die Parametrisierung von Klassen, Datentypen, Modulen, Prozeduren, Funktionen, . . . ◮ Als Parameter werden in der Regel Datentypen (manchmal auch Algorithmen in Form von Prozeduren) verwendet. ◮ Deklariert man beispielsweise eine Liste, so sollte die Liste generisch angelegt werden. Dann kann man später Listen von Zahlen, Zeichen, o. ä. erzeugen. ◮ Auch ein Sortieralgorithmus kann generisch definiert werden. Man setzt nur voraus, dass der Datentyp eine Ordnungsrelation ≤ zur Verfügung stellt. 5.3 Abstrakte Klassen 5-28 Realisierung von abstrakten Datentypen Die folgende Elemente müssen im Programm abgebildet werden: ◮ Name des ADT: wird üblicherweise der Klassenname ◮ Importierte ADTen: werden sowohl zu Definitionen mit dem entsprechenden importierten Typ, als auch zu Import-Anweisungen innerhalb des Programms ◮ Objekterzeugende Operatoren: sogenannte Konstruktoren werden in (meist spezielle) Klassenmethoden abgebildet, die ein neues Objekt des gewünschten Typs zurückliefern ◮ Lesende Operatoren: sogenannte Selektoren werden zu Methoden, die auf die Attribute nur lesend zugreifen ◮ Schreibende Operatoren: sogenannte Manipulatoren werden zu Methoden, die den Zustand des Objekts verändern ◮ Axiome: müssen sichergestellt werden 5.4 Objektorientierte Softwareentwicklung 5-29 Realisierung eines Kellers in Java (Idee) type Stack (T ) import Bool operators empty :→ Stack push : Stack × T → Stack pop : Stack → Stack top : Stack → T empty ? : Stack → Bool axioms ∀s ∈ Stack , ∀x ∈ T pop (push (s , x )) = s top (push (s , x )) = x empty ?(empty ) = true empty ?(push (s , x )) = false 5.4 Objektorientierte Softwareentwicklung Die Implementation kann beispielsweise durch Rückgriff auf die in Java existierenden Listen geschehen. 5-30 Realisierung eines Kellers in Java (Idee) import java.util.*; class Stack<T> { protected List<T> data; public Stack() { ... } public void push(T elem) { ... } public void pop() throws EmptyStackException { ... } public T top() throws EmptyStackException { ... } public boolean isEmpty() { ... } } 5.4 Objektorientierte Softwareentwicklung 5-31 Problembereich Problemlösung Analyse Softwareentwicklung Analysemodelle Design Programmsystem Entwurfsmodelle 5.4 Objektorientierte Softwareentwicklung Implementierung 5-32 Was ist Software-Technik? W. Hesse, H. Keutgen, A. L. Luft, H. D. Rombach: Ein Begriffsystem für die Software-Technik, Informatik-Spektrum, 7, 1984, S. 200–213: Software-Technik (Software-Engineering) ist das Teilgebiet der Informatik, das sich mit der Bereitstellung und systematischen Verwendung von Methoden und Werkzeugen für die Herstellung und Anwendung von Software beschäftigt. 5.4 Objektorientierte Softwareentwicklung 5-33 Software-Technik ◮ setzt solide Kenntnisse in (mindestens) einer Programmiersprache voraus, ◮ ist nicht auf eine spezielle Programmiersprache (sondern evtl. eher auf ein Paradigma) zugeschnitten, ◮ ist ein weites und wichtiges Gebiet der Informatik. 5.4 Objektorientierte Softwareentwicklung 5-34 Teilgebiete der Software-Technik ◮ Software-Entwicklung ◮ Software-Management ◮ Software-Qualitätssicherung 5.4 Objektorientierte Softwareentwicklung 5-35 Software-Entwicklung ◮ Planungsphase ◮ Definitionsphase ◮ Entwurfsphase ◮ Implementierungsphase ◮ Abnahme- und Einführungsphase ◮ Wartungs- und Pflegephase 5.4 Objektorientierte Softwareentwicklung 5-36 Software-Management ◮ Planung ◮ Organisation ◮ Personaleinsatz ◮ Leitung ◮ Kontrolle 5.4 Objektorientierte Softwareentwicklung 5-37 Software-Qualitätssicherung ◮ Qualitätssicherung ◮ Prüfmethoden ◮ Prozessqualität ◮ Produktqualität 5.4 Objektorientierte Softwareentwicklung 5-38 Weitere Aspekte ◮ Werkzeuge, Computer Aided Software Engineering (CASE) ◮ Wiederverwendbarkeit von Software ◮ Modellierung, z. B. Unternehmensmodellierung ◮ Modellierungssprachen, z. B. UML 5.4 Objektorientierte Softwareentwicklung 5-39 Unified Modelling Language ◮ UML (Unified Modelling Language) wurde in den 1990er Jahren mit dem Ziel, eine einheitliche – auch grafische – Notation für die objektorientierte Software-Entwicklung zur Verfügung zustellen, definiert. ◮ Sie enthält ca. ein Dutzend verschiedener Modelltypen zur Beschreibung der verschiedenen Systemaspekte. ◮ Entwickler der UML waren (und sind) Grady Booch, Ivar Jacobson und James Rumbaugh. ◮ UML ist der De-facto-Standard für objektorientierte Analyse und Design. ◮ Object Constraint Language (OCL) zur Formulierung von Bedingungen. ◮ Für UML ist eine Vielzahl an Werkzeugen verfügbar. ◮ UML werden Sie in der Vorlesung „Software Engineering“ und in Praktika gründlich kennen lernen. 5.4 Objektorientierte Softwareentwicklung 5-40 Unified Modelling Language ◮ ◮ Anwendungsfalldiagramme (Benutzersicht) Implementierungsdiagramme (statische Systemstruktur) ◮ ◮ ◮ ◮ Objekt- und Klassendiagramme, Paketdiagramme Komponentendiagramme Verteilungsdiagramme Verhaltensdiagramme (dynamisches Systemverhalten) ◮ ◮ ◮ ◮ Aktivitätsdiagramme Kollaborationsdiagramme Sequenzdiagramme Zustandsdiagramme 5.4 Objektorientierte Softwareentwicklung 5-41 Anwendungsfalldiagramme ◮ modellieren die Einbettung eines Systems in seine Umgebung, ◮ beschreiben die Sicht auf Systemfunktionalität von außen und ◮ werden zur Spezifikation der globalen Systemanforderungen eingesetzt. Kreditkarten-Validierungssystem Fuehre Kartentransaktion durch Kunde Haendler Bearbeite Rechnung Einzelkunde Firmenkunde Verwalte Kundenkonto Finanzinstitut 5.4 Objektorientierte Softwareentwicklung 5-42 Klassendiagramme ◮ stellen die statische Systemstruktur dar und ◮ beschreiben die Systemelemente und ihre Beziehungen zueinander. Bitmap Bildschirm zeichnen() +Elemente Pixel x:Integer y:Integer Farbe:Colour 5.4 Objektorientierte Softwareentwicklung Quadrat Dreieck Icon 5-43 Sequenzdiagramme ◮ stellen die Abfolge der Nachrichten dar. ◮ Sie basieren auf „Message Sequence Charts“. Reader Librarian System hand_book enter_book_data update [reserved] notify acknowledge_librarian acknowledge_reader 5.4 Objektorientierte Softwareentwicklung 5-44 Object Constraint Language ◮ Object Constraint Language (OCL) ist eine Sprache, in der z. B. Vor- und Nachbedingungen sowie Schleifeninvarianten ausgedrückt werden können. ◮ OCL ist kein Bestandteil von UML, sondern ein Vorschlag für eine Sprache zur Formulierung von Erläuterungen (annotations). Prinzipiell kann hierfür jede Sprache, auch Deutsch oder Englisch, verwendet werden. ◮ OCL basiert auf der Prädikatenlogik. ◮ Einige Typen von OCL: Void, Boolean, Integer, Real, String, Tupel, Set, Ordered Set, Bag, Sequence. 5.4 Objektorientierte Softwareentwicklung 5-45 Objektorientierte Programmiersprachen Algol 60 andere PLs Ada 83 Modula-2 Simula Einfache Vererbung Koroutinen Abstrakte Datentypen Keine Vererbung Eiffel OOPLs Klassenkonzept Vererbung Smalltalk C++ Java sowie verschiedene OO-Derivate anderer Programmiersprachen (Visual-Basic, Delphi) 5.4 Objektorientierte Softwareentwicklung 5-46 Objektorientiertes Programmieren ◮ Identifizieren Sie die Klassen und die Beziehungen der Klassen untereinander. Achten Sie auf Datenkapselung und Wiederverwendbarkeit. ◮ Definieren Sie die Methoden. Denken Sie an die Möglichkeit von abstrakten Methoden und Klassen. ◮ Attribute und Methoden, die unabhängig von Instanzen existieren, sind als Klassenvariable bzw. -methoden zu vereinbaren. In der Regel sollten Sie sich auf wenige Klassenvariable und -methoden beschränken. ◮ Achten Sie auf Programmiersicherheit. Vergeben Sie nicht mehr Zugriffsrechte als erforderlich (Geheimnisprinzip). ◮ Variable, die nicht verändert werden, sollten auch als Konstante im Programm deklariert werden. 5.4 Objektorientierte Softwareentwicklung 5-47