Konzepte Objektorientierter Programmierung

Werbung
Thomas Macht
OOP WS 09/10
Konzepte Objektorientierter Programmierung
Ziel der Objektorientierten Programmierung: Verbesserung der Wartbarkeit
Objekt:
 Kapselung (encapsulation) zusammengehöriger Variablen und Routinen
(Funktionen, Prozeduren, Methoden)
 Zugriff von außen nur über Nachrichten
 Identität (identity):
o eindeutig, unveränderlich
o identische Objekte (identical objects) liegen am selben Speicherplatz
 ein Objekt mit zwei Namen
 Zustand (state):
o Werte der Variablen, änderbar
o gleiche Objekte (equal objects): selber Zustand und selbes
Verhalten
 Verhalten (behavior):
o beim Aufruf einer Routine
o abhängig von Parametern, aufgerufener Methode, Zustand des Objekts
 Schnittstelle (interface):
o Beschreibung des Objektverhaltens in einem Detaillierungsgrad, der für
Zugriffe von außen notwendig ist
o Objekt kann mehrere Schnittstellen haben (unterschiedliche
Verwendungen)
o enthalten oft nur Köpfe aufrufbarer Routinen, manchmal Konstanten
o data hiding + Kapselung = Datenabstraktion
o entspricht Typ des Objekts
Klasse:
 jedes Objekt ist Instanz einer Klasse, die seine Struktur beschreibt
 Konstruktoren (constructors): Routinen zur Erzeugung und Initialisierung
neuer Objekte
 Klasse: spezifischte Schnittstelle – Schnittstelle eines Objekts: beliebe
Schnittstelle
 alle Instanzen haben dieselben Schnittstellen, aber unterschiedliche
Identitäten, Instanzvariable und Zustände
Seite 1 von 22
Thomas Macht
OOP WS 09/10
Polymorphismus (Gegenteil: Monomorphismus):
 Variable/Routine (polymorpher Parameter: an Argumente von mehr als einem
Typ gebunden) kann gleichzeitig mehrere Typen haben:
o deklarierter Typ
o statischer Typ: vom Compiler ermittelt, kann spezifischer als
deklarierter Typ sein (Programmoptimierungen)
o dynamischer Typ: spezifischter Typ, steht erst zur Laufzeit fest
(dynamisches Binden/dynamic binding)
 universeller Polymorphismus: zueinander in Beziehung stehende Typen
haben gleichförmige Struktur
o Generizität (genericity): Ausdrücke können Parameter enthalten, für
die Typen eingesetzt werden (zB List<String>)
o enthaltender Polymorphismus (subtyping):
 Objekte der Untertypen sind auch Objekte des Obertypen
 Ersetzbarkeitsprinzip: Typ U ist Untertyp von Typ T wenn
Instanz von U überall verwendbar, wo Instanz von T erwartet
 Ad-hoc-Polymorphismus (nicht spezifisch für objektorientierte
Programmierung):
o Überladen (overloading):
 deklarierte Typen der Argumente entscheiden, welche Routine
ausgeführt wird
 Typen müssen in keiner Relation zueinander stehen
 oft syntaktische Vereinfachung
o Typumwandlung (type coercion): semantische Operation
Vererbung (inheritance):
 abgeleitete/Unterklasse (derived/subclass) – Basisklasse/Oberklasse (base
class/superclass)
 Codewiederverwendung
 Änderungen der Unterklassen in populären Programmiersprachen:
o Erweiterung um neue Methoden, Variable, Konstruktoren
o Überschreiben von Methoden der Oberklasse
 in Java und C++ enger Zusammenhang zu enthaltendem Polymorphismus
(Grund für eingeschränkte Änderungsmöglichkeiten)
 Einfachvererbung (single inheritance) – Mehrfachvererbung (in Java nur mit
Interfaces)
Seite 2 von 22
Thomas Macht
OOP WS 09/10
Qualität in der Programmierung


Qualität von Programmen:
o Brauchbarkeit/Usability
 Zweckerfüllung (Features)
 Bedienbarkeit (Einlernaufwand)
 Effizienz des Programms
o Zuverlässigkeit
o Wartbarkeit (bis zu 70 % der Gesamtkosten):
 Einfachheit
 Lesbarkeit
 Lokalität
 Faktorisierung: Ersetzen von ähnlichen Befehlssequenzen durch
Routinen, Objekte
Effizienz der Programmerstellung/-wartung
o Softwareentwicklungsprozess:
 Analyse (analysis)
 Entwurf (design)
 Implementierung (implementation)
 Verifikation (Anforderungen, verification) und Validierung
(Funktion, validation)
o Wasserfallmodell – zyklische Softwareentwicklungsprozesse
(Anforderungsänderungen besser, Zeit und Kosten schwerer planbar)
Rezept für gute Programme
Verantwortlichkeiten (responsibilities) einer Klasse:
 Was weiß ich? (Zustand der Instanzen)
 Was mache ich? (Verhalten der Instanzen)
 Wen kenne ich? (sichtbare Objekte/Klassen)
 Entwickler der Klasse zuständig
Klassen-Zusammenhalt (class coherence):
 hoch, wenn alle Variablen und Methoden der Klasse eng zusammenarbeiten
und durch den Klassennamen gut beschrieben sind
 es fehlt etwas Wichtiges, wenn man beliebige Variablen/Methoden entfernt
 Zusammenhalt sinkt bei sinnändernder Umbenennung
 sollte hoch sein (gute Zerlegung des Programms in Klassen/Objekte, gute
Faktorisierung)
Objekt-Koppelung (object coupling):
 Abhängigkeit der Objekte voneinander
 stark, wenn:
o große Anzahl nach außen sichtbarer Methoden und Variablen
o im laufenden System häufige Nachrichten zwischen unterschiedlichen
Objekten, große Parameteranzahl bei diesen Methoden
 sollte schwach sein (gute Kapselung, Objekte sind so unabhängig wie
möglich)
Refaktorisierung: rechtzeitig, vernünftiges Maß  gutes Programm
Seite 3 von 22
Thomas Macht
OOP WS 09/10
Wiederverwendung (reuse):
 Programme
 Daten
 Erfahrungen
 Code:
o globale Bibliotheken
o fachspezifische Bibliotheken
o projektinterne Wiederverwendung
o programminterne Wiederverwendung  Programm wird kleiner,
einfacher, leichter wartbar
 Abwägen zwischen investierter Zeit – Nutzen
Entwurfsmuster (design patterns):
 Wiederverwendung von (kollektiver) Erfahrung
 Name
 Problemstellung
 Lösung
 Konsequenzen (Vor- und Nachteile)
Paradigmen der Programmierung


Stil
Objektorientierte Programmierung für Systeme, deren Gesamtkomplexität jene
der einzelnen Algorithmen deutlich übersteigt
Imperative Programmierung:
 Programme sind aus Anweisungen aufgebaut (in fester Reihenfolge
ausgeführt)
 grundlegende Sprachelemente: Variablen, Konstanten, Routinen
 wichtigster Befehl: destruktive Zuweisung (neuer Wert unabhängig vom alten)
 Programmzustand:
o Menge aller Werte, Zeiger auf nächsten auszuführenden Befehl
o ändert sich mit Ausführung einer Anweisung
 Prozedurale Programmierung:
o konventioneller Programmierstil, zB C
o Programme in sich gegenseitig aufrufende Prozeduren zerlegt
o strukturierte Programmierung
 Objektorientierte Programmierung:
o Weiterentwicklung der strukturierten Programmierung
o zusammengehörige Routinen und Daten zu Objekten
zusammengefasst
Seite 4 von 22
Thomas Macht
OOP WS 09/10
Deklarative Programmierung:
 Beziehungen zwischen Ausdrücken in einem System
 keine zustandsändernden Anweisungen
 mathematische Modelle, höhere Abstraktionsniveau als imperative Sprachen
 grundlegende Sprachelemente: Symbole (in Gruppen wie Variablen-,
Funktionssymbole und Prädikate einteilbar)
 Funktionale Programmierung:
o Lambda-Kalkül: definiert mathematischen Formelbegriff formal
o alle Ausdrücke als Funktionen aufgefasst
o wesentlicher Berechnungsschritt: Anwendung einer Funktion auf einen
Ausdruck
o referentielle Transparenz: Ausdruck in einem Programm bedeutet
immer dasselbe, egal wann und wo ausgewertet
 Logikorientierte Programmierung:
o beruht auf einer Teilmenge der Prädikatenlogik erster Stufe
o zB Prolog
Paradigmen für Modularisierungseinheiten:
 abstrakte Datentypen:
o verstecken interne Darstellung ihrer Instanzen, auf Objekten nur vom
ADT exportierte Operationen anwendbar
o structs (im Großen und Ganzen Klassen ohne enthaltendem
Polymorphismus und Vererbung)
 Module:
o Gruppierungen von Variablen, Routinen, Typen, Klassen
o entsprechen Objekten, die direkt (ohne Klassen, nicht zur Laufzeit)
erzeugt werden
o zyklenfrei (A kann nicht B, und B A verwenden, für
Kompilierungsreihenfolge)
 Komponentenprogrammierung:
o selbe Komponente soll in unterschiedlichen Programmen einsetzbar
und austauschbar sein
o nur Schnittstellen anstatt namentlicher Verweise
o Zusammensetzung erst zur Laufzeit
o zB .Net Komponetenmodell
o Zuordnung zu Klasse nicht nötig, aber idR vorgesehen
 Generische Programmierung:
o Entwicklung generischer Abstraktionen als modulare
Programmeinheiten
o generische Einheiten zur Laufzeit zu konkreten
Datenstrukturen/Klassen/Typen/Funktionen/Prozeduren instanziert, die
benötigt werden
o zB List <A>
Seite 5 von 22
Thomas Macht
OOP WS 09/10
Enthaltender Polymorphismus und Vererbung


meist Vererbung so eingeschränkt, dass sie wichtigste Anforderungen des
enthaltenden Polymorphismus erfüllen kann
in Java ist Vererbung Voraussetzung für Untertypbeziehungen
Ersetzbarkeitsprinzip




wichtigste Grundlage des enthaltenden Polymorphismus
Typ U ist Untertyp von Typ T, wenn Instanz von U überall verwendbar, wo
Instanz von T erwartet
Aufruf einer Routine mit einem Argument, dessen Typ ein Untertyp des Typs
des entsprechenden formalen Parameters ist
Zuweisung eines Objektes an eine Variable, wobei der Typ des Objekts ein
Untertyp des deklarierten Typs der Variablen ist
Untertypbeziehungen sind …
 reflexiv
 transitiv
 antisymmetrisch
U ist ein Untertyp von T wenn …
 für jede Konstante in T gibt es eine entsprechende in U, deklarierter Typ U
der Konstante in U ist ein Untertyp des deklarierten Typs der Konstante in T 
kovariant
 für jede Variable in T gibt es eine entsprechende in U, deklarierte Typen sind
gleich  invariant
 für jede Methode in T gibt es eine entsprechende in U, deklarierter
Ergebnistyp in U ist Untertyp des Ergebnistyps in T, gleiche Anzahl formaler
Parameter, deklarierter Typ jedes formalen Parameters in U ist Obertyp des
entsprechenden Parameters in T (gilt nur für Eingangsparameter,
Ausgangsparameter sind kovariant, Durchgangsparameter invariant)
Kovarianz:
 deklarierter Typ eines Elements in U ist Untertyp des deklarierten Typs in T
 Konstante (nicht in Java), Ergebnisse von Methoden (ab Java 1.5),
Ausgangsparameter
 Typen und darin betrachtete Elementtypen variieren in dieselbe Richtung
Kontravarianz:
 deklarierter Typ eines Elements in U ist Obertyp des deklarierten Typs in T
 deklarierte Typen von formalen Eingangsparametern
 Typen und darin betrachtete Elementtypen variieren in entgegengesetzte
Richtungen
Invarianz:
 deklarierter Typ eines Elements in U ist gleich dem deklarierten Typ in T
 Variable, Durchgangsparameter
Seite 6 von 22
Thomas Macht
OOP WS 09/10
Binäre Methode:
 formaler Parametertyp gleich der Klasse, in der die Methode definiert ist
 widerspricht Ersetzbarkeitsprinzip (in Java überladen, nicht überschrieben)
Realisierung in Java:
 alle Typen invariant (außer Ergebnistypen ab Version 1.5)
 Konstanten als spezielle Variable angesehen
 überladene Methoden kaum von Methoden mit kontravariant veränderten
Typen auseinanderzuhalten
Untertypen und Codewiederverwendung:
 Ersetzbarkeit  Codewiederverwendung zwischen Versionen und intern im
Programm, Programmänderungen werden lokal gehalten
 Schnittstellen können im Wesentlichen nur erweitert werden  Schnittstellen,
besonders an der Wurzel, sollten stabil bleiben (gute Faktorisierung hilft)
 Parametertypen sollten allgemein gewählt werden
Dynamisches Binden:
 bei Verwendung von enthaltendem Polymorphismus kann der dynamische
Typ einer Variablen/eines Parameters ein Untertyp des statischen/deklarierten
Typs sein
 Java: unabhängig vom statischen Typ immer in der Klasse des Objekts
definierte Methode ausgeführt (spezifischter dynamischer Typ der Variablen)
 verwandt mit switch-Anweisungen, aber bessere Lesbarkeit und Änderungen
können lokal gehalten werden
Seite 7 von 22
Thomas Macht
OOP WS 09/10
Ersetzbarkeit und Objektverhalten
weitere, nicht vom Compiler überprüfbare Bedingungen für Ersetzbarkeit
Client-Server-Beziehungen:
 Objekt stellt als Server anderen Dienste zur Verfügung
 Objekt nimmt als Client Dienste anderer Objekte in Anspruch
 Objekt gegen anderes austauschbar, wenn es zumindest dieselben Dienste
anbietet
Objektverhalten: Wie verhält sich das Objekt beim Empfang einer Nachricht?
Zusicherungen (assertions):
 Vorbedingungen (preconditions):
o Client vor Erfüllung vor Ausführung verantwortlich
o hauptsächlich Eigenschaften der Argumente
o können Zustand des Servers einbeziehen, sofern der Client ihn kennt
 Nachbedingungen (postconditions):
o Server für Erfüllung nach Ausführung verantwortlich
o Methodenergebnisse und Änderungen/Eigenschaften des
Objektzustands
 Invarianten (invariants):
o Server für Erfüllung vor und nach Ausführung verantwortlich
o impliziert eine Nachbedingung auf jeder Methode des Servers
 sollten stabil bleiben (keine unnötigen Details festlegen)
 so einsetzen, dass Klassenzusammenhalt maximiert und Objektkoppelung
minimiert wird
 alle benötigten Zusicherungen sollen explizit oder implizit im Programm stehen
 gehören zum Typ des Objekts
Typ besteht aus:
 Name einer Klasse, eines Interfaces oder eines einfachen Typs
 entsprechender Schnittstelle
 dazugehörigen Zusicherungen
Untertypen und Verhalten:
damit U Untertyp von T ist:
 jede Vorbedingung auf einer Methode in T impliziert eine in U
(Vorbedingungen in Untertypen können schwächer, aber nicht stärker sein)
 jede Nachbedingung auf einer Methode in U impliziert eine in T
(Nachbedingungen in Untertypen können stärker, aber nicht schwächer
sein)
 jede Invariante in U impliziert eine in T (Invariante in Untertypen können
stärker, aber nicht schwächer sein)
Seite 8 von 22
Thomas Macht
OOP WS 09/10
Abstrakte Klassen:
 nur zur Festlegung des Typs, es können keine Instanzen erzeugt werden
 dürfen sowohl abstrakte Klassen (müssen in Unterklassen implementiert
werden) als auch konkrete (werden vererbt) enthalten
 als Obertypen und Parametertypen sollten abstrakte Klassen ohne
Implementierungen und Interfaces verwendet werden (leichter stabil zu halten)
Vererbung versus Ersetzbarkeit



Untertypbeziehung:
o beruht auf Ersetzbarkeitsprinzip
o bei Nichtbeachtung erschwerte Wartung (Programmänderungen
bleiben nicht lokal)
Vererbungsbeziehung:
o Klasse entsteht durch Abänderung einer anderen
o Ziel: Codewiederverwendung
o sollten sich Untertypbeziehungen unterordnen  keine
Vererbungsbeziehung, die nicht Untertypbeziehung ist
Reale-Welt-Beziehung: angenommene „is a“-Beziehungen in Analyse und
Entwurf (zB Student ist Person), entwickeln sich vor allem zu Untertyp-,
gelegentlich zu Vererbungsbeziehungen weiter
Untertypbeziehungen in Java:
 setzen Vererbungsbeziehungen voraus
 derart eingeschränkt, dass vom Compiler überprüfbare Bedingungen immer
erfüllt
 wesentliches Unterscheidungskriterium: Zusicherungen kompatibel?
Seite 9 von 22
Thomas Macht
OOP WS 09/10
Klassen und Vererbung in Java












aktuelle Instanz: this
Basisklasse: super
Konstruktor der Basisklasse: super()
Destruktor: finalize()
Klassenvariable und -methoden: static
static initializer (Initialisierung von Klassenvariablen): static {}
Konstanten: final
Geschachelte Klassen (nested classes):
o Statische geschachtelte Klassen: können nur auf Klassenvariablen
und statische Methoden der umschließenden Klasse zugreifen
o Innere Klassen: gehören zu einer Instanz der umschließenden Klasse,
dürfen keine statischen Methoden oder Klassenvariablen enthalten
o hohe Objektkoppelung
Klassen sind Objekte (Instanzen der vordefinierten Klasse Class):
o statische Methoden und Klassenvariable nur verwenden, wenn als
Variable/Methode einer Instanz von Class betrachtet
o NICHT Klassenvariable als Variable sehen, die allen Instanzen einer
Klasse gemeinsam gehört, Zugriff wie auf ein anderes Objekt (mit
Methoden, nicht direkt)
2 Variablen mit selben Namen können in Unter- und Oberklasse existieren
(nicht überschrieben wie Methoden)  verdeckt, ansprechen mit super
final-Methoden:
o dürfen in Unterklasse nicht überschrieben werden  statisches Binden
o nur in Spezialfällen
final-Klassen: haben keine Unterklassen
Paketkonzept:
 mehrere Klassen in einer Quellcodedatei (.java) möglich, aber nur eine public
(Name = Dateiname)
 jede kompilierte Klasse in einer eigenen Datei (.class)
 Paket = Verzeichnis
 import:
o von einzelnen Klassen/allen Klassen eines Paketes
o nur am Dateianfang
 package paketPfadName:
o Aufruf von javac oder java muss vorgegebenen Pfad enthalten
o Datei wird nicht aus dem Kontext gerissen/in anderem Paket verwendet
Sichtbarkeiten:
 public: sichtbar und ererbbar im selben und in anderen Paketen, nicht für
Variable (Zusicherungen)
 protected: nicht in anderen Paketen sichtbar, aber ererbbar
 Default (package): in anderen Paketen weder sichtbar noch ererbbar
 private
 Variable sollen nicht public sein (geeignete Zusicherungen)  getter und
setter (deuten auf starke Objektkoppelung und niedrigen
Klassenzusammenhalt hin)
Seite 10 von 22
Thomas Macht
OOP WS 09/10
Interfaces:
 im Wesentlichen eingeschränkte abstrakte Klassen (alle Methoden abstrakt,
abstract kann weggelassen werden)
 Mehrfachvererbung von Interfaces wird in Java unterstützt (nach extends
mehrere durch Komma getrennte Namen von Interfaces)
 keine Variablen, aber Konstanten (static final)
 alle Methoden und Konstanten sind public (kann weggelassen werden)
 stabiler als Klassen mit Implementierung, sind abstrakten Klassen vorzuziehen
Seite 11 von 22
Thomas Macht
OOP WS 09/10
Generizität und Ad-hoc-Polymorphismus


Generische Klassen, Typen und Routinen enthalten Typparamater, für die
Typen eingesetzt werden.
statischer Mechanismus: kleiner Zusatzaufwand für Compiler, aber keiner zur
Laufzeit
Generizität
Einfache Generizität in Java:
 Generische Klassen/Interfaces haben ein/mehrere Typparameter: <A,B>
 Autoboxing/-unboxing: Umwandlung primitive Datentypen  Referenztypen
 generische Methoden bezüglich Parameter oder Rückgabewert (für
Typparameter zu verwendende Typen müssen nicht explizit angegeben
werden, Berechnung = Typinferenz)
Gebundene Generizität in Java:
 einfache Generizität: nichts über Typ, den der Typparameter ersetzt, bekannt
(Methoden, Variable)  Angeben einer Schranken  Instanzen des
Typparameters können wie Instanzen der Schranke verwendet werden
 zB class Hashtable<Key extends Hashable, Value> (Hashable als Schranke
auf Key definiert)
 eine Klasse und/oder mehrere Interfaces <Key extends Hashable & Interface1
& Interface2>
 ungebundener Typparameter: keine Schranke angegeben  Object als
Schranke angenommen
 F-gebundene Generizität:
o mit rekursiven Typparametern
o zB interface Comparable<A> – class Integer implements
Comparable<Integer>
o keine sicheren impliziten Untertypbeziehungen (zB List<String> –
List<Object>, auch nicht wenn String Untertyp von Object ist!)
o Arrays unterstützen implizite Untertypbeziehungen  bei Verwendung
von Generizität vom Compiler abgefangen
 gebundene Wildcards:
o als Typen ersetzen Typparameter (zB void drawAll (List<? extends
Polygon> p) { ... })
o nur Lesezugriffe auf Parameter p (Kovarianz)
o bei Verwendung ohne Schranken  nur Lesezugriffe <? extends
Object>
 super:
o jeder Obertyp erlaubt (zB List <? super Square)
o Schreibzugriffe (Kontravarianz)
 new A(): illegal, wenn A Typparameter
 new A[n]: in einigen Fällen nicht statisch Typsicher
Seite 12 von 22
Thomas Macht
OOP WS 09/10
Verwendung von Generizität





gleich strukturierte Klassen und Routinen (Containerklassen wie Listen,
Stacks, Hashtabellen, Mengen; Routinen die auf Containerklassen zugreifen
wie sortieren, suchen)
viele Klassen und Routinen in Bibliotheken
Typparameter als Typen formaler Parameter, wenn Änderungen der
Parametertypen absehbar (zB neue Währung: Dollar  Euro)
Untertypbeziehungen Vorzug gegenüber Generizität geben 
Codeänderungen mit klaren Grenzen
oft gegeneinander austauschbar, aber homogene Listen nur mit Generizität,
ohne Untertypbeziehungen (gebundene Generizität) keine heterogenen Listen
mit Elementen verschiedener Typen
Arten der Generizität:
Übersetzung generische Klassen/Routinen in ausführbaren Code:
 homogene Übersetzung:
o Java
o jede generische Klasse in genau eine Klasse mit JVM-Code übersetzt
o jeder gebundene Typparameter durch erste Schranke des
Typparameters (ungebundener  Object) ersetzt
o gibt eine Methode eine Instanz eines Typparameters zurück 
dynamisch in Typ, der den Typparameter ersetzt, umgewandelt
o Speichereffizienz
 heterogene Übersetzung:
o für jede Verwendung mit anderen Typparametern eigener übersetzter
Code erzeugt
o „copy and paste“
o Laufzeiteffizienz (keine Typumwandlungen  Überprüfungen)
o bei gebundener Generizität müssen keine Schranken (kein
gemeinsamer Obertyp erforderlich) angegeben werden  Überprüfung
für jede übersetzte Klasse, ob Typen vorausgesetzte Eigenschaften
erfüllen (templates in C++; Java: dafür mehrere Interfaces)
Seite 13 von 22
Thomas Macht
OOP WS 09/10
Typfragen und Typumwandlungen


prozedurale und funktionale Programmiersprachen: strenge Unterscheidung
Typinformationen (stehen nur Compiler bei der Übersetzung zur Verfügung) –
dynamische Programminformationen, keine dynamischen Typinformationen
objektorientierte Programmiersprachen: dynamische Typinformationen für
dynamisches Binden benötigt, oft direkter Zugriff darauf (Überprüfung,
Umwandlung)
Verwendung dynamischer Typinformation:
 getClass()
 instanceof (Ist dynamischer Typ eines Referenzobjekts Untertyp eines
gegebenen Typs?; wenn null  false)
 explizite Typumwandlung: ((Zieltyp)Variable)
 Fehler werden verdeckt, schlecht wartbar (switch-Anweisungen)  Ersatz
durch dynamisches Binden wenn möglich, außer:
o Klassen können nicht erweitert werden
o Methode muss in vielen Klassen implementiert werden wenn nicht in
gemeinsamer Oberklasse möglich
 Typumwandlungen auf primitiven Typen:
o dynamischer Typ immer gleich deklariertem Typ
o tatsächlich Umwandlung der Instanzen, nicht deklarierter Typen
o Informationen können verloren gehen
Typumwandlungen und Generizität:
 homogene Übersetzung einer generischen Klasse/Routine:
o alle Ausdrücke in spitzen Klammern weggelassen, jedes andere
Vorkommen eines Typparameters durch Object/Schranke ersetzt
o Ergebnis generischer Routinen muss in Instanz des Typs, der den
Typparameter ersetzt, umgewandelt werden
 Nachteil: statt Compilerfehlermeldungen Ausnahmebehandlungen erst zur
Laufzeit (höhere Typsicherheit von Generizität)
 nur sichere Typumwandlungen einsetzen:
o in Obertyp des deklarierten Typs (up-cast, Gegenteil: down-cast)
o vorherige dynamische Typabfrage (down-casts)
o schreiben als ob man Generizität verwenden würde, händische
Überprüfung auf mögliche Typfehler, dann homogene Übersetzung 
keine unnötigen dynamischen Typabfragen (down-casts)
 Generizität ist Typumwandlungen vorzuziehen
 Raw Types: generische Typen ohne Typparameter  keine Typüberprüfung
der Generizität
Seite 14 von 22
Thomas Macht
OOP WS 09/10
Kovariante Probleme:
 Kovarianz:
o Typ eines Elements im Untertyp ist Untertyp des Typs des Elements im
Obertyp
o Typen und darin betrachtete Elementtypen variieren in dieselbe
Richtung
o Konstanten, Ergebnisse von Methoden, Ausgangsparameter
o kovariante Eingangsparameter verletzen Ersetzbarkeitsprinzip! 
dynamische Typabfragen und -umwandlungen (allgemeinere
Sichtweise)
o Bsp: Tier – Rind – Tiger, Futter – Fleisch – Gras (Lösung: auch Rind
kann Fleisch angeboten werden)
 häufig binäre Methoden (Parametertyp = Klasse, die Methode enthält)
Überladen vs. Multimethoden








dynamisches Binden in Java: nur deklarierter Typ eines Parameters für
Auswahl einer überladenen Methode relevant, nicht dynamischer
allgemein: dynamisches Binden kann dynamischen Typ des Parameters in
Methodenauswahl mit einbeziehen  Multimethoden
dynamisches Binden nur so verwenden, daß es keine Rolle spielt, ob bei der
Methodenauswahl deklarierte oder dynamische Typen der Argumente
verwendet werden!
Typumwandlungen ändern deklarierten Typ!
für je zwei überladene Methoden gleicher Parameteranzahl:
o zumindest eine Parameterposition, an der sich die Parametertypen
unterscheiden, nicht in Untertyprelation zueinander stehen und keinen
gemeinsamen Untertyp haben
o oder alle Parametertypen der einen Methode sollen Obertypen der
Parametertypen der anderen Methode sein, bei Aufruf der einen
Methode nur auf andere Methode verzweigt, wenn dynamische Typen
der Argumente das erlauben
Multimethoden  höhere Komplexität der Methodenauswahl
Simulation von Multimethoden durch wiederholtes einfaches (anstelle
mehrfaches) dynamisches Binden: auszuführende Methode durch Typen
mehrerer Argumente bestimmt
Visitor Pattern:
o Visitorklassen und Elementklassen (oft gegeneinander austauschbar)
o zB Futter – Tier
o Nachteil: große Anzahl benötigter Methoden
Seite 15 von 22
Thomas Macht
OOP WS 09/10
Ausnahmebehandlung






Ausnahmen in Java: Objekte von Throwable (in der Praxis nur Instanzen von
Error: schwerwiegend und Exception: vom Programmierer selbst
definiert/Instanz von vordefinierter Klasse RuntimeException)
werfen mit throw, abfangen mit try-catch (wenn mehrere passende, erste
gewählt)
Methoden dürfen nur Instanzen von Error, RuntimeException und von Typen
die (mittels throws) ausdrücklich angegeben sind zurückgeben.
Ausführung einer Methode von U darf nur bei Ausführung der Methode in T
erwartete Ausnahmen zurückliefern (Ausnahmen dürfen aber in Untertypen
weggelassen werden)
finally: in jedem Fall ausgeführt (bei Ausnahme im catch-Block vor
Weitergabe der Ausnahme), Freigabe von Ressourcen
Einsatz:
o Unvorhergesehene Programmabbrüche (Ausgabe von Informationen)
o Kontrolliertes Wiederaufsetzen
o Ausstieg aus Sprachkonstrukten
o Rückgabe alternativer Ergebniswerte
o sparsam, nur in echten Ausnahmesituationen und wenn die
Programmlogik vereinfacht wird
Nebenläufige Programmierung












mehrere Threads gleichzeitig nebeneinander (tatsächlich auf mehreren
Prozessorkernen oder scheinbar auf einem)
Synchronisation um inkonsistente Werte zu vermeiden
synchronized: Schlüsselwort bei Methode, in jedem Objekt zu jedem
Zeitpunkt höchstens eine synchronized Methode ausgeführt, atomare
Ausführung
synchronized-Blöcke: synchronized (this) { … }, Argument bestimmt Objekt auf
dem ein Lock gesetzt wird, bei Methoden immer this
wait() in Object vordefiniert, blockiert Thread bis explizit aufgeweckt oder mit
Argument für bestimmte Zeit
notifyAll()
notify(): nur ein zufällig gewählter Thread aufgeweckt
Runnable: Interface, spezifiziert nur run()
Erzeugen eines neuen Threads mit new Thread(p), p ist Instanz von
Runnable, bewirkt Ausführung von run() in p
Collections.synchronizedList(new LinkedList())
Deadlock: zyklische Abhängigkeiten zwischen zwei oder mehreren Threads
in Java verwendet: Monitor-Konzept
Seite 16 von 22
Thomas Macht
OOP WS 09/10
Softwareentwurfsmuster
Erzeugende Entwurfsmuster (creational patterns)
Factory Method (Virtual Constructor):
 Definition einer Schnittstelle für die Objekterzeugung (abstrakt oder DefaultImplementierung)
 tatsächliche Erzeugung in Unterklassen, diese entscheiden von welcher
Klasse erzeugte Objekte sein sollen
 zB BakingMachine – RoundMachine/StarMachine/SquareMachine
 Anwendung:
o Klasse soll neue Objekte erzeugen, kennt deren Klasse aber nicht
o Unterklassen sollen Objekte bestimmen, die Klasse erzeugt
o Klassen delegieren Verantwortlichkeiten an Unterklassen und Wissen,
an welche, soll lokal gehalten werden
 flexibler (Entwicklung von Unterklassen)
 Verknüpfung paralleler Klassenhierarchien (zB Maschinen – Kekse)  viele
Klassen  Generizität (nicht in Java: new A())
Seite 17 von 22
Thomas Macht
OOP WS 09/10
Prototype:
 Art eines neu zu erzeugenden Objekts durch Prototyp-Objekt spezifiziert, neue
Objekte durch kopieren
 Anwendung:
o wenn System unabhängig davon sein soll, wie seine Produkte erzeugt,
zusammengesetzt und dargestellt werden
o Klassen, von denen Instanzen erzeugt werden sollen erst zur Laufzeit
bekannt
o Vermeidung einer Hierarchie von Creator-Klassen, die paralleler
Hierarchie von Product-Klassen entspricht (Factory Method)
o wenn jede Instanz einer Klasse nur wenige unterschiedliche Zustände
haben kann oft einfacher für jeden möglichen einen Prototyp zu
erzeugen als bei jedem new passende Zustände anzugeben
 verstecken konkrete Produktklassen vor Anwendern
 in Java clone() bereits in Object definiert (flache Kopie, für tiefe
überschreiben), Klasse muss Interface Cloneable implementieren  sonst
Ausnahmebehandlung
Singleton:
 eine Klasse hat nur eine Instanz (globale Variable würde nicht Erzeugung
weiterer verhindern), globaler Zugriff darauf
 zB ein globaler Drucker-Spooler
 Klasse soll durch Vererbung erweiterbar sein, erweiterte Klasse ohne
Änderungen verwendbar  flexibler als statische Methoden
 statische Methode instance gibt einzige Instanz zurück (oder erzeugt sie,
wenn nicht vorhanden)
 auch mehrere Instanzen möglich
 Konstruktor ist protected
Seite 18 von 22
Thomas Macht
OOP WS 09/10
Strukturelle Entwurfsmuster (structural patterns)
Decorator (Wrapper):
 gibt einzelnen Objekten (anstelle ganzer Klassen) dynamisch zusätzliche
Verantwortlichkeiten (können wieder entzogen werden)
 flexible Alternative zur Vererbung  weniger Unterklassen (dafür viele kleine
Objekte), nicht unterstützt (final)
 zB ein Fenster erhält eine Scrollbar, andere Fenster nicht
 Nachteil: Instanzen von ConcreteComponent und Decorator sind nicht
identisch
 für Erweiterungen der Oberfläche/des Erscheinungsbilds, nicht für inhaltliche
Erweiterungen und von Grund auf umfangreiche Objekte
Window w = new WindowImpl(); // no scroll bar
w = new ScrollBar(w); // add scroll bar
w = ((ScrollBar)w).noScrollBar(); // remove scroll bar
Seite 19 von 22
Thomas Macht
OOP WS 09/10
Proxy (Surrogate):
 Platzhalter für anderes Objekt, kontrolliert Zugriffe darauf
 teures Objekt erst erzeugt, wenn nötig (zB umfangreiche Daten aus dem
Internet geladen)
 Zeiger auf teures Objekt. leitet Aufrufe (nach evtl. weiteren Aktionen, zB
erzeugen) weiter
 Schnittstelle von Proxy entspricht Subject  kann als Ersatz für eigentliches
Objekt verwendet werden
 intelligentere Referenz als simpler Zeiger
 Arten:
o Remote Proxies: Platzhalter für Objekte in anderen Namensräumen
(zB andere Rechner), Weiterleitung über komplexere
Kommunikationskanäle
o Virtual Proxies: erzeugen aufwendige Objekte bei Bedarf
o Protection Proxies: kontrollieren Zugriffe auf Objekte
o Smart References: ersetzen einfache Zeiger, Mitzählen der
Referenzen (kann entfernt werden, wenn keine mehr vorhanden),
Zusicherung des exklusiven Zugriffs
Seite 20 von 22
Thomas Macht
OOP WS 09/10
Entwurfsmuster für Verhalten (behavioral patterns)
Iterator (Cursor):
 ermöglicht sequentiellen Zugriff auf Elemente eines Aggregats (Sammlung
von Elementen, zB Collection) ohne dessen innere Darstellung offen zu legen
 einheitliche Schnittstelle für Abarbeitung verschiedene Aggregatstrukturen
 unterstützen unterschiedliche Varianten in der Abarbeitung von Aggregaten
(zB Bäume)
 gleichzeitig mehrere Abarbeitungen auf selbem Aggregat
 interner – externer Iterator: Iterator führt übergebene Routine auf allen
Elementen aus (zB max()) – Anwender fragt nächstes Element an (flexibler,
hauptsächlich)
 Java 1.5: for (String s: l) ist abgekürzte Schreibeweise für for (Iterator<String>
i = l.iterator(); i.hasNext();)
 Algorithmus zum Durchwandern des Aggregats kann im Iterator (flexibler)
oder im Aggregat selbst (private Implementierungsdetails) implementiert sein
 in Java Iteratoren durch geschachtelte Klassen in Aggregaten  starke
Abhängigkeit Aggregat – Iterator
 Robuster Iterator: funktioniert trotz Löschen/Hinzufügen von Elementen
(ohne ganzes Aggregat zu kopieren)
Seite 21 von 22
Thomas Macht
OOP WS 09/10
Template Method:
 definiert unveränderliches Grundgerüst eines Algorithmus in einer Operation,
überlässt Implementierung einiger veränderlicher Schritte aber Unterklassen
(primitive Methoden idR protected)
 Codewiederverwendung
 hooks (Operationen mit Default-Verhalten, dürfen überschrieben werden) –
abstrakte Operationen
 Template Method selbst soll nicht überschrieben werden  final
 Hollywood-Prinzip: „Don’t call us, we call you“: Oberklasse ruft Methoden der
Unterklasse auf
 wenige primitive Operationen
Seite 22 von 22
Herunterladen