Cmputational Programmiermethodik

Werbung
C
O
L
mputational
gic
Programmiermethodik
René Thiemann
Institute of Computer Science
University of Innsbruck
SS 2013
RT (ICS @ UIBK)
Programmiermethodik
1/613
Übersicht
Einführung
Einführung in Java
Objektorientierung
Vererbung und Polymorphismus
Ausnahmebehandlung
Pakete und Dokumentation
Generische Programmierung
Java Collection Framework
Unit Tests
Entwurfsmuster
GUI-Programmierung in Java
Ausblick
RT (ICS @ UIBK)
Programmiermethodik
2/613
Einführung
Übersicht
Einführung
Organisation
Motivation
Kursinhalt
RT (ICS @ UIBK)
Programmiermethodik
3/613
Einführung
Organisation
Übersicht
Einführung
Organisation
Motivation
Kursinhalt
RT (ICS @ UIBK)
Programmiermethodik
4/613
Einführung
Organisation
Organisation
LVA 703016
VO 3
cl-informatik.uibk.ac.at/teaching/ss13/pm/
VO
PS
Donnerstags
Montags
Montags
Montags
Montags
11:15 – 13:45
12:15 – 13:45
14:15 – 15:45
16:15 – 17:45
12:15 – 13:45
HS D
RR 15
RR 15
RR 15
HSB 5
(RT)
(CH)
(CH)
(PZ)
(BH)
online Registrierung für PS – erforderlich bis zum 1. 3. 2013
online Registrierung für VO – erforderlich bis zum 31. 3. 2013
Sprechstunden
Christian Haisjackl C125 Mittwochs 09:00 – 11:00
Benedikt Hupfauf
nach Vereinbarung
René Thiemann
3M09
Montags 13:00 – 15:00
Philipp Zech
3M02
Montags 14:00 – 16:00
RT (ICS @ UIBK)
Programmiermethodik
5/613
Einführung
Organisation
Literatur
• Hanspeter Mössenböck
Sprechen Sie Java?
dpunkt.verlag
(in Bücherei)
• David J. Barnes, Michael Kölling
Java lernen mit BlueJ – Eine Einführung in die objektorientiere
Programmierung
Pearson Studium
(in Bücherei)
• Bernhard Lahres, Gregor Rayman
Objektorientierte Programmierung – Das umfassende Handbuch
Galileo Computing
(frei herunterladbar)
RT (ICS @ UIBK)
Programmiermethodik
6/613
Einführung
Organisation
Weitere Quellenangaben
• Stefan Podlipnig
Programmiermethodik
Foliensatz zur Vorlesung im SS 2012
RT (ICS @ UIBK)
Programmiermethodik
7/613
Einführung
Organisation
Organisation – Vorlesung
• Vorlesungsfolien werden auf der Homepage vor der jeweiligen
Vorlesung online gestellt
⇒ Folien zur Vorlesung mitbringen, um darin Notizen zu machen
• Prüfung: schriftlich, am letzen Vorlesungstermin: 27. Juni
RT (ICS @ UIBK)
Programmiermethodik
8/613
Einführung
Organisation
Organisation – Proseminar
• Wöchentliche Aufgabenblätter (Gruppenarbeit)
• Im Proseminar wird Blatt letzter Woche besprochen und neues Blatt
vorgestellt
• Abgabe der Lösungen inklusive Sourcecode etc. per E-Mail an
jeweiligen Lehrveranstaltungsleiter (mit Betreff: [PM13])
• Test während des Semesters (3. Juni)
• Benotung: Wöchentliche Übungsblätter (50%) und Test (50%)
• Mindestens 60% der Übungsaufgaben müssen gelöst werden!
• Anwesenheitspflicht
RT (ICS @ UIBK)
Programmiermethodik
9/613
Einführung
Motivation
Übersicht
Einführung
Organisation
Motivation
Kursinhalt
RT (ICS @ UIBK)
Programmiermethodik
10/613
Einführung
Motivation
Ziel der Vorlesung
• Grundlagen der Programmierung (aus der Einführung in die
Programmierung) vertiefen
• Grundkonzepte der Objektorientierung verstehen und anwenden
• Analyse
• Design
• Implementierung
• Erlernen einer modernen objektorientierten Programmiersprache
• Verstehen moderner Programmierprinzipien
• Methodisches Programmieren vertiefen
RT (ICS @ UIBK)
Programmiermethodik
11/613
Einführung
Motivation
Eigenschaften einer guten Software
• korrekt – Aufgaben so erfüllen, wie es erwartet wird
(Vorlesungen über Programmverifikation und Logik)
• effizient – wenig Ressourcenverbrauch, schnelle Antworten
(Vorlesung Algorithmen und Datenstrukturen)
• wartbar – leicht erweiterbar und änderbar
(diese Vorlesung)
• benutzerfreundlich – intuitiv bedienbar
RT (ICS @ UIBK)
Programmiermethodik
12/613
Einführung
Motivation
Modularisierung in der Technik
• Modularisierung in der Technik ist notwendig, um komplexe Dinge
herzustellen
• Beispiel LKW
• Grober Entwurf: Motor, Karosserie, Reifen, Sitze, . . .
• Motor: Kolben, Zündkerzen, Zylinder, . . .
Zündkerze
• Zündkerze: Isolierung, Elektrode, . . .
• ...
• Reifen: Gummimischung, Drahtgeflecht, Profil, . . .
• ...
• Wichtig: für jedes Modul braucht man nur Verständnis der
Funktionalität, nicht aber Detailkenntnis wie es diese erreicht!
RT (ICS @ UIBK)
Programmiermethodik
13/613
Einführung
Motivation
Modularisierung in der Software(-Technik)
• Modularisierung in der Software-Entwicklung ist wesentlich, um
komplexe Software zu erstellen
• Beispiel Textverarbeitung
• Grober Entwurf: Layout, Rechtschreibprüfung, Silbentrennung, GUI, . . .
• Layout: Dimensionsberechnung, Blocksatz, Schusterjungen, . . .
• GUI: . . .
• ...
• Wichtig: für jedes Modul braucht man nur Verständnis der
Funktionalität, nicht aber Detailkenntnis wie es diese erreicht!
RT (ICS @ UIBK)
Programmiermethodik
14/613
Einführung
Motivation
Objektorientierung
Objektorientierung . . .
• . . . bietet eine Möglichkeit, modulare Software zu entwickeln
• . . . basiert auf den folgenden drei Konzepten:
• Datenkapselung
• Polymorphie
• Vererbung
RT (ICS @ UIBK)
Programmiermethodik
15/613
Einführung
Motivation
Datenkapselung
• Motto: “ich muss nicht alles aufschrauben, bevor ich es benutze”
• in der Technik:
• für den Austauch einer Glühbirne ist deren Aufbau unwichtig
• man muss nur auf die passende Fassung und Leistung achten
• in der Software:
• für die Nutzung einer Datenbank ist dessen interne Struktur irrelevant
• wichtig ist jedoch die Kenntnis der Funktionalität (speichere Daten,
frage Daten ab, . . . )
• die Kapselung verhindert zudem (unbeabsichtigte) Manipulation, indem
man etwa interne Daten ändert und somit inkonsistenten Status
herbeiführt
RT (ICS @ UIBK)
Programmiermethodik
16/613
Einführung
Motivation
Polymorphismus
• Idee: Einfache Austauschbarkeit durch standardisierte Schnittstelle
• in der Technik:
RT (ICS @ UIBK)
Programmiermethodik
17/613
Einführung
Motivation
Polymorphismus
• Idee: Einfache Austauschbarkeit durch standardisierte Schnittstelle
• in der Technik:
kompatibel zu vielen Lampen!
RT (ICS @ UIBK)
Programmiermethodik
17/613
Einführung
Motivation
Polymorphismus
• Idee: Einfache Austauschbarkeit durch standardisierte Schnittstelle
• in der Technik:
kompatibel zu vielen Lampen!
• in der Software:
• biete Service für unterschiedliche Benutzer
• Dokumentation in HTML statt .docx
⇒ freie Wahl des Betriebssystem und eines Browsers
• Austausch von Teilprogrammen
• besseres Sortierverfahren (welches Methode “sort” biete)
• alternativer Fenstermanager (mit Methoden “createWindow”, . . . )
• kostengünstigere Datenbank (welche auf SQL-Standard basiert)
RT (ICS @ UIBK)
Programmiermethodik
17/613
Einführung
Motivation
Vererbung
• Motto: “das Rad nicht neu erfinden”
• Idee: erweitere oder verändere bestehende Funktionalität
• in der Technik:
• um LKW mit Kran zu entwickeln, modifiziert man normalen LKW
⇒ Vorteil: alte Funktionalität braucht nicht neu erfunden werden
• weitere Beispiele: Häuserbau, A-Team, . . .
• in der Software:
• erstelle Basisfunktionalität . . .
• . . . die auf verschiedenste Weisen erweitert oder modifiziert werden kann
• Beispiel: Java Collections Framework
RT (ICS @ UIBK)
Programmiermethodik
18/613
Einführung
Kursinhalt
Übersicht
Einführung
Organisation
Motivation
Kursinhalt
RT (ICS @ UIBK)
Programmiermethodik
19/613
Einführung
Kursinhalt
Java
• um Objektorientierung zu verstehen, benötigen wir objektorientierte
Programmiersprache:
C++, C#, Java, OCaml, Smalltalk, . . .
http://www.oracle.com/technetwork/java/index.html
• Grundkenntnisse der Programmierung in einer imperativen Sprache wie
C oder Pascal werden vorausgesetzt!
• für leichten Einstieg in Java wird IDE BlueJ empfohlen:
http://www.bluej.org
• für komplexere Projekte wird IDE Eclipse genutzt:
http://www.eclipse.org
RT (ICS @ UIBK)
Programmiermethodik
20/613
Einführung
Kursinhalt
Inhalt
• Einführung in Java
• Grundlagen der Objektorientierung (Objekte, Klassen)
• Vererbung und Polymorphismus
• Generische Programmierung
• Ausnahme-Behandlung
• Java Collections Framework
• Entwurfsmuster
• GUI-Programmierung
• ...
RT (ICS @ UIBK)
Programmiermethodik
21/613
Einführung in Java
Übersicht
Einführung in Java
Historie und Features
Grundlegende Elemente eines Java Programms (ohne OO)
Datentypen
Ausdrücke
Anweisungen
Arrays
Methoden
RT (ICS @ UIBK)
Programmiermethodik
22/613
Einführung in Java
Historie und Features
Übersicht
Einführung in Java
Historie und Features
Grundlegende Elemente eines Java Programms (ohne OO)
RT (ICS @ UIBK)
Programmiermethodik
23/613
Einführung in Java
Historie und Features
Historie
• Start 1991
• Sun Microsystems (seit 2010 Tochterunternehmen von Oracle)
• Angelehnt an C++, Elemente aus Smalltalk
(Bytecode, Garbage Collection)
• Ziel: Entwicklung einer Hochsprache für hybride Systeme im
Consumer-Electronic Bereich
• Sun Demo Web-Browser HotJava in den 90-ern (Applets)
• Durchbruch 1995
• Netscape Navigator 2.0 mit integrierter Java Virtual Machine
• Mittlerweile verschiedene Versionen
• Java 7 Standard Edition (diese Vorlesung)
• Java 6 Enterprise Edition (Business-Applikationen etc.)
• Java Micro Edition (Handy, PDA, . . . )
• Java Card Edition (Smartcards)
RT (ICS @ UIBK)
Programmiermethodik
24/613
Einführung in Java
Historie und Features
Java ist . . .
• Objektorientiert
• Portierbar
• Robust
• Strenges Typsystem
• Behandlung von Ausnahmen (Exception Handling)
• Automatische Speicherbereinigung (Garbage Collection)
• Nebenläufig
• Sicher
RT (ICS @ UIBK)
Programmiermethodik
25/613
Einführung in Java
Historie und Features
Java ist objektorientiert
• Objektorientierung ist ein Programmierparadigma
• Programmierparadigma = Sichtweise auf und Umgang mit zu
verarbeitenden Daten und Operationen
• Beispiele von Programmierparadigmen
• Imperatives Programmierparadigma (LV Einführung in die
Programmierung)
sequenziell Abarbeitung einer Folge von Anweisungen
• Objektorientiertes Programmierparadigma (diese LV, Java)
weitergehende Konzepte wie Klassen, Vererbung und Polymorphie
• Funktionales Programmierparadigma (LV Funktionale Programmierung)
funktionale Programme kennen keine Wertzuweisung;
Definition von Funktionen, die Eingabe in Ausgabe transformiert
• Logisches Programmierparadigma (LV Logikprogrammierung)
Programm ist Menge von Schlussfolgerungen; Interpreter beantwortet,
welche Schlüsse gezogen werden können
RT (ICS @ UIBK)
Programmiermethodik
26/613
Einführung in Java
Historie und Features
Beispiel: Konkatenation von Listen A und B
• Imperativ:
• Aktuelles Element E = Kopf von A
• Solange Nachfolger von E existiert, E = Nachfolger von E
• Setze Nachfolger von E auf Kopf von B
RT (ICS @ UIBK)
Programmiermethodik
27/613
Einführung in Java
Historie und Features
Beispiel: Konkatenation von Listen A und B
Lösung berücksichtigt nicht Spezialfall A = [ ]
• Imperativ:
• Aktuelles Element E = Kopf von A
• Solange Nachfolger von E existiert, E = Nachfolger von E
• Setze Nachfolger von E auf Kopf von B
RT (ICS @ UIBK)
Programmiermethodik
27/613
Einführung in Java
Historie und Features
Beispiel: Konkatenation von Listen A und B
Lösung berücksichtigt nicht Spezialfall A = [ ]
• Imperativ:
• Aktuelles Element E = Kopf von A
• Solange Nachfolger von E existiert, E = Nachfolger von E
• Setze Nachfolger von E auf Kopf von B
• Objektorientiert:
• intern: wie imperative Lösung
• Aufruf: A.append(B)
(verändert A)
RT (ICS @ UIBK)
Programmiermethodik
27/613
Einführung in Java
Historie und Features
Beispiel: Konkatenation von Listen A und B
Lösung berücksichtigt nicht Spezialfall A = [ ]
• Imperativ:
• Aktuelles Element E = Kopf von A
• Solange Nachfolger von E existiert, E = Nachfolger von E
• Setze Nachfolger von E auf Kopf von B
• Objektorientiert:
• intern: wie imperative Lösung
• Aufruf: A.append(B)
(verändert A)
• Funktional:
• append([ ], B) = B
• append([X | A], B) = [X | append(A, B)]
• Aufruf append([1,2], [4,5]) liefert [1,2,4,5]
RT (ICS @ UIBK)
Programmiermethodik
27/613
Einführung in Java
Historie und Features
Beispiel: Konkatenation von Listen A und B
Lösung berücksichtigt nicht Spezialfall A = [ ]
• Imperativ:
• Aktuelles Element E = Kopf von A
• Solange Nachfolger von E existiert, E = Nachfolger von E
• Setze Nachfolger von E auf Kopf von B
• Objektorientiert:
• intern: wie imperative Lösung
• Aufruf: A.append(B)
(verändert A)
• Funktional:
• append([ ], B) = B
• append([X | A], B) = [X | append(A, B)]
• Aufruf append([1,2], [4,5]) liefert [1,2,4,5]
• Logisch:
• append(A, B, C) ist wahr, gdw. C Konkatenation von A und B ist
• append([ ], B, B).
• append([X | A], B, [X | C]) ← append(A, B, C).
• Aufruf append([1,2], [4,5], Xs) liefert Antwort Xs = [1,2,4,5]
• Aufruf append(A, B, [1,2,3]) liefert Antworten A = [ ], B = [1,2,3] oder
A = [1], B = [2,3] oder A = [1,2], B = [3] oder A = [1,2,3], B = []
RT (ICS @ UIBK)
Programmiermethodik
27/613
Einführung in Java
Historie und Features
Java ist portierbar
• Portierbarkeit leitet sich aus Ausführungsschema ab
• Ausführungsschema bestimmt wie Programm ausgeführt wird
• Kompiliert
•
•
•
•
Programm wird in Zielsprache (Maschinencode) übersetzt
Hohe Ausführungsgeschwindigkeit
Überprüfung auf Fehler vor Ausführung
Übersetzung in Maschinencode macht Programm Plattform abhängig
• Interpretiert
• Programm wird zur Laufzeit eingelesen und Befehl für Befehl
abgearbeitet
• Langsamere Ausführungsgeschwindigkeit
• Tests und kleinere Änderung komfortabel durchführbar
• Programme laufen auf jeder Plattform, für die Interpreter vorhanden ist
• Java nutzt Mischform
• Programm wird in Zwischencode übersetzt (Bytecode)
• Bytecode wird mittels Interpreter ausgeführt (virtuelle Maschine, JVM)
• JVM dient als Schnittschnelle zwischen Bytecode und Betriebssystem
RT (ICS @ UIBK)
Programmiermethodik
28/613
Einführung in Java
Historie und Features
Java Bytecode
• Plattformunabhängig und kompakt
• Interpreter für Bytecode ist kleiner und schneller als Interpreter für
ursprünglichen Source-Code
• Endbenutzer hat keinen Zugriff auf den Source-Code
• Vorteil: kommerzielle Verwendung
(Source ist Betriebsgeheimnis)
• Nachteil: eigene Modifikationen kaum möglich
(Kunde darf gekauftes Produkt nicht anpassen)
• Interpreter kann zusätzliche Überprüfungen / Einschränkungen für
Sicherheit durchführen
(kein Festplattenzugriff für Java-Applets)
RT (ICS @ UIBK)
Programmiermethodik
29/613
Einführung in Java
Historie und Features
Java ist robust: Strenges Typsystem
• strenges Typsystem:
• Variablen haben festen Typ
• Funktionen können nur mit kompatiblen Parameter aufgerufen werden
• Fehlerhafte Ausdrücke / Typfehler werden nicht akzeptiert
• ohne Typsystem:
• Variablen können beliebige Werte zugewiesen werden
• Funktionen interpretieren Eingaben, als hätten sie passenden Typ
• Beispiel: Interpretation von Trennzeichen / Strings als Zahlen
expr
1000 + 3
1_000 + 3
”1000” + 3
”1_000” + 3
1,000,000 + 3
1.000.000 + 3
1_000_000 + 3
RT (ICS @ UIBK)
Java: int x = expr
1003
1003
Fehler
Fehler
Fehler
Fehler
1000003
Programmiermethodik
Perl: $x = expr
1003
Fehler erst
1003
zur Laufzeit
1003
sichtbar
4
1
3
1000003
30/613
Einführung in Java
Historie und Features
Java ist robust: Garbage Collection
• ohne Garbarge Collection (z.B. in C)
• Programm fordert Speicher an und gibt ihn wieder frei
• Fehleranfällig
• Speicher zu früh freigeben: Referenzen zeigen ins Nichts
• Speicher zu spät (gar nicht) freigeben: hoher (zu hoher) Speicherbedarf
• mit Garbarge Collection
• Programm fordert Speicher an, Laufzeitsystem kümmert sich um
Freigabe
• Vorteil: wenig Speicherlecks, keine fehlerhaften Referenzen
• Nachteil: Zeitpunkt der Garbage Collection nicht voraussehbar
⇒ schlecht für Echtzeit-Anforderungen
RT (ICS @ UIBK)
Programmiermethodik
31/613
Einführung in Java
Historie und Features
Java ist nebenläufig
Nebenläufigkeit
• führe Teilprogramme auf mehreren Prozessoren auf
⇒ deutlich verbesserte Effizienz auf Multi-Core Rechnern
• wird immer wichtiger in Zukunft (Tendenz: gleiche Taktfrequenz,
erhöhte Anzahl von Cores)
• Vorlesung über Nebenläufige und Parallele Programmierung
RT (ICS @ UIBK)
Programmiermethodik
32/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Übersicht
Einführung in Java
Historie und Features
Grundlegende Elemente eines Java Programms (ohne OO)
Datentypen
Ausdrücke
Anweisungen
Arrays
Methoden
RT (ICS @ UIBK)
Programmiermethodik
33/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Ein einfaches Java-Programm
c l a s s MyProgram {
s t a t i c v o i d main ( ) {
System . o u t . p r i n t ( "Die Fakultaet von 5 ist " ) ;
System . o u t . p r i n t l n ( f a c t ( 5 ) ) ;
}
static int fact ( int n) {
int r e s u l t = 1;
f o r ( i n t i = 1 ; i <= n ; i ++)
result = result ∗ i ;
return r e s u l t ;
}
}
RT (ICS @ UIBK)
Programmiermethodik
34/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Farbschema
• return, for , ... : Schlüsselwörter
• ’c’, "hallo", ... : Zeichen und Zeichenketten
• fact , MyProgram, ... : frei wählbare Namen
• // some comment : Kommentare
• 7, <=, ... : der Rest: Operatoren, Zahlen, Klammern, . . .
RT (ICS @ UIBK)
Programmiermethodik
35/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Struktur eines Java-Programms
1 c l a s s MyProgram {
2
3
s t a t i c v o i d main ( ) {
4
}
5
6
static int fact ( int n) {
7
}
8
9}
• Programm hat immer Struktur class SomeName { ... }
• Namenskonvention für Klassennamen
• mit Großbuchstaben beginnend, danach Kleinbuchstaben
• jedes neue Wort wieder mit Großbuchstaben beginnen
• Klasse SomeName muss in Datei SomeName.java gespeichert werden
(sowohl BlueJ als auch Eclipse machen dies automatisch)
• innerer Block (Zeilen 2 - 8) beinhaltet beliebig viele Methoden
RT (ICS @ UIBK)
Programmiermethodik
36/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Struktur einer Methode (= Unterprogramm)
1
2
3
4
5
6
static int fact ( int n) {
int r e s u l t = 1;
f o r ( i n t i = 1 ; i <= n ; i ++)
result = result ∗ i ;
return r e s u l t ;
}
• Methode hat immer Struktur
static returnType methodName (type1 parameterName1, ...) { ... }
• Namenskonvention für Methoden- und Parameternamen:
wie Klassennamen, nur mit Kleinbuchstaben beginnend
• mögliche Rückgabetypen (returnType):
• void: nichts wird zurückgegeben
Prozedur
• int, boolean, String, . . . : etwas wird zurückgegeben
Funktion
• innerer Block (Zeilen 2 – 5) ist beliebe Sequenz von Anweisungen
• in Methoden können lokale Variable deklariert werden ( result und i )
• bei Funktionen muss letzte Anweisung ein return sein
RT (ICS @ UIBK)
Programmiermethodik
37/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Kommentare
• Einzeilig // ... , bis zum Ende der Zeile
i n t x = 5 ; // t h i s i s a comment ; x = x + 1 0 ;
• Mehrzeilig /∗ ... ∗/ , aber nicht geschachtelt
/∗ a m u l t i l i n e
comment
/∗ i n n e r comments a r e n o t s u p p o r t e d ∗/
may r a n g e o v e r m u l t i p l y l i n e s
∗/ // F e h l e r h a f t e r Kommentar
• Dokumentation /∗∗ ... ∗/ : später
RT (ICS @ UIBK)
Programmiermethodik
38/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Übersicht
Einführung in Java
Historie und Features
Grundlegende Elemente eines Java Programms (ohne OO)
Datentypen
Ausdrücke
Anweisungen
Arrays
Methoden
RT (ICS @ UIBK)
Programmiermethodik
39/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Datentypen
• Alle Daten haben einen Typ (Datentyp)
• Typ schränkt die Benutzung der Daten ein
• Wertebereich
• Methoden haben Anforderung an Eingabe-Parameter
(Bsp: fact ("siebzehn") ist nicht erlaubt)
• Java bietet 2 Möglichkeiten
• Primitive Datentypen (beginnend mit Kleinbuchstaben)
• Datentypdefinition durch Klassen (beginnend mit Großbuchstaben)
RT (ICS @ UIBK)
Programmiermethodik
40/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Eingebaute Datentypen in Java
• Ganze Zahlen (byte (8-bit), short (16-bit), int (32-bit), long (64-bit))
Überlauf beachten: für int x = 2_147_483_647 gilt
x + 1 == −2_147_483_648 und x ∗ 2 == −2
• Gleitkommazahlen (float (32-bit), double (64-bit))
Rundungsfehler beachten: es gilt 0.1 + 0.2 != 0.3 und
0.1 + 0.3 == 0.4 und 1e18 + 1 == 1e18
• Logische Werte (boolean, zwei Werte true und false)
• Zeichen (char): 16-bit Unicode-Character (’a’, ’\n’, ’ü’, ’\uFFFF’)
• Zeichenketten (String): "Hallo!\n", "", "1e18 + 1 == 1e18"
• Beachte: String ist kein primitiver Datentyp, sondern Klasse
• Vergleich mittels == führt Identitätsvergleich aus (der selbe String?)
• Vergleich mittels equals führt Inhaltsvergleich aus (der gleiche String?)
S t r i n g x = "ab" , y = "cd" , z = "ab" + "cd" ;
boolean b1 = x + y == "abcd" ;
// f a l s e
boolean b2 = z == "abcd" ;
// t r u e
boolean b3 = ( x + y ) . e q u a l s ( "abcd" ) ; // t r u e
RT (ICS @ UIBK)
Programmiermethodik
41/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Deklaration von Variablen
• Variablen müssen deklariert werden
• Variablen müssen vor erstem Lesezugriff initialisiert werden
• Vorteil: Compiler kann passend Speicher allozieren und Fehler erkennen
RT
s t a t i c v o i d f ( i n t x ) { // P a r a m e t e r x
x = x ∗ x + 7;
y = x − 2;
// F e h l e r , y n i c h t d e k l a r i e r t
int y , z , u ;
// V a r i a b l e n y , z , und u
y = x + 2;
z = u + x;
// F e h l e r , u n i c h t i n i t i a l i s i e r t
i f ( x > y ) { // I n i t i a l i s i e r u n g m i t F a l l u n t e r .
u = y;
} else {
u = 7;
}
z = u;
int a = 3 , b = x , c = a + b ;
}
(ICS @ UIBK)
Programmiermethodik
42/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Namenskonflikte und Sichtbarkeit von Variablen
• In jedem Block sind alle äußeren Variablen (und Parameter) sichtbar
• Variablennamen müssen so gewählt werden, dass es keine 2 Variablen
gibt (bzw. Variable und Parameter), die beide im gleichen Block
sichtbar sind und denselben Namen haben
s t a t i c void f ( i n t x ) {
i n t x ; // F e h l e r , K o n f l i k t m i t P a r a m e t e r x
int y ;
{
int z ;
i n t y ; // F e h l e r , 2 V a r i a b l e n y s i c h t b a r
{ boolean y ; } // g l e i c h e r F e h l e r w i e z u v o r
}
{
String z ;
f o r ( i n t y = 1 ; y < 5 ; y++) // F e h l e r wegen y
x = x + 5;
}
}
RT (ICS @ UIBK)
Programmiermethodik
43/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Übersicht
Einführung in Java
Historie und Features
Grundlegende Elemente eines Java Programms (ohne OO)
Datentypen
Ausdrücke
Anweisungen
Arrays
Methoden
RT (ICS @ UIBK)
Programmiermethodik
44/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Wertzuweisung
• Ausdrücke werden in z.B. in Wertzuweisungen x = exp; benötigt
• Bedeutung: weise der Variable x den Wert des Ausdrucks exp zu
• Ausdrücke (Expressions) werden gebildet durch
• Literale: true , false , 7 , 3.4 , ’c’ , "hallo" , . . .
• Variablen: x , factor , sum , defaultValue , . . .
• Operator-Ausdrücke: exp + exp , − exp , exp && exp ,
exp <= exp , exp ? exp : exp , . . .
• Typ-Anpassung: (type) exp
• geklammerte Ausdrücke: (exp)
• Methodenaufrufe: someMethod(exp,...,exp) ,
exp.someMethod(exp,...,exp)
• Beispiel für komplexeren Ausdruck
static int fact ( int x) {
r e t u r n ( x <= 1 ? 1 : x ∗ f a c t ( x − 1 ) ) ;
}
RT (ICS @ UIBK)
Programmiermethodik
45/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Präzedenzen und Assoziationen
• werden benötigt, um Wert von 100 − 30 − 7 ∗ 2 festzulegen:
• Präzedenz regelt Bindungsstärke
• ∗ bindet stärker als −
⇒ 100 − 30 − 7 ∗ 2 = 100 − 30 − (7 ∗ 2) = 100 − 30 − 14
• Assoziativität regelt Klammerung bei gleicher Präzedenz
• − ist links-assoziativ
⇒ 100 − 30 − 14 = (100 − 30) − 14 = 70 − 14 = 56
RT (ICS @ UIBK)
Programmiermethodik
46/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Häufig genutzte Operatoren
• Arithmetik: + , − (binär und unär), ∗ , / , % (Rest)
• String-Konkatenation: +
• Vergleiche: == , != , < , <= , >= , >
• logische Operationen: & , && (Konjunktion), | , || (Disjunktion),
! (Negation)
• if-then-else: ? :
RT (ICS @ UIBK)
Programmiermethodik
47/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Typkompatibilität
• Operanden, Methoden-Parameter, Zuweisungen benötigen
Typkompatibilität
• Problematische Beispiele: int x = 2.5 , "vier"+ 5
• Zwei Typen sind kompatibel wenn
• sie gleich sind,
• sie durch implizite Typanpassung zum gleichen Typ führen
• implizite Typanpassung (unidirektional)
byte
short
int
long
float
double
String
char
boolean
• Beispiele
•
int fact (int x) { ... }; ... byte b = 5; int f = fact(b);
• byte b = 5; int x = b + 2; double d = x + 2.5;
•
RT (ICS @ UIBK)
String s = "a"+ 3 + 4; s = 3 + 4 + "a";
Programmiermethodik
48/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Explizite Typanpassung
• implizite Typanpassung geht nur in eine Richtung
• Problematisch
• static int foo(int x) { ... } ... long l = 5; int x = foo(l );
•
int i = 5; byte x = i + 2;
• explizite Typanpassung notwendig, Form: (type) exp
•
static int foo(int x) { ... } ... long l = 5; int x = foo((int) l );
•
int i = 5; byte x = (byte)(i + 2);
• explizite Typanpassung kann zu Datenverlusten führen:
byte b = (byte) 400;
• explizite Typanpassung manchmal trotz impliziter Anpassung nötig:
i n t x = 2_000_000_000;
long y = x + x ;
// −294_967_296
long z = ( long ) x + x ; // 4_000_000_000
RT (ICS @ UIBK)
Programmiermethodik
49/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Logische Operationen mit nicht-strikter Auswertung
• normale (strikte) Auswertung bei Operatoren & und |
• Werte erst Argumente aus, dann berechne Ergebnis
• Beispiel: 7 > 5 | 3 ∗ 100 < 2 ∗ 1000 ⇒ true | true ⇒ true
• nicht-strikte Auswertung bei Operatoren && und ||
• Werte zuerst erstes Argument aus, und nur bei Bedarf das zweite
• Beispiel: 7 > 5 || 3 ∗ 100 < 2 ∗ 1000 ⇒
true || 3 ∗ 100 < 2 ∗ 1000 ⇒ true
• nützlich, um Spezialfälle abzufangen
• Beispiel: x != 0 && 5 / x > y
• keine Division durch 0 möglich
• keine nicht-strikte Auswertungen bei arithmetischen Operationen:
• Beispiel: 0 ∗ exp wertet exp aus!
RT (ICS @ UIBK)
Programmiermethodik
50/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Spezielle Operatoren
• Zuweisung = und Abkürzungen += , −= , ∗= , ++ , −− , . . .
• x −= y steht abkürzend für x = x − y
• x++ steht abkürzend für x += 1
• x++ : x wird nach Verwendung erhöht
• ++x : x wird vor Verwendung erhöht
• diese Ausdrücke nur als Anweisung verwenden (bessere Lesbarkeit)
• Positivbeispiel: x = y = z = 5; x += 7; y−−;
• Negativbeispiel: y = 1; y = y++ + ++y + (y += y) + y;
• if-then-else Operator ? :
• nimmt drei Operanden: booleschen Ausdruck b und e_true, e_false
• b ? e_true : e_false wertet zuerst b aus
• wenn b == true, dann hat Gesamtausdruck den Wert von e_true
• ansonsten ist Ergebnis der Wert von e_false
• Beispiel: x < y ? x : y // minimum , x ? true : y // x || y
RT (ICS @ UIBK)
Programmiermethodik
51/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Übersicht Operatoren
Operatoren
() , [] , . , postfix ++ und −−
Assoz.
links
13
präfix ++ und −− , unäres + und − , ~ , ! , (type)
rechts
12
11
10
9
8
7
6
5
∗, /, %
binäres + und −
<< , >> , >>> (bit-shifting)
< , <= , >= , >
== , !=
& (logisch und bitweises UND)
^ (logisch und bitweises XOR)
| (logisch und bitweises ODER)
links
links
links
links
links
links
links
links
4
3
&& (nicht-striktes UND)
|| (nicht-striktes ODER)
links
links
Prä.
14
RT
2
?:
1
= , += , ∗= , /= ,Programmiermethodik
%= , |= , &= , ^= , . . .
(ICS @ UIBK)
rechts
rechts
52/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Übersicht
Einführung in Java
Historie und Features
Grundlegende Elemente eines Java Programms (ohne OO)
Datentypen
Ausdrücke
Anweisungen
Arrays
Methoden
RT (ICS @ UIBK)
Programmiermethodik
53/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Elementare Anweisungen
• Wertzuweisung x = exp; x += exp; ...; x++;
• leere Anweisung ;
• Variablendeklaration type var1 (= exp1), var2 (= exp2), ...;
• Block / Sequenz von Anweisungen (Statements):
{
s t mt1 ;
s t mt2 ;
...
}
• Rücksprung aus einer Methode
• Prozedur: return;
• Funktion: return exp;
RT (ICS @ UIBK)
Programmiermethodik
54/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
If-Anweisungen
• Form: if (bexp) s_true else s_false , else-Teil optional
• Semantik
• Werte booleschen Ausdruck bexp aus
• Falls bexp == true, führe s_true aus
• Falls bexp == false und else-Fall vorhanden, führe s_false aus
• Oft sind s_true und s_false Anweisungsblöcke
• If-Anweisungen treten auch in Kaskaden auf:
i f ( bexp1 ) {
...
} e l s e i f ( bexp2 ) {
...
} e l s e i f ( bexp3 ) {
...
} e l s e { // o t h e r w i s e
...
}
RT (ICS @ UIBK)
Programmiermethodik
55/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Beispiel If-Anweisung
s t a t i c S t r i n g toRoman ( i n t x ) {
String result ;
i f ( x == 1 ) r e s u l t = "I" ;
e l s e i f ( x == 5 ) r e s u l t = "V" ;
e l s e i f ( x == 1 0 ) r e s u l t = "X" ;
e l s e i f ( x == 5 0 ) r e s u l t = "L" ;
e l s e i f ( x == 1 0 0 ) r e s u l t = "C" ;
e l s e i f ( x == 5 0 0 ) r e s u l t = "D" ;
e l s e i f ( x == 1 0 0 0 ) r e s u l t = "M" ;
e l s e i f ( x == 5 0 0 0 ) r e s u l t = "A" ;
e l s e r e s u l t = " unbekannt " ;
return r e s u l t ;
}
RT (ICS @ UIBK)
Programmiermethodik
56/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Dangling Else
• Betrachte if (b1) if (b2) s1 else s2
• Problem: zu welchem if gehört das else?
•
if (b1) { if (b2) s1 else s2} oder if (b1) { if (b2) s1} else s2
• Festlegung: else gehört zum letztes freien if (was kein else hat)
⇒ if (b1) if (b2) s1 else s2 = if (b1) { if (b2) s1 else s2}
RT (ICS @ UIBK)
Programmiermethodik
57/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Switch
• Alternative zu If-Kaskaden, Form:
swi tch ( exp ) {
case V a l u e 1 : s t m t s 1 ; break ;
case V a l u e 2 : s t m t s 2 ; break ;
...
case ValueN : stmtsN ; break ;
default : stmts ;
}
• alle Werte Value1, ..., ValueN müssen verschieden sein
• der default-Teil und die break-Anweisungen sind optional
• Semantik
• Ausdruck exp wird ausgewertet, liefert Wert w
• Falls w einem ValueI entspricht, werden die Anweisungen stmtsI
ausgeführt
• Falls w keinem der Werte entspricht, werden (falls vorhanden) die
default-Anweisungen stmts ausgeführt
RT (ICS @ UIBK)
Programmiermethodik
58/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Beispiel Switch-Anweisung
s t a t i c S t r i n g toRomanSwitch ( i n t x ) {
String result ;
swi tch ( x ) {
case 1 : r e s u l t = "I" ; break ;
case 5 : r e s u l t = "V" ; break ;
case 1 0 : r e s u l t = "X" ; break ;
case 5 0 : r e s u l t = "L" ; break ;
case 1 0 0 : r e s u l t = "C" ; break ;
case 5 0 0 : r e s u l t = "D" ; break ;
case 1 0 0 0 : r e s u l t = "M" ; break ;
case 5 0 0 0 : r e s u l t = "A" ; break ;
d e f a u l t : r e s u l t = " unbekannt " ;
}
return r e s u l t ;
}
RT (ICS @ UIBK)
Programmiermethodik
59/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Wozu break in switch?
swi tch ( exp ) {
case V a l u e 1 : s t m t s 1 ; break ;
...
case ValueN : stmtsN ; break ;
default : stmts ;
}
• die einzelnen Fälle werden als Sprungmarken interpretiert:
springe in die entsprechende Zeile
• nach Sprung führe normale Anweisungsliste aus
• ohne break würden immer alle nachfolgenden Fälle mit ausgeführt!
• erlaubt Zusammenfassung von Fällen, Beispiel:
swi tch ( 4 ) {
case 4 : case 5 : x ∗= 2 ; // w i r d a u s g e f u e h r t
case 7 : x += 9 ; break ; // w i r d a u s g e f u e h r t
default : x = 0;
// w i r d n i c h t a u s g e f .
}
RT (ICS @ UIBK)
Programmiermethodik
60/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Vergleich If und Switch
• Effizienz (mittlere Anzahl von Vergleichen bei n verschiedenen Fällen)
• switch: zwischen konstant und log (n)
• if -Kaskade: im Mittel n2
• Grund: switch wird intern mittels Tabelle implementiert
• Flexibilität
• if : beliebige boolesche Ausdrücke
• switch: Test auf Konstanten mit folgenden Typen byte, short, int,
char oder String (kein boolean, long, float oder double)
⇒ jedes switch kann durch if -Kaskade simuliert werden
⇒ if -Kaskade kann i.A. nicht durch ein switch simuliert werden
RT (ICS @ UIBK)
Programmiermethodik
61/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Schleifen
• erlauben wiederholte Ausführung eines Programmteils
• in Java 3 Varianten
• while (bexp) { stmts; }
1. Evaluiere bexp
2a. Wenn Resultat true ist, dann führe stmts; aus und springe nach 1
2b. Sonst fahre mit Ausführung nach Schleife fort
• do { stmts; } while (bexp);
1. Führe stmts; aus
2. Evaluiere bexp
3a. Wenn Resultat true ist, dann springe nach 1
3b. Sonst fahre mit Ausführung nach Schleife fort
• for ( initStmt ; bexp; iterateStmt ) { stmts; }
1. Führe initStmt ; aus
2. Evaluiere bexp
3a. Bei Resultat true, führe stmts; iterateStmt ; aus, springe nach 2
3b. Sonst fahre mit Ausführung nach Schleife fort
• { stmts; } kann durch einzelne Anweisung stmt; ersetzt werden
• jede Variante kann durch jede andere Variante simuliert werden
RT (ICS @ UIBK)
Programmiermethodik
62/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Beispiel: Fibonacci-Zahlen


wenn n = 0
0,
• fib(n) = 1,
wenn n = 1


fib(n − 1) + fib(n − 2), sonst
• rekursive Lösung einfach, aber ineffizient
s t a t i c long f i b R e c ( i n t
r e t u r n ( n == 0 ? 0
( n == 1 ? 1
fibRec (n −
}
RT (ICS @ UIBK)
n) {
:
:
1) + f i b R e c ( n − 2 ) ) ) ;
Programmiermethodik
63/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Beispiel: Fibonacci-Zahlen
• mittels while-Schleife
s t a t i c long f i b W h i l e ( i n t n ) {
int i = 0;
long f i b I = 0 ; // v a l u e o f f i b ( i )
long f i b I 1 = 1 ; // v a l u e o f f i b ( i +1);
while ( i < n ) {
long o l d F i b I = f i b I ;
fibI = fibI1 ;
fibI1 = oldFibI + fibI1 ;
i ++;
}
return f i b I ;
}
RT (ICS @ UIBK)
Programmiermethodik
64/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Beispiel: Fibonacci-Zahlen
• mittels do ... while-Schleife
s t a t i c long f i b D o W h i l e ( i n t n ) {
i f ( n == 0 ) r e t u r n 0 ;
int i = 0;
long f i b I = 0 ;
long f i b I 1 = 1 ;
do {
long o l d F i b I = f i b I ;
fibI = fibI1 ;
fibI1 = oldFibI + fibI1 ;
i ++;
} while ( i < n ) ;
return f i b I ;
}
RT (ICS @ UIBK)
Programmiermethodik
65/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Beispiel: Fibonacci-Zahlen
• mittels for-Schleife
s t a t i c long f i b F o r ( i n t n )
{
long f i b I = 0 ;
long f i b I 1 = 1 ;
f o r ( i n t i = 0 ; i < n ; i ++) {
long o l d F i b I = f i b I ;
fibI = fibI1 ;
fibI1 = oldFibI + fibI1 ;
}
return f i b I ;
}
RT (ICS @ UIBK)
Programmiermethodik
66/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Continue und Break innerhalb von Schleifen
• break; verlässt die Schleife vorzeitig
• continue; springt direkt zum Schleifende (hinter stmts;)
• Beispiel:
f o r ( i n t i = 1 ; i <= 1 0 ; i ++) {
i f ( i == 3 ) continue ;
i ++;
i f ( i == 9 ) break ;
System . o u t . p r i n t ( i + " " ) ;
}
• continue und break . . .
• können durch entsprechende Umformulierung eliminiert werden
• können übermäßige Verschachtelung vermeiden
• sollten sparsam verwendet werden (Lesbarkeit)
RT (ICS @ UIBK)
Programmiermethodik
67/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Beispiel mit und ohne Continue und Break
int i ;
f o r ( i = 1 ; i <= 1 0 ; i ++) {
i f ( i == 3 ) c o n t i n u e ;
i ++;
i f ( i == 9 ) break ;
System . o u t . p r i n t ( i + " " ) ;
}
int i ;
boolean c o n t = t r u e ;
f o r ( i = 1 ; i <= 10 && c o n t ; ) {
i f ( i != 3 ) {
i ++;
i f ( i == 9 ) c o n t = f a l s e ;
e l s e System . o u t . p r i n t ( i + " " ) ;
}
i f ( c o n t ) i ++;
}
RT (ICS @ UIBK)
Programmiermethodik
68/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Übersicht
Einführung in Java
Historie und Features
Grundlegende Elemente eines Java Programms (ohne OO)
Datentypen
Ausdrücke
Anweisungen
Arrays
Methoden
RT (ICS @ UIBK)
Programmiermethodik
69/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Arrays
• Zusammenfassung gleichartiger Elemente
• Arrays haben fixe Länge
• Länge ist nicht-negativer int-Wert
⇒ Nicht mehr als 2.147.483.647 Elemente
• Länge wird bei Erzeugung fixiert
• Arrayvariablen sind Referenzvariablen
• Jedem Element ist Index vom Typ int zugewiesen
• Index im Bereich 0, . . . , Länge-1
• Mehrdimensionale Arrays möglich
RT (ICS @ UIBK)
Programmiermethodik
70/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Deklaration von Arrays
• [] ist Postfix-Typ Konstruktor
• für jeden Typ type, ist type [] der Typ der Arrays mit Elementen vom
Typ type
• Beispiele:
• int [] : Typ der Arrays von Integers
• String [] : Typ der Arrays von Strings
• double [][] : Typ der Arrays von Arrays von Doubles
= Matrizen von Doubles
(Array von Spaltenvektoren oder Array von Zeilenvektoren)
• Deklaration wie üblich: int [] xs , ys ; String [][] foo;
• oder in Postfix Notation: int x, xs [], matrix [][];
• übliche Deklaration bevorzugt: einheitliches Deklarationsschema
type var1 , var2 , ...;
RT (ICS @ UIBK)
Programmiermethodik
71/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Erzeugung von Arrays
• Erzeugung bei Deklaration int [] arr = new int[10];
• Spätere Erzeugung
int [ ] arr ;
...
a r r = new i n t [ 1 0 ] ;
• Arrayelemente haben zunächst alle Wert
• 0 – bei Arrays von Zahlen
• ’\u0000’ – bei Arrays von Zeichen
• false – bei Arrays von Booleans
• null – bei allen anderen Arrays (null = Referenz auf nichts)
• Länge des Arrays: arr . length
• Anlegen von mehrdimensionalen Arrays: später
RT (ICS @ UIBK)
Programmiermethodik
72/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Erzeugung von Arrays mit Initialisierung
• Erzeugung bei Deklaration int [] arr = {3, x + y, 3, 2, 1};
• Spätere Erzeugung
String [ ] arr ;
...
a r r = new S t r i n g [ ] { "foo" , h e l l o + w o r l d , "bar" } ;
• Länge des Arrays = Anzahl der angegebenen Elemente
RT (ICS @ UIBK)
Programmiermethodik
73/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Zugriff auf Elemente
• Elemente werden mittels Index addressiert
• Index kann beliebiger Ausdruck exp sein, solange Typ mit int
kompatibel ist
• Syntax mittels eckigen Klammern: someArray[exp]
• Lese- und Schreibzugriff möglich
• someArray[5] = 7;
• x = someArray[y] − 3;
• someArray[y − x] += 17;
• Wert des Index muss innerhalb des Indexbereichs (0, . . . ,
someArray.length − 1) liegen
• Ansonsten gibt es Laufzeitfehler, d.h. Programm-Abbruch
RT (ICS @ UIBK)
Programmiermethodik
74/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Zuweisung und Vergleich von Arrays
• Arrayvariable ist Referenz auf eigentliches Array
• Bei Zuweisung wird nur Referenz kopiert, nicht das eigentliche Array
• Beispiel: int [] a, b; a = new int[] {1,2,3}; b = a; b [1] = 5;
a
b
RT (ICS @ UIBK)
Programmiermethodik
75/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Zuweisung und Vergleich von Arrays
• Arrayvariable ist Referenz auf eigentliches Array
• Bei Zuweisung wird nur Referenz kopiert, nicht das eigentliche Array
• Beispiel: int [] a, b; a = new int[] {1,2,3}; b = a; b [1] = 5;
a
1
2
3
b
RT (ICS @ UIBK)
Programmiermethodik
75/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Zuweisung und Vergleich von Arrays
• Arrayvariable ist Referenz auf eigentliches Array
• Bei Zuweisung wird nur Referenz kopiert, nicht das eigentliche Array
• Beispiel: int [] a, b; a = new int[] {1,2,3}; b = a; b [1] = 5;
a
1
2
3
b
RT (ICS @ UIBK)
Programmiermethodik
75/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Zuweisung und Vergleich von Arrays
• Arrayvariable ist Referenz auf eigentliches Array
• Bei Zuweisung wird nur Referenz kopiert, nicht das eigentliche Array
• Beispiel: int [] a, b; a = new int[] {1,2,3}; b = a; b [1] = 5;
a
1
5
3
b
RT (ICS @ UIBK)
Programmiermethodik
75/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Zuweisung und Vergleich von Arrays
• Arrayvariable ist Referenz auf eigentliches Array
• Bei Zuweisung wird nur Referenz kopiert, nicht das eigentliche Array
• Beispiel: int [] a, b; a = new int[] {1,2,3}; b = a; b [1] = 5;
a
1
5
3
b
• == ist Referenzvergleich wie bei Strings, nicht Wertevergleich!
• Beispiel:
int [] a = {1,2}, b = {1,2}; boolean c = a == b; //c == false
RT (ICS @ UIBK)
Programmiermethodik
75/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Zuweisung von Arrays (fortgesetzt)
• Einschränkung bei Zuweisung von Arrays
• Arrays müssen gleichen Typ haben; keine implizite Typanpassung!
• int [] as , bs, cs ; ...; as = x > 3 ? bs : cs ; // okay
•
int [] is ; byte[] bs; ...; is = bs; // nicht okay
•
int [] is ; byte[] bs; ...; bs = is ; // nicht okay
• Gründe
i n t [ ] i s ; byte [ ] b s = { 1 0 } ; i s = b s ;
i s [ 0 ] = 1 0 0 0 ; // n i c h t a u s r e i c h e n d P l a t z
i n t [ ] i s = { 1 0 0 0 } ; byte [ ] b s ; b s = i s ;
byte b = bs [ 0 ] ; // i m p l i z i t e Typanpassung
RT (ICS @ UIBK)
Programmiermethodik
76/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Iterieren über Arrays
• Beispiel: Kopieren eines Arrays
int orig [ ] ; . . .
i n t copy [ ] = new i n t [ o r i g . l e n g t h ] ;
f o r ( i n t i = 0 ; i < o r i g . l e n g t h ; i ++)
copy [ i ] = o r i g [ i ] ;
• Beispiel: Ausgabe eines Arrays
f o r ( i n t i = 0 ; i < a r r a y . l e n g t h ; i ++)
System . o u t . p r i n t ( a r r a y [ i ] + " " ) ;
• Wenn man nur über die Elemente iterieren will, gibt es komfortable
Iterator-Form ( for (type elemVariable : array ) { stmts; } )
f o r ( i n t elem : a r r a y )
System . o u t . p r i n t ( elem + " " ) ;
RT (ICS @ UIBK)
Programmiermethodik
77/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Beispiel: Sieb des Eratosthenes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static int [ ] primes ( int n) {
boolean [ ] i s P r i m e = new boolean [ n + 1 ] ;
f o r ( i n t i = 2 ; i <= n ; i ++)
isPrime [ i ] = true ;
f o r ( i n t i = 2 ; i ∗ i <= n ; i ++)
i f ( isPrime [ i ])
f o r ( i n t j = i + i ; j <= n ; j += i )
isPrime [ j ] = false ;
int nrPrimes = 0;
f o r ( boolean b : i s P r i m e )
i f ( b ) n r P r i m e s ++;
i n t [ ] p r i m e s = new i n t [ n r P r i m e s ] ;
i n t count = 0;
f o r ( i n t i = 2 ; i <= n ; i ++)
i f ( isPrime [ i ]) {
p r i m e s [ c o u n t ] = i ; c o u n t ++;
}
return primes ;
}
RT (ICS @ UIBK)
Programmiermethodik
78/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Freigabe des Speichers (Arrays, Strings, Objekte)
• Freigabe erfolgt durch das System, nicht durch separate Anweisung
• Wenn wenig freier Speicher vorhanden, wird Garbage Collector aktiv
• nicht mehr erreichbare Speicherbereiche werden erfasst und freigegeben
• Erreichbarkeit kann unterbunden werden
• Zuweisung der null-Referenz (die auf nichts zeigt): arr = null;
• Zuweisung eines anderen Wertes: arr = otherArr;
RT (ICS @ UIBK)
Programmiermethodik
79/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Freigabe des Speichers: Beispiel
S t r i n g [ ] a , b ; S t r i n g s = "bar" ;
a = new S t r i n g [ ] { "foo" , s } ;
b = new S t r i n g [ ] { s , "com" , "dot" } ;
b [1] = null ;
a [1] = null ;
b = a;
a
b
s
"bar"
RT (ICS @ UIBK)
Programmiermethodik
80/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Freigabe des Speichers: Beispiel
S t r i n g [ ] a , b ; S t r i n g s = "bar" ;
a = new S t r i n g [ ] { "foo" , s } ;
b = new S t r i n g [ ] { s , "com" , "dot" } ;
b [1] = null ;
a [1] = null ;
b = a;
a
b
•
•
s
"foo"
RT (ICS @ UIBK)
"bar"
Programmiermethodik
80/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Freigabe des Speichers: Beispiel
S t r i n g [ ] a , b ; S t r i n g s = "bar" ;
a = new S t r i n g [ ] { "foo" , s } ;
b = new S t r i n g [ ] { s , "com" , "dot" } ;
b [1] = null ;
a [1] = null ;
b = a;
a
b
•
•
•
•
•
s
"foo"
RT (ICS @ UIBK)
"bar"
Programmiermethodik
"com"
"dot"
80/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Freigabe des Speichers: Beispiel
S t r i n g [ ] a , b ; S t r i n g s = "bar" ;
a = new S t r i n g [ ] { "foo" , s } ;
b = new S t r i n g [ ] { s , "com" , "dot" } ;
b [1] = null ;
a [1] = null ;
b = a;
a
b
•
•
•
•
•
s
"foo"
RT (ICS @ UIBK)
"bar"
Programmiermethodik
"com"
"dot"
80/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Freigabe des Speichers: Beispiel
S t r i n g [ ] a , b ; S t r i n g s = "bar" ;
a = new S t r i n g [ ] { "foo" , s } ;
b = new S t r i n g [ ] { s , "com" , "dot" } ;
b [1] = null ;
a [1] = null ;
b = a;
a
b
•
•
•
•
•
s
"foo"
RT (ICS @ UIBK)
"bar"
Programmiermethodik
"dot"
80/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Freigabe des Speichers: Beispiel
S t r i n g [ ] a , b ; S t r i n g s = "bar" ;
a = new S t r i n g [ ] { "foo" , s } ;
b = new S t r i n g [ ] { s , "com" , "dot" } ;
b [1] = null ;
a [1] = null ;
b = a;
a
b
•
•
•
•
•
s
"foo"
RT (ICS @ UIBK)
"bar"
Programmiermethodik
"dot"
80/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Freigabe des Speichers: Beispiel
S t r i n g [ ] a , b ; S t r i n g s = "bar" ;
a = new S t r i n g [ ] { "foo" , s } ;
b = new S t r i n g [ ] { s , "com" , "dot" } ;
b [1] = null ;
a [1] = null ;
b = a;
a
b
•
•
•
•
•
s
"foo"
RT (ICS @ UIBK)
"bar"
Programmiermethodik
"dot"
80/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Freigabe des Speichers: Beispiel
S t r i n g [ ] a , b ; S t r i n g s = "bar" ;
a = new S t r i n g [ ] { "foo" , s } ;
b = new S t r i n g [ ] { s , "com" , "dot" } ;
b [1] = null ;
a [1] = null ;
b = a;
a
b
•
•
s
"foo"
RT (ICS @ UIBK)
"bar"
Programmiermethodik
"dot"
80/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Freigabe des Speichers: Beispiel
S t r i n g [ ] a , b ; S t r i n g s = "bar" ;
a = new S t r i n g [ ] { "foo" , s } ;
b = new S t r i n g [ ] { s , "com" , "dot" } ;
b [1] = null ;
a [1] = null ;
b = a;
a
b
•
•
s
"foo"
RT (ICS @ UIBK)
"bar"
Programmiermethodik
80/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Mehrdimensionale Arrays
• Arrays können beliebig viele Dimensionen haben.
• Beispiel: 2-dimensionales Array
•
int [][] matrix = new int [3][2];
•
int [][] matrix2 = { { 1, 2 }, { 3, 4 }, { 5, 6 } };
•
int [][] matrix3 = new int [3][]; // = new int [][]{ null , null , null }
• Zugriff
• x = matrix2 [1][0]; // 3
•
arr = matrix2 [2]; // [5,6]
• Realisierung in Java
matrix2
•
1
RT (ICS @ UIBK)
2
•
•
3
4
5
Programmiermethodik
6
81/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Beispiel: Pascalsches Dreieck
• erzeugt nicht-rechteckiges, 2-dimensionales Array
• k-te Zeile = Koeffizienten von (x + y )k
• 3. Zeile = 1 3 3 1 ⇒ (x + y )3 = 1 · x 3 y 0 + 3 · x 2 y 1 + 3 · x 1 y 2 + 1 · x 0 y 3
1 static int [ ] [ ] pascal ( int n) {
2
i n t p [ ] [ ] = new i n t [ n ] [ ] ;
3
f o r ( i n t i = 0 ; i < n ; i ++) {
4
p [ i ] = new i n t [ i + 1 ] ;
5
f o r ( i n t j = 0 ; j <= i ; j ++) {
6
i f ( ( j == 0 ) | | ( j == i ) ) {
7
p [ i ] [ j ] = 1;
8
} else {
9
p [ i ] [ j ] = p [ i − 1 ] [ j − 1] + p [ i − 1 ] [ j ] ;
10
}
11
}
12
}
13
return p ;
14 }
RT (ICS @ UIBK)
Programmiermethodik
82/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Übersicht
Einführung in Java
Historie und Features
Grundlegende Elemente eines Java Programms (ohne OO)
Datentypen
Ausdrücke
Anweisungen
Arrays
Methoden
RT (ICS @ UIBK)
Programmiermethodik
83/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Unterprogramme
• Teile eines Programms können an einer anderen Stelle als
Unterprogramm formuliert werden
• Unterprogramme können in Anweisungsfolge oder Ausdruck aufgerufen
werden
•
•
•
•
Verzweigung zum Unterprogramm
Abarbeitung des Unterprogramms
Nach Abarbeitung Rückkehr zur Aufrufstelle
Eventuell Ergebnis weiterverwenden
RT (ICS @ UIBK)
Programmiermethodik
84/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Arten von Unterprogrammen
Gebe Pascal’s Dreieck aus
Unterscheidung nach Aufgabe
• Prozeduren
• Unterprogramme, die Anweisungen (mit Seiteneffekt) ausführen
• kein Rückgabewert (in Java: void)
• Funktionen
• Unterprogramme, die Anweisungen ausführen
• mit Rückgabewert (in Java: type 6= void)
Unterscheidung nach Zugehörigkeit
• Unterprogramme
Liefere Pascal’s Dreieck als Array
• Eigenständiger Teil des Programms
• C-Funktion
class Name { ... someMethod ...}
• Nicht in Java
• Methoden
• Gehören einer Klasse an
• Java-Methoden
RT (ICS @ UIBK)
Programmiermethodik
85/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Java Methoden
• in Java spricht man nur von Methoden
• in Vorlesung trotzdem manchmal Unterscheidung Prozedur / Funktion,
um Aufgabe klarzustellen
• zwei Arten von Methoden
• Statische Methoden
• Gehören zur Klasse
• Details in diesem Abschnitt
• gekennzeichnet mit Schlüsselwort static
• Objektbezogene Methoden
• später, im Kapitel über Objektorientierung
RT (ICS @ UIBK)
Programmiermethodik
86/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Struktur einer Methode
• Methode = Methodenkopf + Methodenrumpf
• Methodenkopf:
static returnType methodName (type1 parameterName1, ...)
• Methodenrumpf: { stmts; }
• Signatur einer Methode: Methodennamen + Parametertyp-Liste
• methodName(type1, ...)
•
•
•
•
formale Parameter = Namen der Parameter parameterName1, ...
aktueller Parameter = Werte beim Aufruf einer Methode
Aufruf von Methode initialisiert formale Param. mit aktuellen Param.
Beispiel
s t a t i c i n t f o o ( i n t x ) { // f o r m a l e r P a r a m e t e r : x
x ∗= 2 ;
r e t u r n ( x +5);
}
...
i n t y = f o o ( 5 + 3 ) ; // a k t u e l l e r P a r a m e t e r : 5 + 3
RT (ICS @ UIBK)
Programmiermethodik
87/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Arten der Parameterübergabe
static int foo ( int x ) {
x ∗= 2 ;
r e t u r n ( x +5);
}
Betrachte Aufruf foo(exp)
• Call-by-value
• exp wird ausgewertet zu einem Wert w
• Kopie von w wird an Methode übergeben
• Änderungen am formalen Parameter x ändert nichts am aktuellen
Parameter
• Call-by-reference
• exp muss eine Referenz sein (z.B. Variable, kein foo(2) möglich)
• Änderungen am formalen Parameter x ändern aktuellen Parameter
• Beispiel: int x = 1; int y = foo(x); int z = foo(x);
• Call-by-value:
x = ,y = ,z =
• Call-by-reference: x = , y = , z =
RT (ICS @ UIBK)
Programmiermethodik
88/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Parameterübergabe in Java
• immer call-by-value!
• bei Parameterübergabe wird Kopie überzeugt
• es gelten Kompatibilitätsregeln:
Typ eines aktuellen Parameters muss durch implizite Typanpassung in
Typ des formalen Parameters konvertiert werden können
• void foo(int x) { long y = 0; foo(y ); } // nicht okay
• void foo(long x) { int y = 0; foo(y ); } // okay
• void foo( String x) { int y = 0; foo(y ); } // nicht okay
(implizite Typanpassung nach String nur bei + !)
RT (ICS @ UIBK)
Programmiermethodik
89/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Parameterübergabe von Referenzen
• Kopie ist nicht gleich Kopie
• Kopie von Basisdatentyp = Kopie des Wertes
• nichts kann verändert werden
• Kopie von anderen Typen = Kopie der Referenz
• Referenz kann nicht verändert werden
• das referenzierte Objekt kann aber verändert werden
RT (ICS @ UIBK)
Programmiermethodik
90/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Beispiel Übergabe von Referenzen
s t a t i c void t e s t ( ) {
int [ ] x = {4 ,5 ,6};
int [ ] y = x ;
System . o u t . p r i n t l n ( sum ( y ) ) ; // 15
System . o u t . p r i n t l n ( x == y ) ; // t r u e
// x =
// y =
}
s t a t i c i n t sum ( i n t [ ] a ) {
f o r ( i n t i = 1 ; i < a . l e n g t h ; i ++)
a [ 0 ] += a [ i ] ;
return a [ 0 ] ;
}
RT (ICS @ UIBK)
Programmiermethodik
91/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Rückgabewert von Funktionen
•
•
•
•
mittels return exp;
führen zum direktem Abbruch der Funktion
return; zum vorzeitigen Abbruch in einer Prozedur
Beispiele:
static int fact ( int n) {
r e t u r n ( n <= 1 ? 1 : n ∗ f a c t ( n − 1 ) ) ;
}
s t a t i c v o i d p r i n t F i l e ( S t r i n g name ) {
boolean f i l e O p e n e d ;
. . . // t r y t o open f i l e w i t h name
i f (! fileOpened ) {
return ;
}
. . . // p r i n t c o n t e n t o f f i l e and c l o s e i t
}
RT (ICS @ UIBK)
Programmiermethodik
92/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Lokale und globale Variablen
• lokale Variablen
• sind Parameter und Variablen, die innerhalb Methode deklariert werden
• sind nicht in anderen Methoden(aufrufen) sichtbar
• Lebensdauer:
• werden angelegt, wenn Methode aufgerufen wird
• werden freigegeben, wenn Methode verlassen wird
• globale Variablen (Klassenvariablen)
• sind in jeder Methode der Klasse sichtbar
• werden mit Standard-Werten initialisiert (0, false , null)
• Lebensdauer:
• werden angelegt, wenn Klasse erstmalig genutzt wird
• werden freigegeben, wenn Programm beendet wird
c l a s s MyClass {
s t a t i c i n t g l o b a l V a r = 5 ; s t a t i c boolean g l o b a l B o o l ;
s t a t i c void foo ( ) {
int localVar = 3;
i f ( g l o b a l B o o l ) { g l o b a l V a r ++; } . . .
}
}
RT (ICS @ UIBK)
Programmiermethodik
93/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Verwendung lokaler / globaler Variablen
• Wenn möglich, Variablen immer lokal deklarieren
• keine Namenskonflikte mit anderen Methoden
• keine Probleme bei Veränderung einer gemeinsam genutzten globalen
Variable
• Globale Variablen verwenden, wenn Wert über mehrere
Methoden-Aufrufe hinweg verfügbar sein muss
RT (ICS @ UIBK)
Programmiermethodik
94/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Beispiel: globale Variablen für statistische Zwecke
class Fibonacci {
s t a t i c int count ;
static int f i b ( int n) {
c o u n t ++;
r e t u r n ( n == 0 ? 0 : ( n == 1 ? 1 :
f i b ( n − 1) + f i b ( n − 2 ) ) ) ;
}
s t a t i c void t e s t ( i n t n ) {
count = 0;
fib (n );
System . o u t . p r i n t l n ( "To compute fib(" + n + "), "
+ "we invoked fib " + c o u n t + " many times " ) ;
}
}
RT (ICS @ UIBK)
Programmiermethodik
95/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Überladen von Methoden
• Idee: benutze gleichen Methodennamen für unterschiedliche Parameter
• Bereits bekannt bei Operatoren: "a" + "b" , 3 + 2 , − x , x − y
• in Java: gleicher Methodenname gestattet, solange Signatur
unterschiedlich ist
(Erinnerung: Signatur = Methodenname + Liste der Parametertypen)
•
•
•
•
Unterschied in Typen,
Unterschied in Reihenfolge der Typen, oder
Unterschied in Anzahl der Parameter
(Rückgabewert spielt keine Rolle beim Überladen)
• falls gleicher Methodenname mindestens zweimal verwendet wurde,
nennt man diese Methoden überladen
RT (ICS @ UIBK)
Programmiermethodik
96/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Beispiel: Überladen
s t a t i c v o i d f o o ( i n t x ) { System . o u t . p r i n t l n ( "i" ) ; }
s t a t i c v o i d f o o ( double x ) { . . . "d" ) ; }
s t a t i c v o i d f o o ( i n t x , i n t y ) { . . . "ii" ) ; }
s t a t i c v o i d f o o ( i n t x , double y ) { . . . "id" ) ; }
s t a t i c v o i d f o o ( double x , i n t y ) { . . . "di" ) ; }
s t a t i c v o i d f o o ( char x , long y , i n t z ) { . . . "cli" ) ; }
s t a t i c v o i d f o o ( char x , i n t y , long z ) { . . . "cil" ) ; }
s t a t i c void t e s t ( ) {
foo (10);
f o o ( 1 0D ) ;
f o o ( 1 0 , ’a’ ) ;
f o o ( 1 0 , 10D ) ;
foo (10F , 1 0 ) ;
f o o ( ’a’ , 1 0 , 1 0 ) ;
}
RT (ICS @ UIBK)
Programmiermethodik
97/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Methoden mit variabler Parameteranzahl
• normalerweise haben Methode festen Anzahl von Parametern
• manchmal beliebige Anzahl von Parametern eines Typs komfortabel
• herkömmliche Lösung mittels Arrays:
static int sum(int[] values ) { stmts; }
• komfortable Lösung mittels varargs-Parameter “...”
static int sum(int ... values ) { stmts; }
• innerhalb der Methode kann values wie Array-Typ behandelt werden
⇒ Anweisungen in beiden sum-Methoden ist identisch
• varargs-Parameter muss immer an letzter Stelle stehen
• beim Aufruf wird intern ein Array erstellt: int x = sum(1,2,y,7); ⇒
int x = sum(new int[]{1,2,y,7});
RT (ICS @ UIBK)
Programmiermethodik
98/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Beispiel: Varargs (+ Überladen)
s t a t i c void p r i n t ( i n t i , i n t j ) {
System . o u t . p r i n t l n ( " Integer " + i + " " + j ) ;
}
s t a t i c void p r i n t ( i n t i , i n t . . . v a l u e s ) {
System . o u t . p r i n t ( " Integer " + i + ", " ) ;
System . o u t . p r i n t l n ( "# Varargs : " + v a l u e s . l e n g t h ) ;
}
s t a t i c i n t sum ( i n t . . . v a l u e s ) {
int r e s u l t = 0;
for ( int x : values )
r e s u l t += x ;
return r e s u l t ;
}
...
System . o u t . p r i n t l n ( sum ( 1 , 2 , 3 ) ) ;
System . o u t . p r i n t l n ( sum ( 1 , 2 , 3 , 4 , 5 ) ) ;
System . o u t . p r i n t l n ( sum ( ) ) ;
print (1);
p r i n t (1 , 2);
p r i n t (1 , 2 , 3);
RT (ICS @ UIBK)
Programmiermethodik
99/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Vordefinierte Methoden und Konstanten
• Java bietet etliche statische Methoden in Bibliothek an
• gehören zur Klasse
• typischer Aufruf: ClassName.methodName(...)
• Beispiel: Math.sqrt(10.0) , . . .
• neben statischen Methoden gibt es auch globale Konstanten (und
deren Methoden)
• typische Aufrufe: ClassName.CONSTANT_NAME und
ClassName.objectName.methodName(...)
• Beispiel: Math.PI , System.out. println (7) , . . .
RT (ICS @ UIBK)
Programmiermethodik
100/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Beispiele für Klassenmethoden und Konstanten
• System
• System.out. println (...) , System.err . println (...) , . . .
• Math
• Math.random() , Math.sin(double) , Math.E , . . .
• Integer
•
Integer .MAX_VALUE , Integer .MIN_VALUE , . . .
• Arrays
• viele überladene Methoden (hier für short)
• Arrays .copyOf(short [], int length)
• Arrays . equals(short [], short [])
• Arrays . binarySearch(short [], short key)
• Arrays . sort (short [])
• Arrays . toString (short [])
RT (ICS @ UIBK)
Programmiermethodik
101/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Importieren von Klassen (Kurzversion)
• manche Klassen sind immer verfügbar (Math, System, String, . . . )
• andere müssen erst importiert werden
• 2 Möglichkeiten zum Import:
• zu Beginn (am Anfang der Datei)
• import java . util . Arrays ; // Klasse Arrays im Paket java . util
• import java . util .∗; // alles aus java . util
•
... int [] x = Arrays.copyOf(y, y. length ); ...
• direkt im Code (auch zur Auflösung von Mehrdeutigkeiten)
•
RT (ICS @ UIBK)
... int [] x = java. util . Arrays .copyOf(y, y. length ); ...
Programmiermethodik
102/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Beispiel: Import von Klassen
import j a v a . u t i l . A r r a y s ; // i m p o r t kommt v o r c l a s s
class ArrayTest {
s t a t i c void t e s t ( ) {
double [ ] a = { 1 . 5 , Math . c o s ( Math . PI ) , 0 } ;
double [ ] b = {−1, 0 , 1 . 5 } ;
Arrays . sort (a ) ;
System . o u t . p r i n t l n ( a == b ) ;
System . o u t . p r i n t l n ( A r r a y s . e q u a l s ( a , b ) ) ;
System . o u t . p r i n t l n ( a ) ;
System . o u t . p r i n t l n ( A r r a y s . t o S t r i n g ( a ) ) ;
System . o u t . p r i n t l n ( Math . s i n ( Math . PI ) ) ;
}
}
RT (ICS @ UIBK)
Programmiermethodik
...
103/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Dokumentation der Klassen
• Startpunkt: API-Dokumentation
http://docs.oracle.com/javase/7/docs/api/
• Informationen
• für jedes Paket
• Liste der Klassen
• für jede Klasse
• Beschreibung der Klasse
• Liste der Methoden
• für jede Methode
• Kurzbeschreibung im Überblick
• Längere Beschreibung mit Erklärung der Parameter, . . .
RT (ICS @ UIBK)
Programmiermethodik
104/613
Einführung in Java
Grundlegende Elemente eines Java Programms (ohne OO)
Nutzen von Methoden
• Wiederverwendung von Code
• Ausgliedern häufig benutzter Programmteile
• spart Schreibarbeit
• macht Programme kürzer
• Definition benutzerspezifischer Operationen
• Programmiersprache “anpassen”
• Strukturierung von Programmen
• Zusammenfassen von Anweisungen, die logisch zusammengehören
• Erleichtert Programmverständnis
RT (ICS @ UIBK)
Programmiermethodik
105/613
Objektorientierung
Übersicht
Objektorientierung
Allgemeine Grundlagen
Objekte und Klassen
Objekte, Klassen und Methoden in Java
String-Klasse
Wrapper-Klassen
RT (ICS @ UIBK)
Programmiermethodik
106/613
Objektorientierung
Allgemeine Grundlagen
Übersicht
Objektorientierung
Allgemeine Grundlagen
Objekte und Klassen
Objekte, Klassen und Methoden in Java
String-Klasse
Wrapper-Klassen
RT (ICS @ UIBK)
Programmiermethodik
107/613
Objektorientierung
Allgemeine Grundlagen
Motivation
• Bisher: Datentypen, Anweisungen, Arrays, Unterprogramme
• Anwendung: Algorithmen implementieren, kleine Programme
• Problem: Große Programme
• mit bisherigen Mitteln machbar, aber nicht sinnvoll
• zu große Komplexität
• Komplexität (hier: nicht Laufzeit!)
• Schwierigkeiten
• Komplizierte Algorithmen
• Komplexe Software: Verknüpfung vieler Funktionen (die aber meist
einfach sind)
• Probleme bei Softwareentwicklung
• Viele Funktionen müssen organisiert werden
• Anforderung können sich ändern
RT (ICS @ UIBK)
Programmiermethodik
108/613
Objektorientierung
Allgemeine Grundlagen
Lösungen für Komplexität
• Beachte Prinzipien bei Programmierung
• Beispiele
• abgeschlossener Programmteil (Modul) hat nur eine Verantwortung
• Wiederholungen vermeiden
• Trennung von Schnittstelle und Implementierung
• Techniken der Objektorientierung unterstützen diese Prinzipien
• Einschränkung: Objektorientierung führt nicht automatisch zu besserer
Software
RT (ICS @ UIBK)
Programmiermethodik
109/613
Objektorientierung
Allgemeine Grundlagen
Grundelemente der Objektorientung
• Datenkapselung
• Vererbung
• Polymorphie
RT (ICS @ UIBK)
Programmiermethodik
110/613
Objektorientierung
Allgemeine Grundlagen
Datenkapselung
• In strukturierter Programmierung (z.B. C) sind Daten und Routinen
getrennt
• Objektorientierung verändert dies
•
•
•
•
Daten gehören zu einer Einheit (Objekt)
Direkter Zugriff ist nicht erlaubt (sollte nicht erlaubt sein)
Klar definierte Schnittstelle (Operationen) des Objekts wird verwendet
Objekt kann selbst für Konsistenz der Daten sorgen
⇒ Konsistenz der Daten ist gewährt
⇒ Anpassungen der internen Struktur benötigt keine Anpassung beim
Aufrufer
RT (ICS @ UIBK)
Programmiermethodik
111/613
Objektorientierung
Allgemeine Grundlagen
Ohne Datenkapselung
Aufrufer C
Probleme:
Aufrufer B
Änderung der internen
Darstellung angepasst
werden
radius *= 7;
x -= 7;
Aufrufer A
• bei Änderung der
internen Struktur ist evtl.
Konsistenz nicht
gewährleistet
x += 3;
int x;
int y;
int radius;
RT (ICS @ UIBK)
• Alle Aufrufe müssen bei
Programmiermethodik
112/613
Objektorientierung
Allgemeine Grundlagen
Mit Datenkapselung
Aufrufer C
Aufruf
Operation resize
Aufrufer B
radius *= 7;
x -= 7;
x += 3;
int x;
int y;
int radius;
RT (ICS @ UIBK)
Aufrufer A Aufruf
Aufruf
Operation move
Programmiermethodik
113/613
Objektorientierung
Allgemeine Grundlagen
Vererbung
• Vererbung von Spezifikation
• Gemeinsamkeiten werden in abstrakten Spezifikation zusammengefasst
• Klassen implementieren diese Spezifikation
• Vererbung von Implementierung
• Ermöglicht neue Klassen aus existierenden Klassen abzuleiten
• Es werden nur Unterschiede zwischen der abgeleiteten Klasse und der
Basisklasse angegeben
• Man spricht auch von
• Unterklasse (abgeleitete Klasse)
• Oberklasse (Basisklasse)
• Nutzen der Vererbung
• Ersparnis beim Programmieraufwand
• Vereinfachung von Programmänderungen
RT (ICS @ UIBK)
Programmiermethodik
114/613
Objektorientierung
Allgemeine Grundlagen
Polymorphie
• Polymorphie = Vielgestaltigkeit
• Bei Programmiersprachen
• Variable (oder Routine) kann abhängig von Verwendung
unterschiedliche Datentypen annehmen
• Ermöglicht flexible Software
RT (ICS @ UIBK)
Programmiermethodik
115/613
Objektorientierung
Allgemeine Grundlagen
Objektorientierung allgemein
• Objektorientierung: Paradigma für
• Analyse,
• Entwurf und
• Implementierung
von objektorientierten Systemen
• Teilaspekte sind
• Objektorientierte Analyse (OOA),
• Objektorientiertes Design (OOD) und
• Objektorientierte Programmierung (OOP)
• Hauptteil dieser Vorlesung
• Grundlagen der objektorientierten Programmierung (in Java)
• Einführung in das objektorientierte Design
RT (ICS @ UIBK)
Programmiermethodik
116/613
Objektorientierung
Allgemeine Grundlagen
OOA, OOD und OOP
• Objektorientierte Analyse
• Eingabe: informelle Anforderungen (vom Kunden)
• Ausgabe: konzeptuelles Modell (konkretisierte Anforderungen,
Ablaufdiagramme, grober Entwurf)
• Objektorientierte Design
• Eingabe: konzeptuelles Modell
• Ausgabe: konkretes Modell (detaillierte Aufbau des Systems,
Berücksichtigung von Seitenbedingungen wie Plattform,
Programmiersprache, . . . )
• Objektorientierte Programmierung
• Eingabe: konkretes Modell
• Ausgabe: Lauffähiger Code in objektorientierter Sprache
RT (ICS @ UIBK)
Programmiermethodik
117/613
Objektorientierung
Objekte und Klassen
Übersicht
Objektorientierung
Allgemeine Grundlagen
Objekte und Klassen
Objekte, Klassen und Methoden in Java
String-Klasse
Wrapper-Klassen
RT (ICS @ UIBK)
Programmiermethodik
118/613
Objektorientierung
Objekte und Klassen
Basis der Objektorientierung
• Objekt
• Objekt ist Bestandteil eines Programms
• Objekt enthält Zustände
• Objekt stellt anderen Objekten Operationen zur Verfügung
• Objekt legt fest, wie es auf eine Operation reagiert
• Objekt ist Datenkapsel (engl. Encapsulation)
• Objekt bündelt Daten (Zustände) und Funktionalität (Operationen)
• Benutzer (Aufrufer) muss nur wissen was das Objekt macht
• Das wie ist nicht interessant (verringert Komplexität!)
RT (ICS @ UIBK)
Programmiermethodik
119/613
Objektorientierung
Objekte und Klassen
Datenkapsel
• Objekt hat Eigenschaften
• Beispiel: Stoppuhr speichert verstrichene Zeit und Status (läuft Zeit)
• Objekt besitzt Daten, die nur von ihm verändert werden (verstrichene
Zeit)
• Eigenschaften (Attribute)
• sind von außen erfragbar
• direkte Abfrage sollte aber vermieden werden
• können auf den Daten basieren oder errechnet werden (abgeleitete
Eigenschaften)
• Eigenschaften können voneinander abhängig sein
RT (ICS @ UIBK)
Programmiermethodik
120/613
Objektorientierung
Objekte und Klassen
Operationen (Methoden)
• Operationen
• Operationen spezifiziert Funktionalität eines Objekts
• Objekt sichert Aufrufer zu, dass bei Aufruf die Operation ausführt wird
• Schnittstelle = Menge der Operationen eines Objekts
• Realisierung von Operationen in Java: Methoden
• Geheimnisprinzip (information hiding)
• Daten sollten privat, Operationen (Methoden) öffentlich sein
• Klassen aus Daten und Methoden sind die Grundbausteine der
objektorientierten Programmierung
RT (ICS @ UIBK)
Programmiermethodik
121/613
Objektorientierung
Objekte und Klassen
Klassen
• Klasse beschreibt gemeinsame Eigenschaften und Operationen einer
Menge von gleichartigen Objekten
• Struktur und Verhalten der Objekte einer Klasse sind gleich
(unterscheiden sich nur in den Zuständen)
• Klassen stellen Konstruktionsplan für bestimmte Objekte dar
• In den meisten objektorientierten Programmiersprachen ist jedes Objekt
einer Klasse zugeordnet
• Klassifizierung
• Zuordnung von Objekten zu Klassen
• Relevante Gemeinsamkeiten von Objekten identifizieren
• Objekte mit Gemeinsamkeiten in eine Klasse geben
RT (ICS @ UIBK)
Programmiermethodik
122/613
Objektorientierung
Objekte und Klassen
Beispiel Klassifizierung (aus OOP, Lahmes und Rayman)
RT (ICS @ UIBK)
Programmiermethodik
123/613
Objektorientierung
Objekte und Klassen
Exemplare (Instanzen, instances)
• Objekte sind Exemplare der Klassen, zu denen sie gehören
• Klasse kann mehrere Exemplare haben
• Objekte können Exemplare mehrerer Klassen sein
• In vielen Programmiersprachen sind Objekte nur Exemplare einer Klasse
RT (ICS @ UIBK)
Programmiermethodik
124/613
Objektorientierung
Objekte und Klassen
Einfaches Beispiel
• Klasse Sparbuch
• Attribute/Eigenschaften: Kontonummer, Inhaber, Saldo
• Operationen: Einzahlen, Auszahlen
• Objekte (Exemplare von Klasse Sparbuch)
• SB1 = ein Sparbuch (129032, Amy Arm, 5,30 e)
• SB2 = ein Sparbuch (139010, Rudi Reich, 1.000.000,00 e)
• ...
• Beispiel Operation
• SB1.Einzahlen(300 e)
⇒ SB1 = ein Sparbuch (129032, Amy Arm, 305,30 e)
RT (ICS @ UIBK)
Programmiermethodik
125/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Übersicht
Objektorientierung
Allgemeine Grundlagen
Objekte und Klassen
Objekte, Klassen und Methoden in Java
String-Klasse
Wrapper-Klassen
RT (ICS @ UIBK)
Programmiermethodik
126/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Klassen
• Klassen sind selbst definierte Datentypen
• Erlauben mehrere Elemente zu neuem Element zusammenzufassen und
unter gemeinsamen Namen anzusprechen
• Können analog zu den eingebauten Datentypen verwendet werden
• Vergleiche dazu Arrays (Zusammenfassung gleichartiger Elemente)
• Beispiel - Bankkonto (sehr stark vereinfacht)
• Daten: Name, Betrag
• Operationen, die man auf so ein Konto ausführen möchte
• Aufteilung auf Dateien
• Mehrere Klassen pro Datei sind möglich
• Jede Klasse sollte aber in eigener Datei sein
RT (ICS @ UIBK)
Programmiermethodik
127/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Deklaration
• Einfacher Ansatz für ein Bankkonto
p u b l i c c l a s s Account {
p r i v a t e S t r i n g name ;
p r i v a t e double amount ;
p u b l i c v o i d d e p o s i t ( double money ) { . . . }
...
}
• Variablen werden als Felder, Attribute, Membervariablen,
•
•
•
•
Instanzvariablen oder Objektvariablen bezeichnet
Operationen (Methoden) und Objektvariablen werden ohne
Schlüsselwort static deklariert
Klasse Account kann wie jeder andere Datentyp verwendet werden
Klassenname ist Typ, und kann in Deklarationen verwendet werden
Beispiel: Account x, y; deklariert 2 Variablen, die Objekte vom Typ
Account referenzieren können
RT (ICS @ UIBK)
Programmiermethodik
128/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Zugriffsattribute in Java (ein erster Überblick)
• public
• Zugriff von überall erlaubt (bei Objektvariablen: lesend und schreibend)
• private
• Zugriff nur aus Methoden derselben Klasse erlaubt
• Kein Attribut (default)
• Zugriff aus Methoden beliebiger Klassen desselben Pakets erlaubt
• Details über Pakete: später
RT (ICS @ UIBK)
Programmiermethodik
129/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Objekterzeugung
• Erzeugung mit new
x = new Account ( ) ;
y = new Account ( ) ;
x und y zeigen nun auf Account-Objekte
• Beide Objekte haben gleiche Struktur, aber unterschiedliche Identität
(wird intern verwaltet)
• Identität
• Objekte haben immer eigene Identität
• Zwei Objekte können dadurch immer unterschieden werden, auch wenn
sie den gleichen Zustand haben (mittels ==)
• Allgemeines Beispiel: Zwei gleiche Fahrräder (neu, gleiches Modell und
Farbe) haben gleichen Zustand sind aber trotzdem unterschiedlich
(Identität ∼ Seriennummer)
RT (ICS @ UIBK)
Programmiermethodik
130/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Automatische Initialisierung
• Objektvariablen werden automatisch initialisiert
(0, false, ’\u0000’, null)
• Objektvariablen können aber auch wie lokale Variablen initialisiert
werden
• Beispiel
p u b l i c c l a s s Account {
p r i v a t e S t r i n g name ; // = n u l l
p r i v a t e double amount = 5 ;
// 5 EUR S t a r t g u t h a b e n
...
}
RT (ICS @ UIBK)
Programmiermethodik
131/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Verwendung
• Nach Erzeugung kann die Variable vom Typ Account verwendet werden
• Auf Objektvariablen und Methoden (vor allem!) kann durch
Qualifikation zugegriffen werden
• someObject.objectVariabeName
• someObject.methodName(...)
• Wichtig: Direkter Zugriff auf Objektvariablen sollte nur in seltenen
Fällen durchgeführt werden (Datenkapselung)
• Negativbeispiel
p u b l i c c l a s s Account {
p r i v a t e S t r i n g name ;
p u b l i c double amount ; // d a n g e r o u s
...
}
Account x = new Account ( ) ;
...
x . amount = 1_000_000_000.00;
RT (ICS @ UIBK)
Programmiermethodik
132/613
Objektorientierung
Objekte, Klassen und Methoden in Java
this-Referenz
• jedes Objekt hat eine this-Referenz
• Referenz auf sich selbst
• ist in jeder Methode automatisch definiert
• damit können Objektvariablen von lokalen Variablen unterschieden
werden
⇒ Objektvariablen und lokale Variablen können den gleichen Bezeichner
haben
RT (ICS @ UIBK)
Programmiermethodik
133/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Beispiel: Stack
Dateien: Stack1, Stack2, Stack3, StackApplication
RT (ICS @ UIBK)
Programmiermethodik
134/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Zuweisung
• Objektreferenzen können einander zugewiesen werden, falls sie den
gleichen Typ haben
• Typen werden durch denselben Namen bezeichnet (Namensäquivalenz)
• nicht in allen Programmiersprachen gleich
• es gibt auch Strukturäquivalenz (Typen sind gleich, wenn sie gleiche
Struktur haben)
• null darf jeder Objektvariable zugewiesen werden
• Beispiel
Account x = new Account ( ) , y = n u l l ;
y = x;
y und x referenzieren dasselbe Objekt
⇒ Jede Änderung der Objektvariablen ist bei x und y sichtbar (wie bei
Arrays)
RT (ICS @ UIBK)
Programmiermethodik
135/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Vergleiche
• Objekte können mit == und != verglichen werden
⇒ Vergleicht nur Referenzen und nicht die Werte
(wie bei Arrays und Strings)!
• Will man vergleichen, ob Objekte inhaltlich gleich sind
• schreibe eigene Vergleichsmethode
• muss einzelne Objektvariablen vergleichen
• genauer Vergleich kann noch komplizierter sein
(wird im Kapitel über die Vererbung noch genau besprochen)!
RT (ICS @ UIBK)
Programmiermethodik
136/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Getter- und Setter-Methoden
• Private Objektvariable ist von außen nicht erreichbar
• Wenn man die Werte lesen bzw. ändern möchte:
• Getter- bzw. Setter-Methode (Accessors, Mutators)
• Beispiel
p r i v a t e t y p e name ;
...
p u b l i c t y p e getName ( ) { . . . }
p u b l i c v o i d setName ( t y p e name ) { . . . }
• Vorteile durch Methoden
• Kontrolle der übergebenen Werte
• Hilfsmittel zur Fehlersuche
• Setter/Getter für scheinbare Datenelemente
• Interne Maßnahmen (Optimierung) verbergen
RT (ICS @ UIBK)
Programmiermethodik
137/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Getter- und Setter-Methoden
• Getter- und Setter-Methoden sind nur einfachste Möglichkeit, auf
Objektvariablen zuzugreifen
• Intensiver Gebrauch von Getter- und Setter-Methoden ist kein Zeichen
von Objektorientierung
• Deutet eher auf einen fragwürdigen OO-Entwurf hin
• Objekt verkommt zu Datencontainer, keine Objektorientierung!
• Verhalten des Objekts kann zu sehr von anderen Klassen gesteuert
werden
RT (ICS @ UIBK)
Programmiermethodik
138/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Beispiel: Rationale Zahlen
Dateien: Rational1, RationalApplication
RT (ICS @ UIBK)
Programmiermethodik
139/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Konstruktoren
• Konstruktor: spezielle Initialisierungsmethode, die bei Erzeugung des
Objekts aufgerufen werden
• Objektvariablen können darin mit sinnvollen Werten belegt oder
initialisiert werden
• hat den gleichen Namen wie die Klasse
• ist Methode ohne Rückgabetyp
• kann Parameter haben
RT (ICS @ UIBK)
Programmiermethodik
140/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Konstruktoren und Parameter
• Parameterlose Konstruktoren
• Form: public Rational (){...}
• kann beliebigen Code enthalten
• wenn Klasse keinen Konstruktor enthält, fügt Java automatisch einen
parameterlosen leeren Konstruktor (Default-Konstruktor) ein
• Konstruktoren mit Parametern
• Übergabe von Werten (für die Initialisierung)
• Beispiele
p u b l i c R a t i o n a l ( long n , long d ) { . . . }
p u b l i c R a t i o n a l ( long i n t e g e r ) { . . . }
RT (ICS @ UIBK)
Programmiermethodik
141/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Konstruktorenverkettung
• Mit this () (bzw. this (param1 ,...) ) kann in einem Konstruktor auf
andere Konstruktoren zugegriffen werden
• Aufruf eines anderen Konstruktors muss erste Anweisung sein
• Macht private Konstruktoren sinnvoll:
öffentliche Konstrukten nutzen internen (privaten) Konstruktor
RT (ICS @ UIBK)
Programmiermethodik
142/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Beispiel: Rationale Zahlen
Dateien: Rational2, RationalApplication
RT (ICS @ UIBK)
Programmiermethodik
143/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Kopieren von Objekten
• Kann mittels Konstruktoren unterstützt werden
p u b l i c Account ( S t r i n g name , double amount ) {
t h i s . name = name ;
// a s u s u a l
t h i s . amount = amount ;
}
p u b l i c Account ( Account o t h e r ) {
t h i s . name = o t h e r . name ; // copy c o n s t r u c t o r
t h i s . amount = o t h e r . amount ;
}
• Anwendung
Account o r i g , copy ;
o r i g = new Account ( " Spengler " , 3 0 0 ) ;
copy = new Account ( o r i g ) ;
RT (ICS @ UIBK)
Programmiermethodik
144/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Sichtbarkeit von private im Detail
• Betrachte Zuweisung this .name = other.name im Kopierkonstruktor
• Üblicherweise ist name privates Attribut
⇒ Zugriff this .name sollte erlaubt sein (eigenes Attribut)
⇒ Was ist mit Zugriff other .name ?
• 2 Sichtweisen
• Objektbasierte Sicht
• other ist anderes Objekt derselben Klasse
⇒ erlaube keinen Zugriff
• Klassenbasierte Sicht
• other ist anderes Objekt derselben Klasse
⇒ erlaube Zugriff
• Java nutzt klassenbasierte Sicht
RT (ICS @ UIBK)
Programmiermethodik
145/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Probleme beim Kopieren
• Objekt kann andere (Daten-)Objekte enthalten (Arrays, Listen, . . . )
• Einfache Wertzuweisung dupliziert nur Referenzen, nicht Datenobjekte
• Wird Datenobjekt in Kopie verändert, wirkt sich das auch auf
ursprüngliches Objekt aus
• Kann manchmal sinnvoll sein
• In vielen Fällen wird aber wirkliche Kopie (tiefe Kopie) benötigt
RT (ICS @ UIBK)
Programmiermethodik
146/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Flache und tiefe Kopien
• Flache Kopie (shallow copy)
• Es wird nur mit Wertzuweisung kopiert
• Es wird nur das Objekt (nicht die darin enthaltenen Objekte) kopiert
• Tiefe Kopie (deep copy)
• Es wird auch jedes Objekt kopiert
• Wenn das Objekt weitere Objekte enthält, dann wird das Kopieren
fortgesetzt (rekursiv weiter)
• Original und Kopie enthalten dann logisch gleiche aber getrennte
Datenelemente
• Bei der Vererbung müssen zusätzliche Aspekte beachtet werden
• Java bietet zusätzliche Unterstützungen an
(siehe nachfolgendes Kapitel über Vererbung)
RT (ICS @ UIBK)
Programmiermethodik
147/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Beispiel: Stack
1 public class Stack {
2
p r i v a t e Account [ ] d a t a ;
3
p r i v a t e i n t pos ;
4
public Stack () {
5
t h i s . d a t a = new Account [ 1 0 0 ] ;
6
t h i s . pos = 0 ;
7
}
8
9
p u b l i c v o i d push ( Account x ) {
10
i f ( t h i s . pos < t h i s . d a t a . l e n g t h ) {
11
t h i s . data [ t h i s . pos ] = x ;
12
t h i s . pos++;
13
}
14
}
RT (ICS @ UIBK)
Programmiermethodik
148/613
Objektorientierung
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 }
Objekte, Klassen und Methoden in Java
p u b l i c S t a c k ( S t a c k o t h e r ) { // t o o s h a l l o w
t h i s . data = other . data ;
t h i s . pos = o t h e r . p o s ;
}
p u b l i c S t a c k ( S t a c k o t h e r ) { // mixed form
t h i s . d a t a = A r r a y s . copyOf ( o t h e r . data ,
other . data . l e n g t h ) ;
t h i s . pos = o t h e r . p o s ;
}
p u b l i c S t a c k ( S t a c k o t h e r ) { // deep copy
t h i s . d a t a = new Account [ o t h e r . d a t a . l e n g t h ] ;
f o r ( i n t i =0; i < o t h e r . p o s ; i ++)
t h i s . d a t a [ i ] = new Account ( o t h e r . d a t a [ i ] ) ;
t h i s . pos = o t h e r . p o s ;
}
RT (ICS @ UIBK)
Programmiermethodik
149/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Beispiel Aufrufe
Account a = new Account ( " Moser " , 1 0 0 0 ) ;
S t a c k s 1 = new S t a c k ( ) ;
s 1 . push ( a ) ;
S t a c k s 2 = new S t a c k ( s 1 ) ;
Account a = s 1 . pop ( ) ;
Account b = s 2 . pop ( ) ;
b . deposit (300);
• Unterschiedliche Effekte, abhängig von verwendetem
Kopier-Konstruktor (Z. 15, 20 oder 26)
RT (ICS @ UIBK)
Programmiermethodik
150/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Klassen und Typen
• Klasse legt den Typ für alle Exemplare fest
• Typsystem einer Programmiersprache kann diese Information nutzen
• Typsysteme
• Bestandteil des Compilers einer Programmiersprache oder deren
Laufzeitsystems
• Überprüft Datentypen zur Übersetzungszeit oder Laufzeit
• Jeder Ausdruck hat einen Typ
• Typsystem überprüft, ob Verwendung mit Regeln des Typsystems
verträglich ist (Ist Operation auf ein Objekt erlaubt?)
• Unterscheidung bei Typsystemen
• Statisches Typsystem – Überprüfung zur Übersetzungszeit
• Dynamisches Typsystem – Überprüfung zur Laufzeit
RT (ICS @ UIBK)
Programmiermethodik
151/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Statisches Typsystem
• Eigenschaften
• Typ von Variablen und Parametern wird im Quelltext deklariert
• Schränkt ein, welche Objekte einer Variable zugewiesen werden können
• Compiler erkennt frühzeitig unpassende Zuweisung oder unpassenden
Aufruf einer Operation
• Vorteile
• Kompilierte Anwendungen können besser optimiert werden
• Programmstruktur ist übersichtlicher
• Entwicklungsumgebungen können besser unterstützt werden
• Fehler können früher erkannt werden
• Beispiele: Java, C++, C#
RT (ICS @ UIBK)
Programmiermethodik
152/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Dynamisches Typsystem
• Eigenschaften
• Variablen sind keinem deklarierten Typ zugeordnet
• Variablen können beliebige Objekte referenzieren
• Ob Operation auf Objekt erlaubt ist, wird zur Laufzeit überprüft
• Vorteile
• Flexibilität
• Keine Notwendigkeit einer expliziten Typumwandlung
• Klassen und Typen sind entkoppelt
• Beispiele: Smalltalk, Ruby, Python
RT (ICS @ UIBK)
Programmiermethodik
153/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Stark und schwach typisierte Programmiersprachen
• stark typisiert:
Programmiersprache überwacht das Erstellen und den Zugriff auf alle
Objekte so, dass sichergestellt ist, dass Variablen immer auf Objekte
verweisen, die auch die Spezifikation des Typs erfüllen, der für die
Variablen deklariert ist
• schwach typisiert:
erlauben es, Objekt einer Variable zuzuweisen, ohne dass Objekt die
Spezifikation des Typs der Variable erfüllt
• Unterscheidung stark / schwach ist unabhängig von Unterscheidung
statisch / dynamisch
• Java ist stark typisiert, C ist schwach typisiert (int x = 5.7;)
RT (ICS @ UIBK)
Programmiermethodik
154/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Unterschied: Arrays und Klassen
Arrays
Bestehen aus gleichartigen Elementen
Elemente eines Arrays haben keine
Namen, werden über Index angesprochen
Anzahl der Elemente wird bei Erzeugung festgelegt
RT (ICS @ UIBK)
Klassen
Können aus verschiedenartigen Objektvariablen bestehen
Objektvariablen einer Klasse haben
Namen und werden über Namen
angesprochen
Anzahl der Objektvariablen wird
bei Deklaration der Klasse festgelegt
Programmiermethodik
155/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Unterschied: statisch / nicht-statisch
• Beobachtung: Objektvariablen und Methoden können mit
Schlüsselwort static gekennzeichnet werden (voriges Kapitel) oder
nicht (dieses Kapitel)
• Unterschied?
• Klasse ist auch ein Objekt
• Klassenobjekt ist eine Schablone, die Aussehen der Klasse festlegt
• Sowohl Klassenobjekt als auch “normale” Objekte können Variablen und
Methoden haben
• Mit static - gehören zum Klassenobjekt (statische Komponenten)
• Ohne static - gehören zu den Objekten (objektbezogene Komponenten)
• für jede Klasse existiert genau ein Klassenobjekt
⇒ statische Objektvariablen sind wie globale Variablen
RT (ICS @ UIBK)
Programmiermethodik
156/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Statische Komponenten (Zugriff)
• Zugriff auf Variablen und Methoden
• Objektmethoden und Konstruktoren können auf Objekt- und
Klassenvariablen (Objekt- und Klassenmethoden) ohne Qualifizierung
zugreifen (implizites this .)
• Klassenmethoden können ohne Qualifizierung nur auf Klassenvariablen
(Klassenmethoden) zugreifen
• Zugriff auf Klassenvariablen
• Classname. field bzw. Classname.method(...)
• Innerhalb Klasse kann Qualifizierung (Classname.) weggelassen werden
• Es gibt keine this-Referenz in statischen Methoden
• Spezielle Methode main
• Jede Klasse, die eine public static void main(String [] args) Methode
hat, kann von Kommandozeile wie ein Programm aufgerufen werden
(args = Kommandozeilenparameter)
RT (ICS @ UIBK)
Programmiermethodik
157/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Beispiel
p u b l i c c l a s s Account {
private static int counter = 0;
p r i v a t e S t r i n g name ;
p r i v a t e double amount ;
p u b l i c Account ( S t r i n g name , double amount ) {
t h i s . name = name ;
t h i s . amount = amount ;
Account . c o u n t e r ++; // w i t h q u a l i f i e r
}
public static int getCounter () {
// no a c c e s s t o name / amount
r e t u r n c o u n t e r ; // w i t h o u t q u a l i f i e r
}
}
RT (ICS @ UIBK)
Programmiermethodik
158/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Beispiel
public class AccountClient {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
Account a = new Account ( " Peter " , 1 0 ) ;
Account b = new Account ( " Barbara " , 2 0 ) ;
a = new Account ( " Hans " , 5 ) ;
System . o u t . p r i n t l n ( Account . g e t C o u n t e r ( ) +
" accounts have been created " ) ;
}
}
RT (ICS @ UIBK)
Programmiermethodik
159/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Statische Komponenten - Initialisierung
• für Initialisierung kann spezieller Konstruktor verwendet werden
(statischer Initialisierer)
• hat keinen Namen, keine Parameter
p u b l i c c l a s s Account {
private static int counter ;
static {
c o u n t e r = 0 ; // a r b i t r a r y s t m t s ;
}
...
}
• es gibt nur einen einzigen statischen Konstruktor
• wird aufgerufen, wenn Klasse geladen wird (Beginn der
Programmausführung)
RT (ICS @ UIBK)
Programmiermethodik
160/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Unterschied: Objektbezogen oder Statisch
Deklarationen
existieren
Variablen Anlegung
Variablen Freigabe
Konstruktor Aufruf
Variablenzugriff
Methodenaufruf
RT (ICS @ UIBK)
Objektbezogen
Statisch
ohne static
in jedem Objekt
wenn Objekt erzeugt
wird
vom Garage Collector
bei Erzeugung des Objekts
obj . field
this . field
obj .method(...)
this .method(...)
mit static
nur einmal pro Klasse
wenn Klasse geladen
wird
bei Programmende
wenn Klasse geladen
wird
Class . field
Programmiermethodik
Class .method()
161/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Beziehungen zwischen Klassen
• In einem objektorientierten Programm stehen Klassen (und damit
Objekte) in Beziehung (selten isolierte Objekte)
• Einfaches Beispiel
• Klasse Adresse
• Klasse Person
• Jede Person hat eine Adresse.
• Klasse Kurs
• Zu einem Kurs können sich mehrere Personen anmelden.
• Eine Person leitet den Kurs.
RT (ICS @ UIBK)
Programmiermethodik
162/613
Objektorientierung
Objekte, Klassen und Methoden in Java
Kohäsion und Kopplung
• Kohäsion
• Kohäsion beschreibt wie gut eine Methode tatsächlich genau eine
Aufgabe erfüllt oder wie genau abgegrenzt die Funktionalität einer
Klasse ist
• hohe Kohäsion deutet auf gute Trennung der Zuständigkeiten hin
• Genau das will man erreichen, d.h. eine Methode oder Klasse soll nur
eine bestimmte Aufgabe erfüllen
• Hohe Kohäsion hilft bei Wiederverwendung
• Kopplung
• Darunter versteht man, wie stark Klassen miteinander in Verbindung
stehen
• Ziel einer guten Modellierung ist eine möglichst lose Kopplung
• Geringe Abhängigkeiten von Klassen untereinander
• Gute Datenkapselung und sinnvolle Zugriffsmethoden ermöglichen dies
RT (ICS @ UIBK)
Programmiermethodik
163/613
Objektorientierung
String-Klasse
Übersicht
Objektorientierung
Allgemeine Grundlagen
Objekte und Klassen
Objekte, Klassen und Methoden in Java
String-Klasse
Wrapper-Klassen
RT (ICS @ UIBK)
Programmiermethodik
164/613
Objektorientierung
String-Klasse
Strings in Java
• Die Klasse String ist in Java vordefiniert.
• Besonderheiten
• Es gibt auch String-Literale: "TestString"
• Es gibt einen Operator: + (und auch +=)
• Implizite Typkonvertierung
• String-Objekte sind nach dem Anlegen nicht mehr veränderbar
• Es existieren unterschiedliche Konstruktoren
• String s1 = "Hallo";
• String s2 = new String();
• String s3 = new String(s1);
• char charArr [] = {’S’,’W’,’E’,’2’};
• String s4 = new String(charArr);
• String s5 = new String(charArr ,1,2);
RT (ICS @ UIBK)
Programmiermethodik
165/613
Objektorientierung
String-Klasse
Vergleich
• Ähnlich wie bei Objekten und Arrays: == ist Referenzvergleich
• Beispiele
S t r i n g s 1 = " Hallo " ; // " H a l l o " w i r d n u r
S t r i n g s 2 = " Hallo " ; // e i n m a l e r z e u g t
System . o u t . p r i n t l n ( s 2 == s 1 ) ; // t r u e ! ! !
S t r i n g s 3 = new S t r i n g ( s 1 ) ;
System . o u t . p r i n t l n ( s 3 == s 1 ) ; // f a l s e
System . o u t . p r i n t l n ( s 1 . e q u a l s ( s 3 ) ) ; // t r u e
System . o u t . p r i n t l n ( s 1 . e q u a l s ( " HALLO " ) ) ; // f a l s e
System . o u t . p r i n t l n ( s 1 . e q u a l s I g n o r e C a s e ( " HALLO " ) ) ;
// t r u e
RT (ICS @ UIBK)
Programmiermethodik
166/613
Objektorientierung
String-Klasse
Hilfreiche Methoden
public class StringTest {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
S t r i n g s 1 = "Das ist ein spezieller Test " ;
System . o u t . p r i n t l n ( s 1 . l e n g t h ( ) ) ;
System . o u t . p r i n t l n ( s 1 . c h a r A t ( 0 ) ) ;
System . o u t . p r i n t l n ( s 1 . i n d e x O f ( ’i’ ) ) ;
System . o u t . p r i n t l n ( s 1 . l a s t I n d e x O f ( ’i’ ) ) ;
System . o u t . p r i n t l n ( s 1 . i n d e x O f ( ’i’ , 5 ) ) ;
System . o u t . p r i n t l n ( s 1 . l a s t I n d e x O f ( ’i’ , 1 0 ) ) ;
System . o u t . p r i n t l n ( s 1 . i n d e x O f ( "ei" ) ) ;
System . o u t . p r i n t l n ( s 1 . s u b s t r i n g ( 8 ) ) ;
System . o u t . p r i n t l n ( s 1 . s u b s t r i n g ( 4 , 1 5 ) ) ;
}
}
RT (ICS @ UIBK)
Programmiermethodik
167/613
Objektorientierung
String-Klasse
StringBuilder / StringBuffer
• Verhält sich wie String, kann aber editiert werden
• String-Objekte sind nach dem Erzeugen nicht mehr veränderbar
⇒ Jede Konkatenation bei Strings erzeugt neue String-Objekte
⇒ Nicht effizient, um große Strings aus vielen kleinen aufzubauen
• StringBuilder kann dazu verwendet werden, Zeichenketten aufzubauen
• Nach Editieren kann StringBuilder in String umgewandelt werden
• Demo: StringTest
• Neben append und toString gibt es viele weitere Methoden:
• insert ( position , text ), delete ( position , position ),
replace ( position , position , text ), charAt( position ), . . .
RT (ICS @ UIBK)
Programmiermethodik
168/613
Objektorientierung
Wrapper-Klassen
Übersicht
Objektorientierung
Allgemeine Grundlagen
Objekte und Klassen
Objekte, Klassen und Methoden in Java
String-Klasse
Wrapper-Klassen
RT (ICS @ UIBK)
Programmiermethodik
169/613
Objektorientierung
Wrapper-Klassen
Motivation
• Zu jedem primitiven Datentyp in Java gibt es eine sogenannte
Wrapper-Klasse
• Kapselt die primitive Variable in einer objektorientierten Hülle
• Methoden für den Zugriff und die Umwandlung
•
primitiver Datentyp
Klasse
Byte
Short
Integer
Long
Float
Double
Boolean
Character
Void
RT (ICS @ UIBK)
byte
short
int
long
float
double
boolean
char
void
Programmiermethodik
170/613
Objektorientierung
Wrapper-Klassen
Allgemein
• Erzeugung
• Konstruktor (primitiver Typ)
Integer i = new Integer(10);
• Statische Methode (primitiver Typ)
Integer i = Integer .valueOf(10);
• Konstruktor mit String
Integer i = new Integer("-200");
• Rückgabemethoden
• Rückgabe als primitiver Typ
int j = i. intValue ();
• Rückgabe als String
String s = i. toString ();
• Alle Wrapper-Klassen sind unveränderlich
(Wrapper-Klassen sind nur als Ummantelung und nicht als
vollständiger Datentyp gedacht)
RT (ICS @ UIBK)
Programmiermethodik
171/613
Objektorientierung
Wrapper-Klassen
Nützliches
• Wrapper-Klassen bieten nützliche Hilfsmethoden an
• Beispiel: Parsen von Strings (z.B. Integer )
• public static int parseInt ( String s)
• Versucht einen String in eine Ganzzahl umzuwandeln.
• Wenn übergebener String nicht einer Ganzzahl entspricht, wird
Programm abgebrochen (Ausnahme)
• Konstanten
• MIN_VALUE und MAX_VALUE
• NEGATIVE_INFINITY, POSITIVE_INFINITY und NaN (bei Float
und Double)
RT (ICS @ UIBK)
Programmiermethodik
172/613
Objektorientierung
Wrapper-Klassen
Autoboxing / Autounboxing
• Automatische Konvertierung zwischen primitiven Datentypen und
Wrapper-Klassen (seit Java 1.5)
• Compiler fügt notwendigen Code automatisch ein
• Zwei Richtungen
• Umwandlung primitiver Wert → Wrapper-Objekt
• Umwandlung Wrapper-Objekt → primitiver Wert
• Ziel
• Primitive Typen wie Referenztypen verwenden
• Verwendung
• Bei Zuweisungen
• Bei Methodenaufrufen
• Auch innerhalb von Ausdrücken
• ++, −−, +=, −= können nicht auf Wrapper-Objekte angewandt
werden
RT (ICS @ UIBK)
Programmiermethodik
173/613
Objektorientierung
Wrapper-Klassen
Beispiel
• ohne Auto(un)boxing
Integer i = Integer . valueOf ( 5 ) ;
int j = 2 ∗ i . intValue ( ) ;
i = Integer . valueOf ( j − 7);
• mit Auto(un)boxing
I n t e g e r i = 5 ; // a u t o b o x i n g
i n t j = 2 ∗ i ; // a u t o u n b o x i n g
i = j − 7;
// a u t o b o x i n g
RT (ICS @ UIBK)
Programmiermethodik
174/613
Objektorientierung
Wrapper-Klassen
Probleme
• Autoboxing verschleiert Objektgenerierung!
Z. B. Probleme bei ==
• Integer-Caching und Vergleich
• Alle Objekte im Bereich -128 bis +127 werden bereits zur Ladezeit
angelegt
• Bei einem Boxing in diesem Bereich erhält man immer die gleiche
Referenz, ansonsten aber nicht
RT (ICS @ UIBK)
Programmiermethodik
175/613
Objektorientierung
Wrapper-Klassen
Probleme: Beispiele
Integer j1 = 2;
Integer j2 = 2;
System . o u t . p r i n t l n ( j 1 == j 2 ) ; //
I n t e g e r l1 = 128;
I n t e g e r l2 = 128;
System . o u t . p r i n t l n ( l 1 == l 2 ) ; //
I n t e g e r n1 = new I n t e g e r ( 1 0 ) ;
I n t e g e r n2 = I n t e g e r . v a l u e O f ( 1 0 ) ;
I n t e g e r n3 = 1 0 ;
I n t e g e r n4 = 1 0 ;
System . o u t . p r i n t l n ( n1 == n2 ) ; //
System . o u t . p r i n t l n ( n2 == n3 ) ; //
System . o u t . p r i n t l n ( n1 == n3 ) ; //
System . o u t . p r i n t l n ( n3 == n4 ) ; //
RT (ICS @ UIBK)
Programmiermethodik
true
false
false
true
false
true
176/613
Objektorientierung
Wrapper-Klassen
Weitere Probleme
• Keine Konvertierung von null zu 0
Integer i = null; int n = i; // java . lang . NullPointerException
(NullPointerException wird immer dann geworfen, wenn versucht wird,
auf Objektmethoden oder Objektvariablen von null zuzugreifen, hier:
null . intValue)
• Keine implizite Typkonvertierung
float fa
Float fb
Float fc
Integer
RT (ICS @ UIBK)
=
=
=
[]
123;
123;
123 f ;
iarr =
// okay
// e r r o r
// okay
new i n t [ ] { 1 , 2 , 3 , 4 } ; // e r r o r
Programmiermethodik
177/613
Vererbung und Polymorphismus
Übersicht
Vererbung und Polymorphismus
Vererbung Allgemein
Vererbung der Spezifikation in Java
Vererbung der Implementierung in Java
Abstrakte Klassen
Die Klasse Object
RT (ICS @ UIBK)
Programmiermethodik
178/613
Vererbung und Polymorphismus
Vererbung Allgemein
Übersicht
Vererbung und Polymorphismus
Vererbung Allgemein
Vererbung der Spezifikation in Java
Vererbung der Implementierung in Java
Abstrakte Klassen
Die Klasse Object
RT (ICS @ UIBK)
Programmiermethodik
179/613
Vererbung und Polymorphismus
Vererbung Allgemein
Vererbung Allgemein
• Klassen modellieren Dinge der realen Welt
• Dinge kommen in verschiedenen Varianten vor, die man durch
Klassifikation hierarchisch gliedern kann
• Programme sollten
• mit den verschiedenen Varianten arbeiten und
• in bestimmten Situationen Varianten nicht unbedingt unterscheiden
(gleich behandeln)
• Java bietet die Möglichkeit
• hierarchische Klassenstrukturen zu bilden und
• Varianten von Objekten gleich zu behandeln
RT (ICS @ UIBK)
Programmiermethodik
180/613
Vererbung und Polymorphismus
Vererbung Allgemein
Unterklassen und Oberklassen
• Klasse S ist eine Unterklasse der Klasse A, wenn S Spezifikation von A
erfüllt, umgekehrt aber A nicht die Spezifikation von S (A ist eine
Oberklasse von S)
• Beziehung zwischen A und S wird Spezialisierung genannt
• Beziehung zwischen S und A wird Generalisierung genannt
• [Lahres 2006]
RT (ICS @ UIBK)
Programmiermethodik
181/613
Vererbung und Polymorphismus
Vererbung Allgemein
Prinzip der Ersetzbarkeit
• Wenn Klasse B eine Unterklasse der Klasse A ist, dann können in
einem Programm alle Exemplare der Klasse A durch Exemplare der
Klasse B ersetzt werden und es gelten weiterhin alle zugesicherten
Eigenschaften der Klasse A
• Exemplare der Unterklasse sind gleichzeitig Exemplare der Oberklasse
in Bezug auf die der Oberklasse zugrunde liegende Spezifikation
• Vorbedingungen, Nachbedingungen und Invarianten gelten auch dann,
wenn Exemplare der Oberklasse durch Exemplare der Unterklasse
ersetzt werden
• Beispiele folgen noch
RT (ICS @ UIBK)
Programmiermethodik
182/613
Vererbung und Polymorphismus
Vererbung Allgemein
Kategorien von Klassen
• Klassen können kategorisiert
werden
• abhängig davon in welchem
Umfang sie selbst für die von
ihnen spezifizierte
Schnittstelle auch Methoden
anbieten
• Kategorien
• Konkrete Klassen
• Rein spezifizierende Klassen
(Schnittstellen-Klassen)
• Abstrakte Klassen
• [Lahres 2006]
RT (ICS @ UIBK)
Programmiermethodik
183/613
Vererbung und Polymorphismus
Vererbung Allgemein
Konkrete Klassen
• Stellen für alle von der Klasse spezifizierte Operationen auch
Methoden bereit
• Es können Exemplare erzeugt werden
• Wurden bisher in dieser Vorlesung besprochen
• Beispiel: Array-basierter Stack
public class ArrayStack {
private Object [ ] elements ;
private int s i z e ;
p u b l i c v o i d push ( O b j e c t o b j ) {
elements [ s i z e ] = obj ;
s i z e ++;
}
p u b l i c O b j e c t pop ( ) { . . . }
...
}
RT (ICS @ UIBK)
Programmiermethodik
184/613
Vererbung und Polymorphismus
Vererbung Allgemein
Schnittstellen-Klassen
• Schnittstellen-Klassen
• Dienen alleine der Spezifikation einer Menge von Operationen
• Für keine Operation wird Implementierung bereitgestellt
• Es können keine Exemplare erzeugt werden
• Implementieren
• Wenn eine Unterklasse einer Schnittstellen-Klasse Methoden für alle
von der Schnittstelle spezifizierten Operationen bereitstellt
• Unterklasse implementiert die Schnittstelle
• Einsatz bei statisch typisierten Programmiersprachen (wie Java)
• Beispiel
public interface Stack {
// no i m p l e m e n t a t i o n s ! !
v o i d push ( O b j e c t o b j ) ; // p u t o b j on s t a c k
O b j e c t pop ( ) ; // r e t u r n and remove t o p e l e m e n t
O b j e c t p e e k ( ) ; // r e t u r n t o p e l e m e n t ( no r e m o v a l )
boolean i s E m p t y ( ) ; // c h e c k i f s t a c k i s empty
}
RT (ICS @ UIBK)
Programmiermethodik
185/613
Vererbung und Polymorphismus
Vererbung Allgemein
Abstrakte Klassen
• Abstrakte Klassen
• Stellen meist für mindestens eine Operation keine Implementierung
bereit
(Spezialfall: Alle Methoden implementiert, Klasse aber als abstrakt
markiert, siehe Abschnitt über abstrakte Klassen)
• keine direkten Exemplare möglich (Java: kein new AbstractClass (...) )
• Alle Exemplare einer abstrakten Klasse müssen gleichzeitig Exemplare
einer nicht abstrakten Unterklasse sein
• Abstrakte Methoden
• Erlauben eine Operation für eine Klasse zu definieren, ohne dafür eine
Methodenimplementierung zur Verfügung zu stellen
• Methode dient nur zur Spezifikation
• Implementierung erfolgt in abgeleiteter konkreter Unterklasse
RT (ICS @ UIBK)
Programmiermethodik
186/613
Vererbung und Polymorphismus
Vererbung Allgemein
Beispiel
p u b l i c a b s t r a c t c l a s s D e f a u l t S t a c k implements S t a c k {
// p r o v i d e d e f a u l t i m p l e m e n t a t i o n f o r p e e k
public Object peek ( ) {
O b j e c t o = t h i s . pop ( ) ;
t h i s . push ( o ) ;
return o ;
}
// l e a v e r e m a i n i n g s t a c k o p e r a t i o n s open
// f o r c o n c r e t e c l a s s e s
p u b l i c a b s t r a c t O b j e c t pop ( ) ;
p u b l i c a b s t r a c t boolean i s E m p t y ( ) ;
p u b l i c a b s t r a c t v o i d push ( O b j e c t o b j ) ;
}
RT (ICS @ UIBK)
Programmiermethodik
187/613
Vererbung und Polymorphismus
Vererbung Allgemein
Polymorphismus
• Polymorph = vielgestaltig
• Variable oder Methode kann gleichzeitig mehrere Typen haben
• Objektorientierte Sprachen sind polymorph
(Konventionelle Sprachen wie zum Beispiel Pascal sind monomorph)
• Verschiedene Arten:
• Universeller Polymorphismus
• Parametrischer Polymorphismus
• Inklusions-, Vererbungspolymorphismus
• Ad-hoc Polymorphismus
• Überladen
• Typumwandlung
RT (ICS @ UIBK)
Programmiermethodik
188/613
Vererbung und Polymorphismus
Vererbung Allgemein
Polymorphismus Arten
• Universeller Polymorphismus
• Name oder Wert kann theoretisch unendlich viele Typen besitzen
• Implementierung einer universell polymorphen Operation führt generell
gleichen Code unabhängig von den Typen ihrer Argumente aus
• Ad-hoc-Polymorphismus
• Name oder ein Wert kann nur endlich viele verschiedene Typen besitzen
• Typen sind zur Übersetzungszeit bekannt
• Ad-hoc-polymorphe (also überladene) Operationen können abhängig
von den Typen ihrer Argumente unterschiedlich implementiert sein
RT (ICS @ UIBK)
Programmiermethodik
189/613
Vererbung und Polymorphismus
Vererbung Allgemein
Polymorphismus in dieser Vorlesung
• Ad-hoc Polymorphismus wurde schon behandelt
(Typumwandlung, Überladen)
• Universeller Polymorphismus
• Parametrischer Polymorphismus wird noch behandelt
(Generische Programmierung)
• Inklusionspolymorphismus ist zentrales Thema dieses Kapitels
• Inklusionspolymorphismus
• Ersetzbarkeitsprinzip
• Dynamische Polymorphie
RT (ICS @ UIBK)
Programmiermethodik
190/613
Vererbung und Polymorphismus
Vererbung der Spezifikation in Java
Übersicht
Vererbung und Polymorphismus
Vererbung Allgemein
Vererbung der Spezifikation in Java
Vererbung der Implementierung in Java
Abstrakte Klassen
Die Klasse Object
RT (ICS @ UIBK)
Programmiermethodik
191/613
Vererbung und Polymorphismus
Vererbung der Spezifikation in Java
Interfaces
• Interfaces bestehen aus
• Methoden-Spezifikation ohne Rumpf
• Sind abstrakte Methoden
• Sind immer public
• Keine Konstruktoren
• Konstanten
• Alle Objektvariablen sind public static final (nur Konstanten)
• Implementierung
• Eine Klasse kann ein Interface implementieren
RT (ICS @ UIBK)
Programmiermethodik
192/613
Vererbung und Polymorphismus
Vererbung der Spezifikation in Java
Schlüsselwort final
• verschiedenen Dinge können als final gekennzeichnet werden
• Klassenvariablen
• Objektvariablen
• lokale Variablen
• Methodenparameter
• Methoden und Klassen (später)
• Bedeutung
• finale Variable oder Parameter kann nur maximal einmal einen Wert
zugewiesen bekommen, danach besteht nur noch Lesezugriff
• bei Klassenvariablen, Objektvariablen und Parametern, geschieht dies
genau einmal
• Klassenvariablen: bei Deklaration oder im statischen Initialisierungsblock
• Objektvariablen: bei Deklaration oder im Konstruktor
• Parameter: beim Aufruf der Methode
• Achtung bei Variablen von Referenztypen: Referenz bleibt unverändert,
aber Objekt kann sich ändern
RT (ICS @ UIBK)
Programmiermethodik
193/613
Vererbung und Polymorphismus
c l a s s Test {
final int x ;
final int y = 5;
int z ;
s t a t i c f i n a l i n t PI ;
static {
i n t x = 7 ; PI = x ∗ x ;
}
T e s t ( f i n a l Account b , i n t v ) {
v += 3 + PI ;
b . d e p o s i t ( 3 0 0 ) ; // okay
b = n u l l ; // n o t okay
t h i s . y = 3 ; // n o t okay
} // n o t okay
Test ( ) {
this ( null , 3);
t h i s . x = 2 ; // n o t okay
}
RT }(ICS @ UIBK)
Programmiermethodik
Vererbung der Spezifikation in Java
194/613
Vererbung und Polymorphismus
Vererbung der Spezifikation in Java
Klassen und Interfaces
• Klassen implementieren Interfaces (mit implements)
• Man kann keine Objekte von Interfaces anlegen
• Klasse kann mehrere Interfaces implementieren
• Interface kann von mehreren Klassen implementiert werden
• Implementierung eines Interfaces muss die Spezifikation erfüllen
• Alle Methoden müssen implementiert werden (Ausnahmen: später)
• Konstruktoren müssen in den Klassen implementiert werden
(nicht im Interface)
RT (ICS @ UIBK)
Programmiermethodik
195/613
Vererbung und Polymorphismus
Vererbung der Spezifikation in Java
Beispiel (Komplexe Zahlen)
• Einfaches Interface für komplexe Zahlen
p u b l i c i n t e r f a c e Complex {
double g e t R e a l ( ) ;
double g e t I m a g ( ) ;
double g e t D i s t a n c e ( ) ;
double g e t P h a s e ( ) ;
}
• Alle Methoden sind implizit public und abstract
(Könnte man angeben, muss man aber nicht)
• Jede Klasse, die Interface implementiert, muss die 4 Methoden
implementieren
• Beispiel: Siehe Polar.java, Cartesian.java, Complex.java
RT (ICS @ UIBK)
Programmiermethodik
196/613
Vererbung und Polymorphismus
Vererbung der Spezifikation in Java
Erläuterungen
• Klasse Cartesian und Polar implementieren das Interface Complex
• Beide Klassen implementieren die vorgegebenen Methoden (jeweils
unterschiedlich)
• Beide Klassen geben zusätzlich einen Konstruktor an
• Form des Konstruktors wird nicht vom Interface vorgegeben
• Es könnten noch mehrere Konstruktoren angegeben werden
• Es können zusätzliche Methoden angegeben werden (add, sub etc.)
⇒ keine Einschränkung für weitere Methoden
• Beide Klassen sind gleichberechtigte und unabhängige
Implementierungen von Complex
RT (ICS @ UIBK)
Programmiermethodik
197/613
Vererbung und Polymorphismus
Vererbung der Spezifikation in Java
Polymorphismus
• Interfaces definieren einen Typ
• Können in Variablendeklarationen, Parameterlisten, und als Ergebnistyp
von Methoden verwendet werden
• Bsp: other und Rückgabe Wert in multiply sind vom Typ Complex
• Warum funktioniert das Beispiel?
• Wenn Klasse das Interface Complex implementiert, können Objekte
dieser Klasse einer Variable vom Typ Complex zugewiesen werden
• Variable other kann daher auf unterschiedliche Objekte zeigen
⇒ Inklusionspolymorphismus
RT (ICS @ UIBK)
Programmiermethodik
198/613
Vererbung und Polymorphismus
Vererbung der Spezifikation in Java
Inklusionspolymorphismus
• Variable können Objekte unterschiedlichen Typs zugeordnet werden
• Typ der Variable beschreibt nur Schnittstelle
• Objekte sind zuweisungs-kompatibel, wenn Klasse Schnittstelle erfüllt
• Beim Aufruf einer Operation wird entsprechende Methode ausgewählt
(zur Laufzeit, abhängig vom Objekt)
• Späte Bindung (dynamisches Binden)
• Im Hauptprogramm wird zufällig eine Implementierung ausgewählt
• Frage: Wie wird richtige Methode gefunden?
• Zur Laufzeit wird von der JVM abhängig vom momentan zugewiesenen
Objekt die entsprechende Methode aufgerufen – dynamisches Binden
• Methodenaufruf wird abhängig vom Kontext in unterschiedliche Abläufe
umgesetzt
• Beispiel
Complex c1 = new P o l a r ( 2 , 0 ) ;
Complex c2 = new C a r t e s i a n ( 0 , 1 ) ;
c1 . m u l t i p l y ( c2 ) ; c2 . m u l t i p l y ( c1 ) ; c1 . m u l t i p l y ( c1 ) ;
RT (ICS @ UIBK)
Programmiermethodik
199/613
Vererbung und Polymorphismus
Vererbung der Spezifikation in Java
Statischer / Dynamischer Typ
• Statischer Typ
• Typ der Variable laut Deklaration
• Bestimmt, welche Objektvariablen und Methoden angesprochen werden
können
• Kompatibilitätsüberprüfung
• Dynamischer Typ
• Typ zur Laufzeit (abhängig vom tatsächlich zugewiesenen Objekt)
• Kann sich nach jeder (gültigen) Zuweisung ändern
• Bestimmt, welche Methoden wirklich aufgerufen werden
• Beispiel
Complex c = new P o l a r ( 2 , 0 ) ;
c = new C a r t e s i a n ( 2 , 0 ) ;
c = Math . random ( ) > 0 . 5 ? c : new P o l a r ( 1 , 1 ) ;
c = c . multiply (c );
RT (ICS @ UIBK)
Programmiermethodik
200/613
Vererbung und Polymorphismus
Vererbung der Spezifikation in Java
Mehrfache Implementierung
• Klasse kann mehrere Interfaces implementieren
(muss alle Methoden dieser Interfaces implementieren)
• Interfaces können die gleiche Methode vorschreiben (gleiche Signatur)
• Klasse, die diese Interfaces implementiert, muss Methode nur einmal
implementieren
RT (ICS @ UIBK)
Programmiermethodik
201/613
Vererbung und Polymorphismus
Vererbung der Spezifikation in Java
Beispiel
public interface P r in t a bl e {
String toString ();
}
p u b l i c c l a s s C a r t e s i a n implements Complex , P r i n t a b l e {
// methods f o r i n t e r f a c e Complex a s b e f o r e
public String toString () {
r e t u r n ( t h i s . r e a l + " + " + t h i s . imag + "i" ) ;
}
}
RT (ICS @ UIBK)
Programmiermethodik
202/613
Vererbung und Polymorphismus
Vererbung der Spezifikation in Java
Beispiel
• Beispiel: Siehe Stack.java, Container.java, Iterator.java,
ArrayStack.java, StackContainerTest.java
RT (ICS @ UIBK)
Programmiermethodik
203/613
Vererbung und Polymorphismus
Vererbung der Spezifikation in Java
Ableiten (bei Interfaces)
• Interface kann von anderen Interface abgeleitet werden
• Verwende dazu Schlüsselwort extends
• Interface kann mehrere Super-Interfaces haben
• Interface übernimmt alles aus den Super-Interfaces und kann
zusätzliche Methoden und Konstanten hinzugeben
• jeder Variablen eines Super-Interface kann Objekt vom Typ des
Sub-Interfaces zugewiesen werden
RT (ICS @ UIBK)
Programmiermethodik
204/613
Vererbung und Polymorphismus
Vererbung der Spezifikation in Java
Beispiel
public interface I t e r a t o r {
boolean h a s N e x t ( ) ; // i s t h e r e n e x t e l e m e n t
S t r i n g n e x t ( ) ; // g i v e me n e x t e l e m e n t
}
p u b l i c i n t e r f a c e R e m o v a b l e I t e r a t o r extends I t e r a t o r {
v o i d remove ( ) ;
// remove l a s t e l e m e n t t h a t was r e t u r n e d by n e x t ( )
// from c o n t a i n e r
// a u t o m a t i c a l l y i n h e r i t s methods from I t e r a t o r
}
• siehe auch LinkedList.java
RT (ICS @ UIBK)
Programmiermethodik
205/613
Vererbung und Polymorphismus
Vererbung der Spezifikation in Java
Konstanten
• In Interfaces können Konstanten deklariert werden
• Konstanten können auch weitervererbt werden
• Wenn Klasse Interface mit Konstanten implementiert, dann übernimmt
sie diese Konstanten!
• Wird normalerweise nicht empfohlen!
⇒ Sollte in einer sauberen Implementierung vermieden werden!
RT (ICS @ UIBK)
Programmiermethodik
206/613
Vererbung und Polymorphismus
Vererbung der Spezifikation in Java
Beispiel (schlecht)
public interface Grundfarben {
i n t ROT = 1 , GRUEN = 2 , BLAU = 3 ; }
p u b l i c i n t e r f a c e S o c k e n f a r b e n extends G r u n d f a r b e n {
i n t SCHWARZ = 1 0 , LILA = 1 1 ; }
p u b l i c i n t e r f a c e H o s e n f a r b e n extends G r u n d f a r b e n {
i n t LILA = 1 1 , SCHWARZ = 2 0 , BRAUN = 2 1 ; }
p u b l i c i n t e r f a c e A l l e f a r b e n extends S o c k e n f a r b e n , H o s e n f a r b
i n t BRAUN = 3 0 ; }
p u b l i c c l a s s A implements A l l e f a r b e n { }
public class InterfaceTest {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
System . o u t . p r i n t l n ( S o c k e n f a r b e n .ROT ) ; // s c h l e c h t
System . o u t . p r i n t l n ( A l l e f a r b e n .ROT ) ;
// s c h l e c h t
System . o u t . p r i n t l n ( H o s e n f a r b e n .SCHWARZ ) ;
// System . o u t . p r i n t l n ( A l l e f a r b e n .SCHWARZ ) ; g e h t n i c h t
// System . o u t . p r i n t l n ( A l l e f a r b e n . LILA ) ;
geht n i c h t
System . o u t . p r i n t l n ( new A ( ) . ROT ) ; // s c h l e c h t
System . o u t . p r i n t l n (A .ROT ) ;
// s c h l e c h t
}}
RT (ICS @ UIBK)
Programmiermethodik
207/613
Vererbung und Polymorphismus
Vererbung der Spezifikation in Java
Einsatz von Interfaces
• Erlauben isolierte Entwicklung von Implementierungen
• Anwendungen können nur auf Interfaces aufbauen
• Anwendung deklariert Variablen vom Interface-Typ
• Zukünftige Klassen, die Interface implementieren, können sofort in die
Anwendung eingebunden werden
• Leere Interfaces
• Marker-Interfaces (werden noch besprochen)
RT (ICS @ UIBK)
Programmiermethodik
208/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Übersicht
Vererbung und Polymorphismus
Vererbung Allgemein
Vererbung der Spezifikation in Java
Vererbung der Implementierung in Java
Abstrakte Klassen
Die Klasse Object
RT (ICS @ UIBK)
Programmiermethodik
209/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Vererbung und Interfaces
• Interface fixiert gemeinsame Eigenschaften von Klassen
• Klassen erfüllen gleichen Zweck (im Interface angegeben)
• Sind ansonsten unabhängig
• Bei vielen Klassen beruht Verwandtschaft nicht nur auf gleichen
Eigenschaften, sondern auf Erweiterung und Modifikation von
Eigenschaften
RT (ICS @ UIBK)
Programmiermethodik
210/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Vererbung der Implementierung (allgemein)
• Unterklassen erben in Oberklassen implementierte Funktionalität
• Unterklassen erben
• Verpflichtungen
• Alle Methoden
• Alle Daten
(abhängig von Sichtbarkeits-Modifikatoren)
• Funktionalität kann komplett übernommen werden oder von der
Unterklasse verändert/erweitert werden
⇒ Überschreiben
RT (ICS @ UIBK)
Programmiermethodik
211/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Überschreiben (allgemein)
• Unterklasse implementiert Operation, für die es Methode in Oberklasse
gibt
• Wird Methode auf Exemplar der Unterklasse aufgerufen, wird
überschriebene Implementierung aufgerufen
• Hängt nicht vom Typ der Variable ab, über die das Objekt referenziert
wird
• Entscheidend ist Typ des Objekts
⇒ Polymorphie!
• Überschriebene Methode kann
• eigene Implementierung haben und
• zusätzlich auf geerbte Implementierung zugreifen
RT (ICS @ UIBK)
Programmiermethodik
212/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Überschreiben (speziell)
• Geschützte Methoden (protected)
• Gehören nicht zur Schnittstelle
• Unterstützen Methoden zur Bereitstellung der Schnittstelle
• Können in Unterklassen verwendet und überschrieben werden
• Überschreiben verhindern
• Oberklasse will bestimmte Funktionalität erzwingen
• Unterklasse darf nicht überschreiben
(z.B. um bestimmte Verträge einzuhalten)
RT (ICS @ UIBK)
Programmiermethodik
213/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Beispiel (Fahrzeugverwaltung, minimal)
• KFZ
• Kennzeichen
• Standort
• Methode zur Ausgabe der KFZ-Daten
• LKW
• Kennzeichen
• Standort
• Ladung
• Methode zur Ausgabe der KFZ-Daten
• Methode zum Ändern der Ladung
RT (ICS @ UIBK)
Programmiermethodik
214/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Beispiel (Vererbungshierarchie)
• Auf Typebene (Ober- und Unterklassen)
• Auf Instanzebene (Mengen-Beziehung)
RT (ICS @ UIBK)
Programmiermethodik
215/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Beispiel (schlechte Lösung)
• Vehicle1.java, Truck1.java, VehicleTest1.java
RT (ICS @ UIBK)
Programmiermethodik
216/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Vererbung in Java
• Klasse B kann die Subklasse (Unterklasse, abgeleitete Klasse) einer
Klasse A (Superklasse, Oberklasse, Basisklasse) sein
• Subklasse erbt alle Objektvariablen und Methoden der Superklasse
• Subklasse kann weitere Objektvariablen deklarieren und Methoden
implementieren
• Objekt der Subklasse ist auch Objekt der Superklasse
• Java unterstützt nur Einfachvererbung (nur eine Superklasse)
RT (ICS @ UIBK)
Programmiermethodik
217/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Beispiel (mit Vererbung)
• Vehicle2.java, Truck2.java, VehicleTest2.java
RT (ICS @ UIBK)
Programmiermethodik
218/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Syntax
• Zusatz extends Vehicle2 lässt Klasse Truck2 von Klasse Vehicle2
erben
• Bestandteile von Klasse Vehicle2 werden in Klasse Truck2 eingeblendet
(sind dort vorhanden)
• Aber nicht alles ist sichtbar
(z.B. number, location sind als private deklariert)!
• Methode getInfo wird geerbt und kann in der Klasse Truck2
aufgerufen werden
RT (ICS @ UIBK)
Programmiermethodik
219/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Konstruktoren bei der Vererbung
• Konstruktoren werden nicht vererbt
• Jeder Konstruktor einer Subklasse muss zuerst einen
Superklassen-Konstruktor aufrufen
(Initialisierung der Superklasse)!
• Aufruf: super (...);
• Ausnahme: zuerst anderen Konstruktor mit this (...); aufrufen
• Wenn nichts angegeben wird (kein super (...); oder this (...); ), dann
ruft Konstruktor den Default-Konstruktor der Superklasse auf
• Wenn dieser nicht existiert?
• entweder in Superklasse implementieren oder
• anderen Konstruktor in Superklasse explizit aufrufen
RT (ICS @ UIBK)
Programmiermethodik
220/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Expliziter Aufruf
• Default-Konstruktor kann auch explizit mit super(); aufgerufen werden
(redundant)
• Wie bei this () und seinen Varianten kann man auch bei super() zu
allen möglichen Konstruktoren eine Verbindung herstellen
• Im Beispiel wird mit super(number,location); der entsprechende
Konstruktor in Vehicle2 aufgerufen
• Folgende Einschränkungen existieren
• super-Aufruf darf nur einmal vorkommen
• super-Aufruf muss als erste Anweisung auftreten
• this-Aufrufe und super-Aufrufe können nicht gleichzeitig verwendet
werden (immer erster Aufruf)
RT (ICS @ UIBK)
Programmiermethodik
221/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Zugriffsschutz mit protected
• Im Beispiel sind number und location mit private gekennzeichnet
• In Truck2 kann man nicht darauf zugreifen
• Wenn man aber einen Zugriff haben will?
• Mit protected markierte Objektvariablen und Methoden stehen allen
Subklassen zur Verfügung
• Sind in den Subklassen sichtbar
• Sichtbarkeit erstreckt sich auch über mehrere Stufen einer
Vererbungshierarchie
• Wie bei private gibt es eine Unterscheidung zwischen klassenbasierter
und objektbasierter Definition
(in Java klassenbasiert)
• Sichtbarkeitsregeln können auch bei Klassen verwendet werden
(Beispiele später)
RT (ICS @ UIBK)
Programmiermethodik
222/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Überschreiben von Methoden
• Klasse kann Methoden, die sie von Superklasse erbt, neu
implementieren (überschreiben)
• Folgende Regeln gelten dabei
• Name und Parameterliste der überschriebenen Methode müssen exakt
übernommen werden
• Ansonsten: Überladen (auch in Subklassen möglich)
• Zugriffsschutz darf gelockert werden (z.B. protected in public)
• Ergebnistyp darf vom Ergebnistyp der zu überschreibenden Methode
abgeleitet werden
• Rumpf kann komplett ersetzt werden
RT (ICS @ UIBK)
Programmiermethodik
223/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Beispiele
• Zugriff mittels protected Attributen: Vehicle3.java, Truck3.java,
VehicleTest3.java
• bessere Lösung mit Zugriff mittels protected Gettern: Vehicle4.java,
Truck4.java, VehicleTest4.java
RT (ICS @ UIBK)
Programmiermethodik
224/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Zugriff auf die Superklasse
• super kann auch in normalen Methoden eingesetzt werden
• super.method(...) ruft die entsprechende Methode method(...) in
direkten Superklasse auf
• Weitere Verkettung ist nicht möglich!
⇒ super.super.method(...) ist nicht möglich
• method(...) darf nicht private sein
• Kann auch bei Objektvariablen eingesetzt werden
RT (ICS @ UIBK)
Programmiermethodik
225/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Beispiele
• noch bessere Lösung mittels super: Vehicle5.java, Truck5.java,
VehicleTest5.java
RT (ICS @ UIBK)
Programmiermethodik
226/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Polymorphismus (Wiederholung)
• Es ist erlaubt, dass Variable objA vom Typ A Objekt objB einer
Subklasse B zugewiesen werden darf
• objA = objB; ist immer erlaubt (Ersetzbarkeitsprinzip)
• objB = (B) objA; ist nur zulässig, wenn objA auf B-Objekt zeigt
• Expliziter Cast notwendig
• Wird als Downcast bezeichnet
• Downcast ist problematisch
• Verletzt Prinzip der Trennung der Schnittstelle von Implementierung
• Kann meist mit Hilfe dynamischer Polymorphie und Prinzip der
Ersetzbarkeit umgangen werden
RT (ICS @ UIBK)
Programmiermethodik
227/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
instanceof Operator
• Objektvariablen sind polymorph
• sie haben statischen Typ (Deklaration)
• sie haben aktuelle Klassenzugehörigkeit (dynamischer Typ)
• dynamischer Typ kann mit instanceof abgefragt werden
• Vererbung muss aber berücksichtigt werden
• Erbt Klasse B von Klasse A, dann ist Exemplar der Klasse B auch
Exemplar der Klasse A, Umkehrung gilt nicht
• instanceof sollte nur in Ausnahmefällen eingesetzt werden
RT (ICS @ UIBK)
Programmiermethodik
228/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Beispiel
• VehicleTest5b.java
RT (ICS @ UIBK)
Programmiermethodik
229/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Dynamisches Binden
• Beim Übersetzen von Methodenaufrufen prüft Compiler statischen Typ
des Zielobjekts
• Variable v in typeTest(Vehicle5 v) hat Typ Vehicle
• Klasse Vehicle5 definiert Methode getInfo () und daher wird Aufruf
akzeptiert
• Zur Laufzeit wird Methodenaufruf dynamisch gebunden
• Aktueller Typ von v wird herangezogen, um tatsächliche Methode zu
bestimmen
• Wenn Methode nicht überschrieben wurde, wird entsprechende
Methode aus Superklasse aufgerufen
• Beispiel: typeTest(new Truck5(...)) wird getInfo () aus Truck5
ausführen
RT (ICS @ UIBK)
Programmiermethodik
230/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Statisches Binden
• In bestimmten Situationen werden Methoden statisch (und nicht
dynamisch) gebunden
• Statische Methoden
• Gehören zu Klasse und nicht zu Objekt
• Konstruktoren
• Objekt muss erst vom Konstruktor erzeugt werden
• Private Methoden
• Sind in Subklasse nicht sichtbar
• Neue Definition einer privaten Methode ist keine Redefinition
• Binden von Datenelementen
• Datenelemente werden statisch gebunden
• Beim Zugriff wird der statische Typ herangezogen
• Datenelemente werden aber geerbt
RT (ICS @ UIBK)
Programmiermethodik
231/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Beispiel
public class
protected
}
public class
protected
}
public class
}
Base {
int data = 1;
Sub extends Base {
int data = 2;
Sub2 extends Sub {
public c l a s s Test {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
Base x = new Sub ( ) ;
Sub2 s = new Sub2 ( ) ;
System . o u t . p r i n t l n ( x . d a t a ) ;
System . o u t . p r i n t l n ( s . d a t a ) ;
}
}
RT (ICS @ UIBK)
Programmiermethodik
232/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
final bei Methoden und Klassen
• final als Attribut bei Methode
• Methode kann in Subklasse nicht überschrieben werden
• dynamisches Binden wird unterbunden
• final als Attribut bei Klasse
• es kann keine Subklasse gebildet werden
• alle Methoden sind automatisch final
• Beispiele: String, StringBuilder
RT (ICS @ UIBK)
Programmiermethodik
233/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Kovarianz, Kontravarianz, Invarianz
• Fragestellung: Was darf beim Überschreiben verändert werden?
• Kovarianz
• Redefinition von Parameter- und Ergebnistypen mit Subtypen
• Kontravarianz
• Redefinition von Parameter- und Ergebnistypen mit Supertypen
• Invarianz
• Typen bleiben gleich
• Java (seit Version 1.5)
• Kovarianz bei Ergebnistypen
• Sonst Invarianz
RT (ICS @ UIBK)
Programmiermethodik
234/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Kovarianter Ergebnistyp
• Kovariante Ergebnistypen erlauben kompatiblen Ergebnistyp beim
Überschreiben von Methoden und bei Implementierung von
Interfacemethoden
• Beispiele
• Interface:
iterator () in LinkedList liefert RemovableIterator, während iterator ()
in Interface Container Rückgabetyp Iterator hat
• Überschreiben:
class A {
p u b l i c A getCopy ( ) { . . . }
}
c l a s s B extends A {
p u b l i c B getCopy ( ) { . . . }
}
RT (ICS @ UIBK)
Programmiermethodik
235/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Vererbung der Implementierung und Redundanzen
• Vorteil der Vererbung der Implementierung
• Methoden müssen nicht neu implementiert werden
• Redundanzen im Quellcode werden vermieden
• Aber
• Vererbung legt starre Struktur fest
• Erweiterungen sind mit Aufwand verbunden
RT (ICS @ UIBK)
Programmiermethodik
236/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Probleme
• Klasse B kann Funktionalität der Klasse A nutzen durch
• Vererbung (B erbt von A)
• Beziehung (Assoziation zwischen B und A, B benutzt A)
• Falle
• Vererbung erscheint einfacher
• Aber nicht immer sinnvoll
• Prinzip der Ersetzbarkeit sollte immer gelten
RT (ICS @ UIBK)
Programmiermethodik
237/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Ersetzbarkeitsprinzip - Bedingungen
• Unterklasse kann Vorbedingungen für Operation, die in Oberklasse
definiert werden, einhalten oder abschwächen, aber nicht verschärfen
• Unterklasse kann Nachbedingungen für Operation, die in Oberklasse
definiert werden, einhalten oder erweitern, aber nicht einschränken
• Unterklasse muss dafür sorgen, dass für Oberklasse definierten
Invarianten immer gelten
• Verhaltensänderung ist aber erlaubt!
RT (ICS @ UIBK)
Programmiermethodik
238/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Beispiel: Einhaltung des Ersetzbarkeitprinzips
• Container bietet Einfügen und Iterator an
• Bedingungen: Iterator muss über alle Elemente iterieren, die bislang
eingefügt (und nicht entfernt) wurden
• Klasse Tree implementiert Container-Schnittstelle
• unbalanciert
• preorder-Iterator
• Klasse BalancedTree erbt von Tree
• neue Zusatzeigenschaft: Einfügen in logarithmischer Zeit
• Verhaltensänderung bei Iterator
RT (ICS @ UIBK)
Programmiermethodik
239/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Beispiel: Verletzung des Prinzips der Ersetzbarkeit
public class Rectangle {
double w i d t h ;
double h e i g h t ;
p u b l i c v o i d s c a l e W i d t h ( double f a c t o r ) { . . . }
p u b l i c v o i d s c a l e H e i g h t ( double f a c t o r ) { . . . }
p u b l i c v o i d s c a l e ( double f a c t o r ) { . . . }
...
}
p u b l i c c l a s s S q u a r e extends R e c t a n g l e {
// i n v a r i a n t : w i d t h = h e i g h t
}
• Problem: Quadrat kann nicht wie Rechteck benutzt werden
• Beispiel:
R e c t a n g l e r = new S q u a r e ( 5 . 0 ) ;
r . scaleWidth (2);
RT (ICS @ UIBK)
Programmiermethodik
240/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Problem der instabilen Basisklasse
• Falls das Prinzip der Ersetzbarkeit gilt?
• Alles ok?
• Gilt das auch in Zukunft?
• Problem der instabilen Basisklasse (Fragile Base Class Problem)
• Anpassungen an Basisklasse können zu unerwartetem Verhalten von
abgeleiteten Klassen führen
⇒ Wartung von Systemen, die nur Vererbung der Implementierung
benutzen, ist schwierig
• Sind spätere Änderungen an der Basisklasse sehr wahrscheinlich:
• Vererbung der Spezifikation (und nicht der Implementierung)
• Wenn man Redundanzen vermeiden möchte - Delegation
RT (ICS @ UIBK)
Programmiermethodik
241/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Delegation
• Objekt setzt Operation so um, dass Aufruf der Operation an anderes
Objekt delegiert (weitergereicht) wird
• Verantwortung, Implementierung für bestimmte Schnittstelle
bereitzustellen, wird an Exemplar einer anderen Klasse delegiert
• Vorteil
• Kann mit Vererbung der Spezifikation gemeinsam benutzt werden
(Quellcode einsparen)
• Auch ohne Mehrfachvererbung kann Funktionalität von mehreren
Klassen benutzt werden
• Dynamisch (Delegat kann zur Laufzeit geändert werden)
• Beispiel: Well.java, WellTest.java, . . .
RT (ICS @ UIBK)
Programmiermethodik
242/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
”is-a” vs. ”has-a”
• ”B ist ein A” ⇒ B wird von A abgeleitet
• ”B enthält ein A” ⇒ B definiert Objektvariable vom Typ A
• Beispiel
• 2 Klassen Dreieck und Punkt
• Dreieck ist ein Punkt – Falsch
• Dreieck enthält einen Punkt – Richtig
⇒ Klasse Dreieck verwendet Klasse Punkt (Objektvariable vom Typ Punkt)
• 2 Klassen Dreieck und Polygon
• Dreieck ist ein Polygon – Richtig
• Dreieck enthält ein Polygon – Falsch
⇒ Dreieck wird von Polygon abgeleitet
RT (ICS @ UIBK)
Programmiermethodik
243/613
Vererbung und Polymorphismus
Vererbung der Implementierung in Java
Abstraktionsebenen
• Vererbung einsetzen, wenn Superklasse und Subklasse konzeptionell
auf unterschiedlichen Abstraktionsebenen stehen
• Klassenname ist umgangssprachlich ein Oberbegriff des anderen
Klassennamens
• Beispiel
RT (ICS @ UIBK)
Programmiermethodik
244/613
Vererbung und Polymorphismus
Abstrakte Klassen
Übersicht
Vererbung und Polymorphismus
Vererbung Allgemein
Vererbung der Spezifikation in Java
Vererbung der Implementierung in Java
Abstrakte Klassen
Die Klasse Object
RT (ICS @ UIBK)
Programmiermethodik
245/613
Vererbung und Polymorphismus
Abstrakte Klassen
Abstrakte Klassen
• Konkrete Superklassen und Interfaces bilden zwei Extreme
• Abstrakte Klassen bilden Mittelweg
• Enthalten Objektvariablen
• Enthalten vollständige Methoden
• Enthalten Schnittstellen (abstrakte Methoden)
• Abstrakte Klasse wird mit dem Schlüsselwort abstract markiert
• Zusätzlich werden abstrakte Methoden mit abstract gekennzeichnet
• Abstrakte Klasse muss keine abstrakten Methoden enthalten
• Wenn Klasse ein Interface nicht vollständig implementiert, dann muss
sie abstrakte Klasse sein
RT (ICS @ UIBK)
Programmiermethodik
246/613
Vererbung und Polymorphismus
Abstrakte Klassen
Vererbung bei abstrakten Klassen
• Von abstrakter Klasse können keine Objekte angelegt werden
• Subklasse muss alle abstrakten Methoden implementieren, damit man
von Subklasse Objekte anlegen kann
• Implementiert Subklasse nur Teil (oder keine) der abstrakten
Methoden, dann ist sie auch abstrakte Klasse
• In Subklasse können neue Methoden definiert und Methoden
überschrieben werden
• Auch super kann verwendet werden
• Beispiel: siehe Folie 247
RT (ICS @ UIBK)
Programmiermethodik
247/613
Vererbung und Polymorphismus
Abstrakte Klassen
Beispiel
p u b l i c a b s t r a c t c l a s s D e f a u l t S t a c k implements S t a c k {
// p r o v i d e d e f a u l t i m p l e m e n t a t i o n f o r p e e k
public Object peek ( ) {
O b j e c t o = t h i s . pop ( ) ;
t h i s . push ( o ) ;
return o ;
}
// l e a v e r e m a i n i n g s t a c k o p e r a t i o n s open
// f o r c o n c r e t e c l a s s e s
p u b l i c a b s t r a c t O b j e c t pop ( ) ;
p u b l i c a b s t r a c t boolean i s E m p t y ( ) ;
p u b l i c a b s t r a c t v o i d push ( O b j e c t o b j ) ;
}
RT (ICS @ UIBK)
Programmiermethodik
247/613
Vererbung und Polymorphismus
Abstrakte Klassen
Vergleich: Abstrakte Klasse - Interface
• Unterschiede: Abstrakte Klassen bieten . . .
• . . . abstrakte Methoden mit Zugriffsschutz protected und default
(in Interface: alles public)
• . . . Objektvariablen (nicht nur Konstanten)
• . . . konkrete Methoden
• . . . Konstruktoren, die von den Subklassen benutzt werden
• Rein abstrakte Klassen sind möglich
• Keine Objektvariablen
• Nur abstrakte Methoden
• Wozu dann Interfaces?
• In Java: nur Einfachvererbung bei Klassen
RT (ICS @ UIBK)
Programmiermethodik
248/613
Vererbung und Polymorphismus
Abstrakte Klassen
Subtyping und Subclassing
• Subtyping
• Wenn eine Klasse ein Interface implementiert
(von diesem Interface “erbt”)
• Es wird nur der Typ “geerbt”
• Subclassing
• Wenn eine Klasse von einer andere Klasse erbt
• Es wird die Implementierung geerbt
RT (ICS @ UIBK)
Programmiermethodik
249/613
Vererbung und Polymorphismus
Abstrakte Klassen
Varianten der Vererbung (Zusammenfassung)
• Reine Vererbung der Spezifikation
• Schnittstellen-Klassen (Interfaces in Java)
• Vererbung der Spezifikation und Implementierung
• Normalfall (auch in Java)
• Unterklasse erbt Spezifikation und Implementierung
• Reine Vererbung der Implementierung
• Unterklasse übernimmt Implementierung, nicht Spezifikation
• Für interne Nutzung (z.B. private Vererbung in C++)
RT (ICS @ UIBK)
Programmiermethodik
250/613
Vererbung und Polymorphismus
Die Klasse Object
Übersicht
Vererbung und Polymorphismus
Vererbung Allgemein
Vererbung der Spezifikation in Java
Vererbung der Implementierung in Java
Abstrakte Klassen
Die Klasse Object
RT (ICS @ UIBK)
Programmiermethodik
251/613
Vererbung und Polymorphismus
Die Klasse Object
Die Wurzelklasse Object
• Jede Klasse, die von keiner Klasse erbt, erbt automatisch von der
Wurzelklasse Object
⇒ Folgende Definitionen sind äquivalent
• public class ClassName { ... }
• public class ClassName extends Object { ... }
• Damit werden alle Klassen direkt oder indirekt von Object abgeleitet
RT (ICS @ UIBK)
Programmiermethodik
252/613
Vererbung und Polymorphismus
Die Klasse Object
Vordefinierte Methoden
• Object bietet einige Methoden an
⇒ Diese Methoden werden an jede Java-Klasse vererbt
• Beispiele
• public String toString ()
•
•
•
•
Liefert lesbare Repräsentation des Objekts
(analog getInfo () im KFZ-Beispiel)
public boolean equals(Object x)
Prüft ob aktuelles Objekt und x gleich sind
public int hashCode()
Liefert Kennnummer (Hashcode) des Objekts
protected Object clone()
Liefert Kopie des Objekts
protected void finalize ()
Wird vom Garbage Collector aufgerufen
RT (ICS @ UIBK)
Programmiermethodik
253/613
Vererbung und Polymorphismus
Die Klasse Object
Object: vollständige Methodenliste
p u b l i c f i n a l n a t i v e C l a s s <?> g e t C l a s s ( ) ;
p u b l i c n a t i v e i n t hashCode ( ) ;
p u b l i c boolean e q u a l s ( O b j e c t o b j ) { . . . }
protected native Object c l o n e ( )
throws C l o n e N o t S u p p o r t e d E x c e p t i o n ;
public String toString () { . . . }
public f i n a l native void n o t i f y ( ) ;
public f i n a l native void n o t i f y A l l ( ) ;
public f i n a l void wait ( )
throws I n t e r r u p t e d E x c e p t i o n { . . . }
p u b l i c f i n a l n a t i v e v o i d w a i t ( long t i m e o u t )
throws I n t e r r u p t e d E x c e p t i o n ;
p u b l i c f i n a l v o i d w a i t ( long t i m e o u t , i n t n a n o s )
throws I n t e r r u p t e d E x c e p t i o n { . . . }
protected void f i n a l i z e ( )
throws Thr owab le { . . . }
RT (ICS @ UIBK)
Programmiermethodik
254/613
Vererbung und Polymorphismus
Die Klasse Object
Implementierungen in der Klasse Object
• Minimale Implementierung
• Methoden sollten in jeder Klasse entsprechend überschrieben werden
• Wenn Methoden nicht überschrieben werden, wird minimale
Implementierung aus Object verwendet
• Beispiele
• toString gibt Namen der Klasse zusammen mit Hashcode aus
public String toString () {
r e t u r n g e t C l a s s ( ) . getName ( ) + "@"
+ I n t e g e r . t o H e x S t r i n g ( hashCode ( ) ) ;
}
• equals vergleicht nur Referenzen
p u b l i c boolean e q u a l s ( O b j e c t o b j ) {
r e t u r n ( t h i s == o b j ) ;
}
RT (ICS @ UIBK)
Programmiermethodik
255/613
Vererbung und Polymorphismus
Die Klasse Object
toString
• Sinn: benutzerdefinierte Ausgabe eines Objekts
• Spezielle Unterstützung in Kombination mit +
• in someString + obj wird automatisch obj zu obj . toString () expandiert
• Beispiel
c l a s s Person {
private String firstName ;
private S t r i n g lastName ;
...
public String toString () {
return f i r s t N a m e + " " + lastName ;
}
}
P e r s o n p = new P e r s o n ( " Hans " , " Mustermann " ) ;
...
S t r i n g o u t p u t = "The current person is " + p ;
RT (ICS @ UIBK)
Programmiermethodik
256/613
Vererbung und Polymorphismus
Die Klasse Object
Typobjekte / getClass()
• Typobjekte: genutzt für Java Reflection – siehe Entwurf von
Softwaresystemen
• Jedem Typ ist ein eindeutiges Typobjekt zugeordnet
• Zugriff in Form: Type.class
• Beispiel: System.out. println ( String . class) liefert
"class java.lang.String"
• Typobjekt eines Objekts obj kann mit obj . getClass () ermittelt
werden
• Beispiel: System.out. println ("Hello".getClass ()); liefert
"class java.lang.String"
RT (ICS @ UIBK)
Programmiermethodik
257/613
Vererbung und Polymorphismus
Die Klasse Object
equals
• Default-Implementierung vergleicht nur Referenzen
• korrekte Implementierung erfüllt
• Reflexivität
• x. equals(x)
• Symmetrie
• x. equals(y) ⇒ y. equals(x)
• Transitivität
• x. equals(y) ⇒ y. equals(z) ⇒ x. equals(z)
• Konsistenz
• Objekte müssen bei wiederholten Aufrufen von equals immer gleiches
Ergebnis liefern, solange sie sich nicht verändert haben
• Alle Objekte sind von null verschieden
• ! x. equals( null )
RT (ICS @ UIBK)
Programmiermethodik
258/613
Vererbung und Polymorphismus
Die Klasse Object
Probleme mit equals
• Überladen vs. Überschreiben (siehe Circle1.java, Circle2.java)
• Probleme bei der Vererbung (siehe (Colored)Circle2.java,
(Colored)Circle3.java)
• Lösung 1: Verlange Typ-Gleichheit (siehe (Colored)Circle4.java)
• Lösung 2: fixiere Vergleich in Oberklasse (siehe (Colored)Circle5.java)
• Beachte instanceof in Kombination mit Lösung 2: trotz Gleichheit
mittels equals kann Unterschied bei instanceof auftreten (siehe
testInstanceof )
RT (ICS @ UIBK)
Programmiermethodik
259/613
Vererbung und Polymorphismus
Die Klasse Object
hashCode
• Für jedes Objekt sollte eindeutige Kennnummer produziert werden
(nicht immer möglich)
• Wird im Collection-Framework (später) benutzt
• Anforderungen
• Hashcode muss immer gleich bleiben, solange sich Objekt nicht ändert
• Wenn Objekte gemäß equals gleich sind, muss hashCode gleiches
Resultat liefern
• Umkehrung gilt nicht, d.h. Objekte können gleichen Hashcode haben,
aber verschieden sein
RT (ICS @ UIBK)
Programmiermethodik
260/613
Vererbung und Polymorphismus
Die Klasse Object
hashCode und equals
• equals und hashCode hängen zusammen und sollten immer gemeinsam
überschrieben werden
• equals und hashCode sollten immer die gleichen Objektvariablen
verwenden
• man kann immer die hashCode-Methode von Referenzen verwenden
(falls implementiert)
• schlechte Beispiele: (Colored)Circle 2 / 3
• gute Beispiele: (Colored)Circle 4 / 5
RT (ICS @ UIBK)
Programmiermethodik
261/613
Vererbung und Polymorphismus
Die Klasse Object
clone
• Kopier-Konstruktor eignet sich zum Kopieren eines Objekts ohne
Vererbung
( Circle c1 = new Circle(2.5); ...; Circle c2 = new Circle(c1); )
• Kopieren bei dynamischen Typ kann nur durch dynamisch gebundene
Methode erfolgen: clone
C i r c l e c1 = new C o l o r e d C i r c l e ( 2 . 5 , RED ) ;
...;
C i r c l e c2 = new C i r c l e ( c1 ) ; // wrong
C i r c l e c2 = c1 . c l o n e ( ) ; // ok
• clone hat den Zugriffsschutz protected
• Damit kann clone nicht von außen aufgerufen werden
• Beim Überschreiben muss Zugriffsschutz auf public gelockert werden
RT (ICS @ UIBK)
Programmiermethodik
262/613
Vererbung und Polymorphismus
Die Klasse Object
Regeln für clone
• Klasse muss
• Interface Cloneable implementieren
• eigene öffentliche Methode clone () implementieren
• in clone Kopie des Superklassenobjekts mit super.clone() erzeugen
• in clone alle Datenelemente veränderlicher Klassen einzeln mit
clone-Aufrufen kopieren
• clone kann nur verwendet werden, wenn jede verwendete Klasse clone
korrekt implementiert
• Beispiel: Address, Person, Teacher, CloneTest.java
RT (ICS @ UIBK)
Programmiermethodik
263/613
Ausnahmebehandlung
Übersicht
Ausnahmebehandlung
Assertions
Ausnahmen (Exceptions)
RT (ICS @ UIBK)
Programmiermethodik
264/613
Ausnahmebehandlung
Motivation
• Programme müssen Fehlersituationen erkennen und kontrolliert darauf
reagieren
• In Java
• Assertions für Absicherung der inneren Programmlogik
• Exceptions für Einhalten beliebiger Randbedingungen
RT (ICS @ UIBK)
Programmiermethodik
265/613
Ausnahmebehandlung
Assertions
Übersicht
Ausnahmebehandlung
Assertions
Ausnahmen (Exceptions)
RT (ICS @ UIBK)
Programmiermethodik
266/613
Ausnahmebehandlung
Assertions
Assertions allgemein
• Assertion (Zusicherung) ist Boolescher-Ausdruck, der immer zutreffen
muss
• Assertions werden beim Programmablauf von JVM überwacht
• Programmabbruch, wenn Assertion nicht zutrifft
• Assertions sind Ausdrücke
• Form assert expr ; oder assert expr : string ;
• expr muss immer true liefern, string enthält Fehlermeldung
• Beispiele
• assert a <= b && b <= c;
• assert x >= 0: "negative x";
RT (ICS @ UIBK)
Programmiermethodik
267/613
Ausnahmebehandlung
Assertions
Arbeitsweise
• Assertions werden zur Laufzeit ausgewertet
• Wenn Ergebnis false ist, stoppt Programm mit AssertionError
• Nachfolgenden Anweisungen werden dann nicht mehr ausgeführt
• Bei Abbruch wird Information über Ort der gescheiterten Assertion
ausgegeben
RT (ICS @ UIBK)
Programmiermethodik
268/613
Ausnahmebehandlung
Assertions
Aktivierung
•
•
•
•
•
Assertions kosten Rechenzeit
Können zur Laufzeit wahlweise aktiviert werden
Deaktiviert sind sie automatisch!
Programm muss nicht neu übersetzt werden
Aktivierung im Programm Test:
java −ea Test
• Deaktivierung (default):
java −da Test
• Normalerweise aktiviert während Entwicklungszeit
• Aktivierung kann zur Laufzeit festgestellt werden
s t a t i c f i n a l boolean ASSERTIONS_ENABLED ;
static {
boolean a c t i v e = f a l s e ;
assert ( a c t i v e = true ) ;
ASSERTIONS_ENABLED = a c t i v e ;
}
RT (ICS @ UIBK)
Programmiermethodik
269/613
Ausnahmebehandlung
Assertions
Einsatz von Assertions
• Sind für Bedingungen geeignet, deren Einhaltung vom Programm
selbst garantiert werden kann
• Z.B. am Ende von Methode Rechenergebnisse prüfen
• Nicht für Bedingungen geeignet, die von äußeren Einflüssen abhängen
• Z.B. am Anfang von öffentlicher Methode Werte der Parameter
überprüfen
RT (ICS @ UIBK)
Programmiermethodik
270/613
Ausnahmebehandlung
Assertions
Anwendung
• Überprüfung von Parametern, die an nicht-öffentliche Methoden
übergeben werden (nur falsch, wenn eigenes Programm fehlerhaft)
• Verwendung in Postconditions, die am Ende einer Methode erfüllt sein
müssen
• Überprüfung von Schleifeninvarianten
• Markierung von “toten Zweigen” in if - oder case-Anweisungen, die
normalerweise niemals erreicht werden sollten (Assertion mit false als
Argument)
RT (ICS @ UIBK)
Programmiermethodik
271/613
Ausnahmebehandlung
Assertions
public class AssertionTest {
p r i v a t e s t a t i c i n t max ( f i n a l i n t x , f i n a l i n t y ) {
return x < y ? x : y ;
}
p r i v a t e s t a t i c i n t min ( f i n a l i n t x , f i n a l i n t y ) {
return x > y ? x : y ;
}
private s t a t i c void t e s t ( f i n a l i n t x , f i n a l i n t y ) {
i n t maximum = A s s e r t i o n T e s t . max ( x , y ) ;
i n t minimum = A s s e r t i o n T e s t . min ( x , y ) ;
a s s e r t maximum >= minimum : "max < min" ;
System . o u t . p r i n t l n ( maximum + " " + minimum ) ;
}
p u b l i c s t a t i c v o i d main ( f i n a l S t r i n g [ ] a r g s ) {
AssertionTest . t e s t (10 , 15);
AssertionTest . t e s t (8 , 3);
AssertionTest . t e s t (2 , 2);
}
RT }(ICS @ UIBK)
Programmiermethodik
272/613
Ausnahmebehandlung
Assertions
Private Invarianten-Methoden
• Objektvariablen dürfen meist nicht beliebige Werte annehmen
• Es gelten bestimmte Bedingungen
• Bedingungen werden als Klasseninvarianten bezeichnet
• Bedingungen gelten für jedes Objekt der Klasse
• Bedingungen können während Ausführung einer Methode kurzfristig
verletzt werden
• Vor dem Aufruf und nach der Rückkehr müssen die Invarianten immer
gelten
• Klasseninvarianten können komplex sein
• Mehrere Objektvariablen müssen berücksichtigt werden
• Test kann aufwändig sein
• Muss möglicherweise an vielen Stellen erfolgen
• Private Invarianten-Methoden
• Test der Klasseninvarianten wird in Boolean-Methode gegeben
• Enthält keine Assertions
• Wird in anderen Methoden bei Assertions verwendet
RT (ICS @ UIBK)
Programmiermethodik
273/613
Ausnahmebehandlung
Assertions
Beispiel
public class Rational {
p r i v a t e i n t denom ;
...
p r i v a t e boolean i n v a r i a n t H o l d s
r e t u r n denom != 0 ;
}
...
public void reduce ( ) {
...
assert this . invariantHolds
}
...
public void m u l t i p l y ( R a t i o n a l
...
assert this . invariantHolds
}
}
RT (ICS @ UIBK)
Programmiermethodik
() {
();
other ) {
();
274/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Übersicht
Ausnahmebehandlung
Assertions
Ausnahmen (Exceptions)
RT (ICS @ UIBK)
Programmiermethodik
275/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Motivation
• In laufendem Programm können Fehler auftreten
• Logische Fehler im Programm
• Fehlerhafte Bedienung
• Probleme im Java-Laufzeitsystem
• ...
• Exceptions (Ausnahmen) sind ein Sprachmittel zur kontrollierten
Reaktion auf Laufzeitfehler
• Assertions sind Sonderfall davon
RT (ICS @ UIBK)
Programmiermethodik
276/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Exceptions
• 2 Vorteile durch Exceptions
• Fehler (und Exceptions) können nicht ignoriert werden ⇒ erfordert
Maßnahmen zur Behandlung
• Code für Programmablauf und Fehlerbehandlung wird getrennt
• Exception-Handling
• Ausnahmesituationen werden an bestimmten Punkten im Programm
geprüft (und gemeldet)
• An anderen Stellen steht Code zur Reaktion auf potenzielle
Ausnahmesituationen
RT (ICS @ UIBK)
Programmiermethodik
277/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Grundprinzip der Ausnahmebehandlung
• Information über Ausnahme wird in spezielles Objekt verpackt
• Instanz der Klasse Exception (oder einer Subklasse davon)
• Ausnahme kann auch explizit ausgelöst werden (mittels throw)
• Ausnahme kann an bestimmter Stelle (äußerer Block, aufrufende
Methode etc.) in einer catch-Klausel abgefangen werden
• Grundkonstrukt: try-catch-Anweisung
RT (ICS @ UIBK)
Programmiermethodik
278/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Die try-catch Anweisung (Grundform)
• Schema
try {
...
n o r m a l e r Code
...
} catch ( E x c e p t i o n T y p e 1 e ) {
. . . Fehlerbehandlung . . .
} catch ( E x c e p t i o n T y p e 2 e ) {
. . . Fehlerbehandlung . . .
} catch . . . {
...
} catch ( E x c e p t i o n T y p e x e ) {
. . . Fehlerbehandlung . . .
}
RT (ICS @ UIBK)
Programmiermethodik
279/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Ablauf
try {
stmtA ;
• Normalfall (keine Fehler in stmtABC):
stmtB ;
Ausführung von stmtABCD
stmtC ;
} catch ( E1 e ) { • Ausnahme E1 in stmtB:
Ausführung von stmtAB1D
stmts1 ;
} catch ( E2 e ) { • Ausnahme E2 in stmtB:
stmst2 ;
Ausführung von stmtAB2D
} catch ( E3 e ) { • Ausnahme E4 in stmtB:
stmst3 ;
Ausführung von stmtAB, E4 muss an anderer
}
Stelle behandelt werden
stmtD ;
RT (ICS @ UIBK)
Programmiermethodik
280/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Ablauf
• Wird Ausnahme vom Typ E geworfen
• Dann wird entsprechende catch-Klausel vom Typ E gesucht
• Statt E kann auch Klausel mit Superklasse von E verwendet werden, da
E dort substituiert werden kann
• Reihenfolge der catch-Klauseln ist entscheidend
• Ausnahme wird der Reihe nach mit catch-Klauseln verglichen
• Ausgeführt wird catch-Klausel, zu der Ausnahme kompatibel ist
• Nachfolgende catch-Klauseln werden ignoriert
⇒ Ordnung der catch-Klauseln sollte beachtet werden:
von speziell zu allgemein
• Wenn zuerst allgemeinere Ausnahme angegeben wird (und danach
speziellere), dann kommt es zu Compile-Fehler
RT (ICS @ UIBK)
Programmiermethodik
281/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Ablauf
• Falls keine catch-Klausel gefunden wird, wird in äußeren try-Blöcken
gesucht
• In verschachtelten try-Blöcken
• Entlang der Methodenaufrufkette
• Wird niemals catch-Klausel gefunden (auch nicht in main), dann
bricht Programm ab
RT (ICS @ UIBK)
Programmiermethodik
282/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
public class ExceptionTest {
p u b l i c s t a t i c v o i d main ( f i n a l S t r i n g [ ] a r g s ) {
try {
int x , y ;
x = Integer . parseInt ( args [ 0 ] ) ;
y = Integer . parseInt ( args [ 1 ] ) ;
System . o u t . p r i n t l n ( x / y ) ;
} catch ( NumberFormatException e ) {
System . o u t . p r i n t l n ( "no integer number " ) ;
// a d d i t i o n a l e r r o r h a n d l i n g
} catch ( A r r a y I n d e x O u t O f B o u n d s E x c e p t i o n e ) {
System . o u t . p r i n t l n ( " provide 2 parameters " ) ;
// a d d i t i o n a l e r r o r h a n d l i n g
} catch ( A r i t h m e t i c E x c e p t i o n e ) {
System . o u t . p r i n t l n ( " division by 0" ) ;
// a d d i t i o n a l e r r o r h a n d l i n g
}
}
RT }(ICS @ UIBK)
Programmiermethodik
283/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Termination Model / Resumption Model
• Termination Model
• Kontrollfluss kehrt nicht mehr an Stelle zurück, an der Ausnahme
aufgetreten ist
• Die Ausnahmebehandlung in Java folgt dem Termination-Model
• Resumption Model
• Alternative zum Termination Model
• Es erfolgt Rückkehr zur Aufrufstelle, d.h. nach Fehlerbehandlung wird
Programm an der Stelle der Ausnahme fortgesetzt
• Wird nicht in Java verwendet
RT (ICS @ UIBK)
Programmiermethodik
284/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Arten von Ausnahmen
• Systemausnahmen
• Werden automatisch ausgelöst (illegale Instruktionen)
• Beispiele
• ArithmeticException (bei Division durch 0)
• NullPointerException (Zugriff auf null -Referenz)
• ArrayIndexOutOfBoundsException (Arrayindex außerhalb des erlaubten
Bereichs)
• Können abgefangen werden, müssen es aber nicht
• Benutzerausnahmen
• Müssen explizit vom Programmierer ausgelöst werden
(mittels throw-Anweisung)
• Java-Bibliothek enthält schon häufige Fehlerarten
(z.B. java . io .IOException)
• Zusätzlich kann man eigene Ausnahme-Klassen implementieren und
verwenden
• Müssen abgefangen werden
RT (ICS @ UIBK)
Programmiermethodik
285/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Exception-Klassen
• Ausnahmen sind in Java Objekte
• Enthalten Informationen über aufgetretene Fehler
• Bieten Methoden an, um auf Informationen zuzugreifen
• Alle Ausnahmen sind in Klassenhierarchie gruppiert
• Allgemeine Klasse Exception
• Diverse Unterklassen für spezifische Ausnahmen
• Dient zur Differenzierung
• catch-Klausel, die Klasse E behandeln kann, kann auch alle
Unterklassen von E behandeln
RT (ICS @ UIBK)
Programmiermethodik
286/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Hierarchie
• Oberste Klasse ist Throwable
• Enthält Methoden zur Fehleranalyse
• String getMessage(): Text bei Ausnahme
• String toString (): Klassenname + getMessage
• void printStackTrace ()
• diverse Konstruktoren (leer, mit Fehlermeldung, . . . )
• Unterklassen
• Error
• irreparable Fehler
• Exception
• Fehler, die sinnvoll behandelt werden können
• Existenz von Subklassen zur Fehlerbehandlung
RT (ICS @ UIBK)
Programmiermethodik
287/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Error
• Error sind Fehler, die mit JVM in Verbindung stehen
• Beispiel: Zu wenig Speicher für die JVM bei Objekterzeugung
vorhanden ⇒ OutOfMemoryError
• Da Fehler “abnormales” Verhalten anzeigen, müssen sie nicht mit
catch-Klausel aufgefangen werden
• Wie Systemausnahmen können sie abgefangen werden
• Auffangen macht meist wenig Sinn: Wie sollte man auf Fehler
reagieren?
RT (ICS @ UIBK)
Programmiermethodik
288/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Exception-Hierarchie
• Exception
• RuntimeException, Systemausnahmen (Unchecked Exceptions)
•
•
•
•
•
ArithmeticException
NullpointerException
IndexOutOfBoundsException
MyRuntimeException
...
ab hier: Benutzerausnahmen (Checked Exceptions)
• java . io .IOException
• java . io .FileNotFoundException
• ...
• InterruptedException
• MyException
• ...
RT (ICS @ UIBK)
Programmiermethodik
289/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Eigene Klasse / Ausnahme auslösen
• Von Klasse Exception oder RuntimeException ableiten
c l a s s MyExcept io n extends E x c e p t i o n {}
(Hat nur einen Defaultkonstruktor)
• Wenn man Nachricht mitgeben möchte
c l a s s MyExcept io n extends E x c e p t i o n {
p u b l i c MyE xc e pt io n ( ) {}
p u b l i c MyE xc e pt io n ( S t r i n g i n f o ) {
super ( i n f o ) ;
}
}
• Auslösen (“Werfen”) einer Ausnahme mit throw-Anweisung
throw new MyE xc e pt io n ( ) ;
throw new MyE xc e pt io n ( " Falsche Eingabe " ) ;
RT (ICS @ UIBK)
Programmiermethodik
290/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Exception-Signatur
• Methoden müssen Ausnahmen nicht lokal behandeln, sondern können
sie weiterreichen
• Benutzer einer Methode muss mit Exception-Signatur darauf
hingewiesen werden
• Form: type methodName(...) throws ExcepType1, ExcepType2, ...
• Zeigt Aufrufer an, dass bestimmte Ausnahme geworfen werden könnte
• Sollte möglichst spezifisch sein
• Wird vom Compiler überprüft
(Fehlende oder falsche Angaben führen zu Compile-Fehler)
• Beispiel: Stack..., ArrayStack.java
RT (ICS @ UIBK)
Programmiermethodik
291/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Ausnahme durchreichen
• Ausnahmen können durchgereicht werden
• Methode generiert Ausnahme nicht selbst, sondern ruft Methode auf,
die Ausnahme generiert
• Methode muss in ihrer Signatur angeben
• Typen der selbst ausgelösten Ausnahmen
• Typen aller Ausnahmen aller aufgerufenen Methoden
• RuntimeException und Subklassen müssen nicht angegeben werden
• Compiler stellt sicher, dass keine Ausnahme von untergeordneter
Methode übersehen wird
• Beispiel: siehe Methode main in StackTest.java
RT (ICS @ UIBK)
Programmiermethodik
292/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Überladen und Überschreiben
• Überladen
• Exception-Signaturen überladener Methoden sind völlig unabhängig
• Unterschiedliche Exception-Signaturen reichen nicht aus, um Methoden
zu überladen
• Überschreiben
• Exception-Signatur darf bei der Redefinition der Methode nicht
erweitert werden (neuer Exceptiontyp), nur verringert
• Bei der Redefinition dürfen in der Exception-Signatur alle Typen
aufscheinen, die zu Typ in der Signatur irgendeiner direkten oder
indirekten Basisklassenmethode kompatibel sind
RT (ICS @ UIBK)
Programmiermethodik
293/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Beispiel
class A {
v o i d f o o ( i n t x ) throws I n t e r r u p t e d E x c e p t i o n { . . . }
v o i d f o o ( S t r i n g s ) throws I O E x c e p t i o n { . . . }
}
c l a s s B extends A {
void foo ( i n t x ) { . . . }
v o i d f o o ( S t r i n g s ) throws
F i l e N o t F o u n d E x c e p t i o n , EOFException { . . . }
}
c l a s s C extends B {
// n o t okay
v o i d b a r ( ) throws I n t e r r u p t e d E x c e p t i o n { . . . }
v o i d b a r ( ) throws I O E x c e p t i o n { . . . }
v o i d f o o ( S t r i n g x ) throws I O E x c e p t i o n { . . . }
}
RT (ICS @ UIBK)
Programmiermethodik
294/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
finally
• try–catch-Block kann nach den catch-Klauseln eine finally -Klausel
enthalten
• Anweisungen in finally -Klausel werden immer als Abschluss der
try-Anweisung ausgeführt, egal ob eine Ausnahme auftrat oder nicht
• Zweck: Arbeiten sauber abschließen, die im try-Block begonnen
wurden
• Beispiel
• Im try-Block wird Datei geöffnet
• Datei muss wieder geschlossen werden
(egal ob bei Verarbeitung der Daten Fehler auftritt oder nicht)
• Auch bei verschachtelten try-Anweisungen möglich
RT (ICS @ UIBK)
Programmiermethodik
295/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Ablauf
try {
stmts0 ;
} catch ( E1 e ) { • Normalfall (keine Fehler in stmts0):
Ausführung von stmt034
stmts1 ;
} catch ( E2 e ) { • Ausnahme E1 in stmts0:
stmst2 ;
Ausführung von stmts0134
} finally {
• Ausnahme E3 in stmts0:
stmst3 ;
Ausführung von stmts013, E3 wird in
}
aufrufender Methode behandelt
s t mt 4 ;
• Beispiel: FinallyTest.java
RT (ICS @ UIBK)
Programmiermethodik
296/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Exception-Chaining
• Wenn Methoden Ausnahmen immer weiterreichen
• Sehr lange Exception-Signaturen
• Detailfehler auf niederer Ebene müssen an ganz anderer Stelle
behandelt werden
• Änderungen in Exception-Signatur zieht viele Veränderungen nach sich
• Lösung: Exception-Chaining
• Mehrere Ausnahmen untergeordneter Aufrufe werden aufgefangen
• Ausnahmen werden zusammengefasst und in neuer Ausnahme
weitergegeben
RT (ICS @ UIBK)
Programmiermethodik
297/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Exception-Chaining Struktur
try {
...
} catch ( E1 ex ) {
throw new MyExcept io n ( ex ) ;
} catch ( E2 ex ) {
throw new MyExcept io n ( ex ) ;
}
Ausnahmen vom Typ E1 und E2 werden in MyException verpackt
RT (ICS @ UIBK)
Programmiermethodik
298/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Chaining bei eigenen Ausnahmen
• Entsprechende Konstruktoren implementieren
• Exception-Klasse gibt Beispiele für solche Konstruktoren
Exception( String message, Throwable cause)
Exception(Throwable cause)
• Beispiel für Konstruktor für die MyException-Klasse
MyException(Throwable cause) { super(cause); }
• Oder initCause -Methode verwenden
catch ( E1 ex ) {
M yException m = new M yE xc e pt io n ( ) ;
m. i n i t C a u s e ( ex ) ;
throw m;
}
• Beispiel: siehe ResourceLoader.java
RT (ICS @ UIBK)
Programmiermethodik
299/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Konstruktoren und Ausnahmen
• Ausnahmen können auch in Konstruktoren verwendet werden
• Fehler beim Anlegen eines Objekts sollten vermieden werden
• Objekt könnte in inkonsistenten Zustand sein
• Konstruktor sollte Ausnahme weiterreichen (throws)
• Aufrufende Methode kann entsprechend auf gescheiterte Erzeugung
des Objekts reagieren
• Beispiel:
public FileReader ( String filename ) throws FileNotFoundException
RT (ICS @ UIBK)
Programmiermethodik
300/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Debugging von Ausnahmen
• Klasse Throwable liefert einige Methoden
• printStackTrace liefert Aufrufstack der Methoden
• getStackTrace - erlaubt Zugriff auf Stack-Trace-Elemente
• getMessage - liefert Fehlerstring einer Ausnahme (wenn vorhanden)
RT (ICS @ UIBK)
Programmiermethodik
301/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Multi-Catch (ab Java 7)
• Manchmal möchte man mehrere Ausnahmetypen gleichartig behandeln
⇒ nur eine catch-Klausel verwenden
⇒ Multi-Catch
• Bei Aufzählung werden einzelnen Ausnahmen mit | getrennt
• Beispiel
try {
...
} catch ( MyExc ep ti on | O t h e r E x c e p t i o n e ) {
...
}
RT (ICS @ UIBK)
Programmiermethodik
302/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Multi-Catch
• Abarbeitung erfolgt wie bei mehreren catch-Blöcken
• Neben Standard-Tests kommen neue Überprüfungen hinzu, ob etwa
gleiche Ausnahme mehrfach in Liste ist oder ob es Widersprüche durch
Mengenbeziehungen gibt
• Beispiel für fehlerhaftes Multi-Catch (Mengenbeziehung)
try {
. . . = new F i l e R e a d e r ( f i l e N a m e ) ;
...
} catch ( F i l e N o t F o u n d E x c e p t i o n | I O E x c e p t i o n e ) {
...
}
RT (ICS @ UIBK)
Programmiermethodik
303/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Final Rethrow (ab Java 7)
• Wenn in catch-Block ein throw stattfindet, ermittelt Compiler die im
try-Block tatsächlich aufgetretenen geprüften Ausnahmetypen
• Im catch genannten Typ für das rethrow wird nicht berücksichtigt
• Statt gefangenen Typ wird Compiler den durch die Codeanalyse
gefundenen Typ beim rethrow melden
RT (ICS @ UIBK)
Programmiermethodik
304/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Beispiel: Final Rethrow
c l a s s E x c e p t i o n A extends E x c e p t i o n {}
c l a s s E x c e p t i o n B extends E x c e p t i o n {}
public c l a s s Test {
p r i v a t e v o i d methodA ( ) throws E x c e p t i o n A {}
p r i v a t e v o i d methodB ( ) throws E x c e p t i o n B {}
p r i v a t e s t a t i c v o i d methodC ( )
throws E x c e p t i o n A , E x c e p t i o n B {
T e s t t = new T e s t ( ) ;
try {
t . methodA ( ) ;
t . methodB ( ) ;
} catch ( E x c e p t i o n e ) {
throw e ;
}
}
}
RT (ICS @ UIBK)
Programmiermethodik
305/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Verwendung von Ausnahmen – Allgemeine Regeln
• Behandlung
• Behandle auftretende Ausnahmen, wenn sinnvoll möglich
• Propagiere im Zweifelsfall Ausnahmen an höhere Aufrufebenen weiter
• Dabei sollte möglichst aussagekräftiger Ausnahmetyp gewählt werden
• Art der Ausnahme
• Wenn Aufrufer außergewöhnliche Situation behandeln kann, so sollte
Benutzerausnahme geworfen werden
• Ist Aufrufer nicht in der Lage, Fehlersituation zu korrigieren, so
verwende Systemausnahme
RT (ICS @ UIBK)
Programmiermethodik
306/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Verwendung von Ausnahmen
• Ausnahmen werden oft für Preconditions verwendet
• Preconditions beziehen sich meist auf Parameter
• Parameter dürfen meist nicht beliebige Werte annehmen
• Ohne Überprüfung kann Objekt in falschem (inkonsistenten) Zustand
sein
• Verwendung von try-catch
• try-catch findet sich meist in übergeordneten Methoden
• Je mehr über aktuellen Programmzustand bekannt ist, desto besser
lässt sich angemessen auf Fehler reagieren
RT (ICS @ UIBK)
Programmiermethodik
307/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Verwendung von Ausnahmen – Eigene Klassen definieren
• Trade-Off
• Viele Einzelklassen
⇒ Feingranulare Behandlung, aber lange Exception-Signaturen oder
catch-Listen
• Wenige Einzelklassen
⇒ Weniger Abfragen, aber schlechte Differenzierung
• Hierarchien aufbauen (Subklassen von Exception oder
RuntimeException)
• Spezielle Klassen für differenzierte Fehlersituationen
• Spezielle Klassen nach Fehlerart gruppieren und mit gemeinsamen
Basisklassen versehen
• Detaillierte Ausnahmen anbieten
• Ausnahme beinhalten weitere Objektvariablen
• Beim Werfen werden Objektvariablen belegt (z.B. mit den falschen
Parameterwerten etc.)
• Damit kann Programmierer auf mehr Information zugreifen
RT (ICS @ UIBK)
Programmiermethodik
308/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Verwendung der verschiedenen Basisklassen
• Abfangen in catch-Klauseln
• Error: nein
• Exception: nein (würde alle Subklassen abfangen), nur Subklassen davon
• RuntimeException: nein, eigentlich Fehler im Programm, der behoben
werden sollte
• Werfen
• Error: ja, eventuell auch eigene Unterklasse
• Exception: nein (zu allgemein), nur Unterklassen
• RuntimeException: ja, aber gerne auch passende Unterklassen
RT (ICS @ UIBK)
Programmiermethodik
309/613
Ausnahmebehandlung
Ausnahmen (Exceptions)
Ausnahmen - Was man nicht machen soll
• Niemals Ausnahme verschwinden lassen
try {
...
} catch ( MyExc ep ti on e ) {}
• Fehler verschwinden nicht von selbst
• Programm wird möglicherweise nicht richtig funktionieren
(inkonsistente Daten etc.)
• Ausnahmen sollten niemals Kontrollstrukturen ersetzen
• Z.B. bei Arraydurchlauf nicht auf Länge überprüfen, sondern auf
Ausnahme warten und dann abfangen
• Rückgabe von null statt Ausnahme im Fehlerfall
• Ausnahmen müssen behandelt werden, null kann ignoriert werden
• Rückgabe von null ist nur in sehr wenigen Fällen sinnvoll
• Muss in aufrufender Methode separat behandelt werden
RT (ICS @ UIBK)
Programmiermethodik
310/613
Pakete und Dokumentation
Übersicht
Pakete und Dokumentation
Pakete
Dokumentation: javadoc
Dokumentation: UML
RT (ICS @ UIBK)
Programmiermethodik
311/613
Pakete und Dokumentation
Pakete
Übersicht
Pakete und Dokumentation
Pakete
Dokumentation: javadoc
Dokumentation: UML
RT (ICS @ UIBK)
Programmiermethodik
312/613
Pakete und Dokumentation
Pakete
Organisation von Klassen
• Grundlegende Bausteine eines Java-Programms sind Klassen
• Erzeugter Bytecode steht in Bytecodedateien
• Einer pro Klasse (auch wenn mehrere Klassen in einer Datei stehen)
• Konvention in Java
• Eine Klasse pro Datei
• Wenn mehrere Klassen in einer Datei vorhanden sind
• Eine Klasse public
• Alle anderen Klassen nicht public
RT (ICS @ UIBK)
Programmiermethodik
313/613
Pakete und Dokumentation
Pakete
Komplexität
• Große Programme beinhalten viele Klassen
• Probleme
• Orientierung
• Namenskonflikte
• Verwaltung von Teilmengen
• Lösung in Java
• Pakete
RT (ICS @ UIBK)
Programmiermethodik
314/613
Pakete und Dokumentation
Pakete
Pakete
• Paket
• Sammlung mehrerer logisch zusammengehörender Klassen
• Regeln
• In einem Paket sollte eine Klasse eindeutig benannt werden
• In unterschiedlichen Paketen kollidieren gleiche Namen nicht
• Pakete werden benannt (wie Variablen etc.)
• Pakete können geschachtelt werden
• Höchstens ein Super-Package
• Pakete bilden Baumstruktur
• Namenskonventionen
• http://www.oracle.com/technetwork/java/
codeconventions-135099.html
• Beispiel:
at.ac.uibk.cl-informatik.thiemann.myproject.mypackage
RT (ICS @ UIBK)
Programmiermethodik
315/613
Pakete und Dokumentation
Pakete
Beispiel
project
frontend
text
datastore
web
• Pakete
• project
• project.frontend
• project.frontend.web
• project.frontend.text
• project.datastore
RT (ICS @ UIBK)
Programmiermethodik
316/613
Pakete und Dokumentation
Pakete
Abbildung auf Dateisystem
• Pakethierarchie kann auf Verzeichnisse im Dateisystem abgebildet
werden.
• Beispiel (Unix)
•
•
•
•
/home/dev
CLASSPATH
project.datastore
Paket
StorageHandler
Klasse
StorageHandler.class
Bytecode für die Klasse
⇒ /home/dev/project/datastore/StorageHandler.class
• CLASSPATH kann mehrere Startverzeichnisse enthalten
• Erste gefundene Datei wird verwendet
• Wenn nur eine Java-Datei vorhanden ist, wird class-Datei automatisch
erzeugt
RT (ICS @ UIBK)
Programmiermethodik
317/613
Pakete und Dokumentation
Pakete
Organisationsschema
• Pakete aus unterschiedlichen Quellen sollten verwendet werden können
• Weltweit einheitliches Benennungsschema
• Orientiert sich an Internet-Domainnamen
• Domainnamen werden von hinten nach vorne auf Pakete und Subpakete
abgebildet
• Beispiel für Innsbruck
• cl-informatik.uibk.ac.at ⇒ at.ac.uibk.cl-informatik
• Ausnahmen
• Standardklassen (z.B. String) - Paket java
• Pakete unter javax
RT (ICS @ UIBK)
Programmiermethodik
318/613
Pakete und Dokumentation
Pakete
Qualifizierte Namen
• Element eines Pakets kann explizit angesprochen werden
• Beispiel: java . util . Arrays . sort (x );
• Ruft sort -Methode in Arrays-Klasse im java.util-Paket auf
(util ist Subpaket)
• Aufruf ähnlich wie Zugriff bei Objekten
• Allgemeines Beispiel a.b.c
• Klasse c im Paket a.b
• Objektvariable c in Objektvariable b des Objekts a
• Klassenvariable c der Klasse b im Paket a
• Wird vom Compiler unterschieden (Kontext)
RT (ICS @ UIBK)
Programmiermethodik
319/613
Pakete und Dokumentation
Pakete
import-Klausel
• Expliziter Aufruf ist umständlich
• Elemente aus fremden Paketen können mit import zugänglich
gemacht werden: import packagepath.classname;
• packagepath ist beliebig langer Paketpfad
• classname bestimmt Klasse
• ∗ statt classname importiert alle Klassen eines Pakets
• import-Klausel steht immer vor Klassendefinition
• Mehrere import-Klauseln sind zulässig (Reihenfolge egal)
• import-Klausel wird vom Compiler ausgewertet
• Subpakete werden nicht automatisch eingebunden
RT (ICS @ UIBK)
Programmiermethodik
320/613
Pakete und Dokumentation
Pakete
package-Klausel
• Legt Paketzugehörigkeit der entsprechenden Quelldatei fest
• Syntax: package packagepath;
• Nur eine Klausel ist zulässig (steht immer vor import-Klauseln)
• Zusätzlich muss Quelldatei in Subdirectory entsprechend
package-Klausel abgelegt werden
RT (ICS @ UIBK)
Programmiermethodik
321/613
Pakete und Dokumentation
Pakete
Default-Package
• Wenn keine package-Klausel angegeben wird (wie bisher)
• Klasse liegt im Default-Package
• Wird auch als anonymes Paket bezeichnet
• Default-Package ist einem Verzeichnis im CLASSPATH zugeordnet
• Default-Package kann nicht importiert werden
RT (ICS @ UIBK)
Programmiermethodik
322/613
Pakete und Dokumentation
Beispiel
Pakete
// A . j a v a
package demo ;
public class A {
...
}
// Demo . j a v a
// d e f a u l t −p a c k a g e
import demo . ∗ ;
import demo . sub . C ;
// B . j a v a
package demo ;
public class B {
...
}
p u b l i c c l a s s Demo {
void t e s t ( ) {
A a = new A ( ) ;
B b = new B ( ) ;
C c = new C ( ) ;
}
}
// C . j a v a
package demo . sub ;
public class C {
...
}
RT (ICS @ UIBK)
Verzeichnisstruktur:
../Demo.java
../demo/A.java
../demo/B.java
../demo/sub/C.java
Programmiermethodik
323/613
Pakete und Dokumentation
Pakete
Namenskollisionen
• Definition im eigenen Paket hat immer Vorrang
• Importieren gleichnamiger Klassen aus anderen Paketen hat keine
Auswirkung
• Konkurrierende Definitionen in verschiedenen fremden Paketen müssen
explizit unterschieden werden (trotz import-Klausel)
RT (ICS @ UIBK)
Programmiermethodik
324/613
Pakete und Dokumentation
Pakete
Statische import-Klausel
• Stellt statisches Element (Objektvariablen, Methoden) einer Klasse so
zur Verfügung, dass es ohne Qualifizierung (Klassennamen) benutzt
werden kann
• Beispiel:
import s t a t i c j a v a . l a n g . Math . PI ;
...
System . o u t . p r i n t l n ( PI + PI ) ; // ohne Math
• Nur sinnvoll, wenn wiederholt gleiches statisches Element aus fremden
Klasse gebraucht wird
• Übermäßiger Gebrauch führt leicht zur Unübersichtlichkeit
RT (ICS @ UIBK)
Programmiermethodik
325/613
Pakete und Dokumentation
Pakete
Default-Zugriffsschutz
• Wird kein Zugriffsschutz angegeben, dann wird Default-Zugriffsschutz
(Package-Zugriffsschutz) verwendet
• Alle Elemente mit Default-Zugriffsschutz können im gemeinsamen
Paket verwendet werden
• Alle Leistungen, die von Klassen in Paket untereinander angeboten
werden, sollten diesen Zugriffsschutz erhalten
• Sollte nur sparsam eingesetzt werden
RT (ICS @ UIBK)
Programmiermethodik
326/613
Pakete und Dokumentation
Pakete
Zugriffsschutz – Zusammenfassung
private
default
protected
public
RT (ICS @ UIBK)
Klasse
3
X
3
3
Paket
7
3
3
3
Subklasse(n)
7
7
3
3
Programmiermethodik
Alle Klassen
7
7
7
3
327/613
Pakete und Dokumentation
Pakete
Archivdateien
• Alternative Organisationsform für Pakete (jar-Dateien)
• Vorteile
• Leicht zusammenzuhalten
• Kompression für effiziente Übertragung
• Können digital signiert werden (oder andere Informationen enthalten)
• Aber höherer Aufwand bei Zugriff
• Können im CLASSPATH aufscheinen
• Sind Einstiegspunkte bei Suche
• Enthalten Pakethierarchie
RT (ICS @ UIBK)
Programmiermethodik
328/613
Pakete und Dokumentation
Pakete
jar-Tool
• Kommandozeilenwerkzeug jar
• Einige Schalter
• Erzeugen (c = create, v = verbose, f = file)
jar cvf jarfile bytecodefile bytecodefile ...
• Inhalt auflisten (t = table of contents)
jar tvf jarfile
• Auspacken (x = extract)
jar xvf jarfile
• Applikationen können direkt aus Archiv gestartet werden
• Jedes jar-Archiv enthält bestimmte Datei (Manifestdatei) mit
Metainformationen
• Man kann Eintrag mit Verweis auf main-Methode generieren
• Dokumentation:
http://docs.oracle.com/javase/tutorial/deployment/jar/
RT (ICS @ UIBK)
Programmiermethodik
329/613
Pakete und Dokumentation
Dokumentation: javadoc
Übersicht
Pakete und Dokumentation
Pakete
Dokumentation: javadoc
Dokumentation: UML
RT (ICS @ UIBK)
Programmiermethodik
330/613
Pakete und Dokumentation
Dokumentation: javadoc
Motivation
• Konsistente Dokumentation von Quelltexten ist mühsam
• Häufig: Quelltext und Dokumentation in verschiedenen Dateien
• Aktueller Stand des Quelltextes kann sich von Dokumentation
unterscheiden
(Programm funktioniert auch ohne neue Dokumentation)
• Java hebt diese Trennung auf
• Eine einzige Datei
• Spezielle Kommentare (Doc-Kommentare)
/∗ ∗
...
∗/
RT (ICS @ UIBK)
Programmiermethodik
331/613
Pakete und Dokumentation
Dokumentation: javadoc
Aufbau von Doc-Kommentaren
• Werden nicht beliebig im Text verstreut
• Stehen vor Definition von
• Klassen und Interfaces
• Methoden
• Datenelementen
• Aufbau (typisch)
• Zusammenfassung in einem Satz mit Punkt am Ende
• Ausführliche Beschreibung
• Liste von Tags, die bestimmte zusätzliche Ausgaben erzeugen
• Weitere Informationen: http://www.oracle.com/technetwork/
java/javase/documentation/index-137868.html
RT (ICS @ UIBK)
Programmiermethodik
332/613
Pakete und Dokumentation
Dokumentation: javadoc
Tags
• Tags markieren Informationen mit bestimmter Bedeutung
• Bestehen aus @ und Schlüsselwort
• Nach Tag folgt Beschreibung
• Stehen am Anfang von neuen Zeile
RT (ICS @ UIBK)
Programmiermethodik
333/613
Pakete und Dokumentation
Dokumentation: javadoc
Tags (Beispiele)
• Für Klassen / Interfaces
• @author text
• @version text
• @since version
• @see reference (Klasse, auch bei Methoden)
• Methoden
• @param name text
• @return text
• @throws exceptionclass text
• @deprecated text
(markiert veraltete Methode, die nicht mehr verwendet werden soll)
• Datenelemente
• Keine Tags
• Weitere Tags siehe http://www.oracle.com/technetwork/java/
javase/documentation/index-jsp-135444.html
RT (ICS @ UIBK)
Programmiermethodik
334/613
Pakete und Dokumentation
Dokumentation: javadoc
javadoc-Compiler
• Für Dokumentation gibt es eigenen Compiler: javadoc
• Übersetzt Dokumentation in HTML-Format
• javac ignoriert Dokumentation
• Einige Schalter
-d path
-public
-private
-author
-version
-help
Speicher-Verzeichnis
Nur public-Elemente werden in Doku aufgenommen
Alle Elemente werden in Dokumentation aufgenommen
Übernimmt das @author-Tag (nicht default)
Übernimmt das @version-Tag (nicht default)
Hilfe zu javadoc
• Aufruf (Beispiel)
• javadoc –private BankAccount.java
• Project / Generate Javadoc
• Tools / Project Documentation
RT (ICS @ UIBK)
Programmiermethodik
(Kommandozeile)
(Eclipse)
(BlueJ)
335/613
Pakete und Dokumentation
Dokumentation: javadoc
Kommentare in HTML
• Inhalt von Doc-Kommentaren wird in HTML-Dateien übersetzt
⇒ HTML-Tags verwendbar
• Sollten sinnvoll und korrekt sein
• Beispiel
@author Rene Thiemann <a href=mailto:[email protected]>
rene [email protected]</a>
• Erzeugte Dateien
• Mehrere HTML-Dateien
• Startpunkt: index.html
RT (ICS @ UIBK)
Programmiermethodik
336/613
Pakete und Dokumentation
Dokumentation: UML
Übersicht
Pakete und Dokumentation
Pakete
Dokumentation: javadoc
Dokumentation: UML
RT (ICS @ UIBK)
Programmiermethodik
337/613
Pakete und Dokumentation
Dokumentation: UML
Modell und Diagramm
• Modell stellt Abstraktion eines Realitätsausschnitts dar
• Um Informationen verständlicher darzustellen
(Analog: Baupläne von Gebäuden)
• Um essentielle Systemaspekte aufzuzeigen
• Zur Kommunikation
(mit Projektmitarbeitern oder Kunden)
• Um komplexe Architekturen darstellen zu können
• Diagramm ist die grafische Repräsentation eines Modells
RT (ICS @ UIBK)
Programmiermethodik
338/613
Pakete und Dokumentation
Dokumentation: UML
Unified Modeling Language (UML)
• Unified Modeling Language (UML) ist standardisierte ausdruckstarke
Modellierungssprache
• Mit Hilfe von UML können Softwaresysteme entworfen, analysiert und
dokumentiert werden
• Begriff Unified bedeutet
• Unterstützung des gesamten Entwicklungsprozesses
• Unabhängigkeit von Entwicklungswerkzeugen, sowie
Programmiersprachen oder auch Anwendungsbereichen
• UML ist aber nicht
• Allheilmittel und vollständig
• vollständiger Ersatz für eine Textbeschreibung
• Methode oder Vorgehensmodell
RT (ICS @ UIBK)
Programmiermethodik
339/613
Pakete und Dokumentation
Dokumentation: UML
Diagrammarten
• Etliche unterschiedliche Diagrammarten
• Klassendiagramm (dieser Abschnitt)
• Beschreibt den strukturellen Aspekt (Klassen, Interfaces, Beziehungen)
• Sequenzdiagramm (Abschnitt über Entwurfsmuster)
• Beschreibt komplexe Interaktionen zwischen Objekten in bestimmten
Rollen
• Beschreibt zeitliche Abfolge der Interaktionen
• ...
RT (ICS @ UIBK)
Programmiermethodik
340/613
Pakete und Dokumentation
Dokumentation: UML
Notation für Klassen
Sprachkonzept
Notation
className
Klasse
className
Klasse mit Abschnitten
attribute1
attribute2
method1
method2
RT (ICS @ UIBK)
Programmiermethodik
341/613
Pakete und Dokumentation
Dokumentation: UML
Klassen (Attribute)
• Sichtbarkeit für Attribute und Operationen
• + = public
• # = protected
• − = private
• ~ = default
• Instanzattribute oder Klassenattribute
• Klassenattribute werden unterstrichen
• Zusätzliche Eigenschaften angeben
• «readOnly»
• «ordered»
• «unique»
• «nonunique»
• ...
RT (ICS @ UIBK)
Programmiermethodik
342/613
Pakete und Dokumentation
Dokumentation: UML
Klassen (Multiplizität)
• Multiplizität von Attributen
• Spezifiziert wie viele Werte ein Attribut aufnehmen kann
• Form: attribute: type[a..b]
• a..b
• mindestens a, höchstens b
• a und b sind natürliche Zahlen
• * statt b bedeutet beliebig viele
• Beispiele
• 1..1 genau ein (entspricht 1)
• 0..1 keins oder eins
• 0..* beliebig viele (entspricht *)
• 1..* mindestens eins
RT (ICS @ UIBK)
Programmiermethodik
343/613
Pakete und Dokumentation
Dokumentation: UML
Klassen (Operationen)
• Angabe einer (eventuell leeren) Parameterliste für jede Operation
• Für jeden Parameter muss zumindest Name und Typ angegeben
werden (auch Multiplizität)
• Auch Rückgabetyp möglich (wenn nichts angegeben: void)
• Unterstreichen kennzeichnet Klassenoperationen
• Sichtbarkeit wie bei Attributen
• Zusätzliche Eigenschaften
• «abstract» (oder kursiv geschrieben)
• «query» (Methode ohne Seiteneffekte)
• «leaf» (wenn final )
• «raisedException» (wie throws)
• Hinweise auf Algorithmen können in Notiz angefügt werden
RT (ICS @ UIBK)
Programmiermethodik
344/613
Pakete und Dokumentation
Dokumentation: UML
Beispiele
Alle Attribute sind
privat
Stack
–maxSize : int
–position : int
–data : int[0..*]
«constructor»+Stack(maxSize : int)
+push(element : int)
+pop() : int
+isEmpty() : boolean
+size() : int
User
–name : String[1]
–key : Password[1..*]
Bereich kann leer
bleiben (hier: Operationen)
Alle Operation sind
öffentlich
RT (ICS @ UIBK)
User kann mehrere
Passwörter haben
Programmiermethodik
345/613
Pakete und Dokumentation
Dokumentation: UML
Assoziation
A
B
• Grundform (binäre Assoziation)
• Zusätzliche Angaben
• Benennung (in der Mitte)
• Rollen (an den Enden der Assoziation, spezifische Funktion angeben)
• Multiplizitäten (an den Enden, wie bei Attributen)
• Angabe von Eigenschaften
• «ordered»
• «unique»
• ...
• Navigationsangaben
• Zulässige Navigationsrichtung (durch Pfeil)
• Keine Navigation erlaubt (durch X)
RT (ICS @ UIBK)
Programmiermethodik
346/613
Pakete und Dokumentation
Dokumentation: UML
Beispiele
User
Password
has
User
has
–key
Password
*
Reflexive Assoziation
User
–owner
1
has
–key
Password
*
SortedList
«constructor»+SortedList()
+insert(element : int)
+print()
RT (ICS @ UIBK)
Node
–head
0..1
–data : int
«constructor»˜Node(data : int)
Programmiermethodik
0..1
–next
347/613
Pakete und Dokumentation
Dokumentation: UML
Beispiel (Java Umsetzung – Grundformen)
User
–key
Password
User
*
–owner
1
–key
Password
*
public c l a s s User {
private Passwort [ ] key ;
...
}
public c l a s s User {
private Passwort [ ] key ;
...
}
p u b l i c c l a s s Password {
...
...
}
p u b l i c c l a s s Password {
p r i v a t e U s e r owner ;
...
}
RT (ICS @ UIBK)
Programmiermethodik
348/613
Pakete und Dokumentation
Dokumentation: UML
Beispiel (Java Umsetzung)
Borrower
–currentBorrower
0..1
borrows
public c l a s s Borrower {
p r i v a t e Book [ ] b o r r o w e d B o o k s ;
p r i v a t e i n t numBooks
–borrowedBooks
0..5
Book
p u b l i c c l a s s Book {
private Borrower
currentBorrower ;
public Borrower ( ) {
public void setBorrower (
numBooks = 0 ;
Borrower b ) {
b o r r o w e d B o o k s = new Book [ 5 ] ;
currentBorrower = b ;
}
} ...
p u b l i c v o i d b o r r o w ( Book b ) {
}
...
b o r r o w e d B o o k s [ numBooks ] = b ;
numBooks++;
b . setBorrower ( this ) ;
...
} ...
}
RT (ICS @ UIBK)
Programmiermethodik
349/613
Pakete und Dokumentation
Dokumentation: UML
Aggregation
• Ist spezielle Assoziation (Teil-Ganzes-Beziehung)
• Komposition ist speziellere (strengere) Form der Aggregation mit
folgenden Einschränkungen
• Ein Teil darf Kompositionsteil höchstens eines Ganzen sein
• Multiplizität 1 bedeutet, dass Teil nur solange existiert wie sein Ganzes
• Beispiele
Company
Division
has
1
Invoice
1..*
Invoice Line Item
has
1
1..*
Aggregation
Komposition
Rechnungsposten existiert nur mit Rechnung
RT (ICS @ UIBK)
Programmiermethodik
350/613
Pakete und Dokumentation
Dokumentation: UML
Beispiel (Java Umsetzung)
Car
has
–wheels Wheel
4
Car
has
–wheels Wheel
4
p u b l i c c l a s s Car {
p u b l i c c l a s s Car {
p r i v a t e Wheel [ ] w h e e l s ;
p r i v a t e Wheel [ ] w h e e l s ;
...
...
p u b l i c Car ( Wheel w1 , . . . ) {
p u b l i c Car ( ) {
w h e e l s = new Wheel [ 4 ] ;
w h e e l s = new Wheel [ 4 ] ;
w h e e l s [ 0 ] = w1 ;
w h e e l s [ 0 ] = new Wheel ( ) ;
w h e e l s [ 1 ] = w2 ;
w h e e l s [ 1 ] = new Wheel ( ) ;
w h e e l s [ 2 ] = w3 ;
w h e e l s [ 2 ] = new Wheel ( ) ;
w h e e l s [ 3 ] = w4 ;
w h e e l s [ 3 ] = new Wheel ( ) ;
...
...
}
}
}
}
RT (ICS @ UIBK)
Programmiermethodik
351/613
Pakete und Dokumentation
Dokumentation: UML
Vererbung und Interfaces
ArrayStack
«interface»
Stack
+push(data : Object)
+pop() : Object
+isEmpty() : boolean
# stack : Object[]
# position : int
+push(data : Object)
+pop() : Object
+isEmpty() : boolean
+isFull() : boolean
Implemetierung
Vererbung
ResizableArrayStack
+resize(preferredSize : int)
RT (ICS @ UIBK)
Programmiermethodik
352/613
Generische Programmierung
Übersicht
Generische Programmierung
Motivation
Generizität
Type-Erasure
Polymorphe Methoden
RT (ICS @ UIBK)
Programmiermethodik
353/613
Generische Programmierung
Motivation
Übersicht
Generische Programmierung
Motivation
Generizität
Type-Erasure
Polymorphe Methoden
RT (ICS @ UIBK)
Programmiermethodik
354/613
Generische Programmierung
Motivation
Implementierung von Paaren verschiedener Typen
public class IPair {
private f i n a l Integer f i r s t ;
p r i v a t e f i n a l I n t e g e r second ;
public IPair ( Integer first , Integer
this . first = first ;
t h i s . second = second ;
}
public Integer getFirst () {
return this . f i r s t ;
}
p u b l i c I n t e g e r getSecond () {
r e t u r n t h i s . second ;
}
}
second ) {
p u b l i c c l a s s DPair {
p r i v a t e f i n a l Double f i r s t ;
p r i v a t e f i n a l Double second ;
p u b l i c DPair ( Double f i r s t , Double second ) {
this . first = first ;
t h i s . second = second ;
}
p u b l i c Double g e t F i r s t ( ) {
return this . f i r s t ;
}
p u b l i c Double getSecond ( ) {
r e t u r n t h i s . second ;
}
}
RT (ICS @ UIBK)
Programmiermethodik
355/613
Generische Programmierung
Motivation
Object-Paare
public class Pair {
private f i n a l Object f i r s t ;
private f i n a l Object second ;
public Pair ( Object f i r s t , Object second ) {
this . f i r s t = f i r s t ;
t h i s . second = second ;
}
public Object g e t F i r s t () {
return t h i s . f i r s t ;
}
public Object getSecond () {
return t h i s . second ;
}
}
• Wurzelklasse Object und Ersetzungsprinzip ausnutzen
⇒ Problem gelöst?
⇒ Typsicherheit?
RT (ICS @ UIBK)
Programmiermethodik
356/613
Generische Programmierung
Motivation
Allgemeine Implementierung
• Es werden nur Objekte vom Typ Object verwaltet
⇒ Alle Objekte (durch Autoboxing auch primitive Datentypen) können
verwaltet werden
⇒ Eine Implementierung für unterschiedliche Typen
• Aber
• Getter-Methoden liefern nur Objekt vom Typ Object
⇒ weitere Benutzung erfordert Casting
Pair p = new Pair("foo","bar"); String s = (String) p. getFirst ();
• Es können gleichzeitig unterschiedliche Typen (z.B. Integer , String
etc.) gespeichert werden (Typ ist nicht vorhersagbar)
Pair stringPair = new Pair(2,"foo");
⇒ Keine Typsicherheit und daher umständliche Programmierung
notwendig
• Lösung?
RT (ICS @ UIBK)
Programmiermethodik
357/613
Generische Programmierung
Generizität
Übersicht
Generische Programmierung
Motivation
Generizität
Type-Erasure
Polymorphe Methoden
RT (ICS @ UIBK)
Programmiermethodik
358/613
Generische Programmierung
Generizität
Generizität
• Generizität erlaubt es, Programmteil (Klasse, Interface, Methode) mit
Typen zu parametrisieren
• Seit Java 1.5
• Unterscheidung
• Generische Klasse
• Generischer Typ
RT (ICS @ UIBK)
Programmiermethodik
359/613
Generische Programmierung
Generizität
Generische Klasse
• Definition
• Wie normale Klasse
• Zusätzlich wird der Klasse eine Typvariable in spitzen Klammern
nachgestellt:
public class Pair<T> {...}
• Kann beliebiger Buchstabe sein
• <T> ist aber Konvention
• Im Klassenrumpf wird Typvariable fast wie normaler Typ verwendet
• Bei Übergabe- bzw. Rückgabeparameter etc.
• Einschränkungen werden noch erklärt
RT (ICS @ UIBK)
Programmiermethodik
360/613
Generische Programmierung
Generizität
Generischer Typ
• Bei Anwendung wird für generische Typvariable ein konkretes
Typargument übergeben
• Generische Klasse und Typargument liefern generischen Typ
• Kann wie jeder andere Typ verwendet werden
• Variablendeklaration
• Methodenparameter
• Rückgabeparameter
• ...
• Beispiel (Pair): Pair<Integer> p = new Pair<Integer>(10,10);
RT (ICS @ UIBK)
Programmiermethodik
361/613
Generische Programmierung
Generizität
Beispiel: Pair
p u b l i c c l a s s P a i r <T> {
private f i n a l T f i r s t ;
private f i n a l T second ;
public Pair ( f i n a l T f i r s t , f i n a l T second ) {
this . f i r s t = f i r s t ;
t h i s . second = second ;
}
public T g e t F i r s t () {
return th is . f i r s t ;
}
public T getSecond () {
return t h i s . second ;
}
}
RT (ICS @ UIBK)
Programmiermethodik
362/613
Generische Programmierung
Generizität
Beispiel: Anwendung
public c l a s s Test {
p r i v a t e s t a t i c v o i d p r i n t I n t P a i r ( P a i r <I n t e g e r > i ) {
System . o u t . p r i n t l n ( i . g e t F i r s t ( ) + " " +
i . getSecond ( ) ) ;
}
p u b l i c s t a t i c v o i d main ( f i n a l S t r i n g [ ] a r g s ) {
P a i r <I n t e g e r > p i = new P a i r <I n t e g e r >(10 , 1 0 ) ;
P a i r <S t r i n g > p s = new P a i r <S t r i n g >(" EINS " , "2" ) ;
// P a i r <S t r i n g > p s i = new P a i r <S t r i n g >("EINS " , 2 ) ;
printIntPair ( pi );
// p r i n t I n t P a i r ( p s ) ;
}
}
RT (ICS @ UIBK)
Programmiermethodik
363/613
Generische Programmierung
Generizität
Generische Typen
• Pair<Integer> und Pair<String> sind unterschiedliche (inkompatible)
Typen
• Können nicht zugewiesen werden
• Keine Substitution möglich (wenn z.B. Pair<Integer> formaler
Parameter ist, und Pair<String> Typ des aktuellen Parameters ist)
• Alle Methoden mit Rückgabewerten liefern jetzt Ergebnis des
Typarguments (kein Cast notwendig)
• Beim Übersetzen überprüft Compiler korrekte Zuweisungen,
Verwendungen, etc.
• Statische Typprüfung durch Compiler verhindert Übersetzung von
Programmen mit Typfehlern
• Zur Laufzeit finden keine Tests statt
RT (ICS @ UIBK)
Programmiermethodik
364/613
Generische Programmierung
Generizität
Generische Interfaces
• Auch Interfaces können generisch definiert werden
• Beispiel
p u b l i c i n t e r f a c e Stack <T> {
v o i d push (T d a t a ) ;
T pop ( ) ;
boolean i s E m p t y ( ) ;
}
• Implementierung
• Durch Klasse, wobei Interface mit konkreten Typargument versehen
wird
• Durch generische Klasse, wobei Typvariablen der Klasse und des
Interfaces gekoppelt werden
RT (ICS @ UIBK)
Programmiermethodik
365/613
Generische Programmierung
Generizität
Beispiel mit konkretem Typargument
p u b l i c c l a s s S t r i n g S t a c k implements Stack <S t r i n g > {
p r i v a t e S t r i n g [ ] d a t a = new S t r i n g [ 2 0 ] ;
int position = 0;
p u b l i c v o i d push ( S t r i n g d a t a ) {
t h i s . data [ t h i s . p o s i t i o n ] = data ;
t h i s . p o s i t i o n ++;
}
p u b l i c S t r i n g pop ( ) {
t h i s . p o s i t i o n −−;
return t h i s . data [ t h i s . p o s i t i o n ] ;
}
p u b l i c boolean i s E m p t y ( ) {
r e t u r n t h i s . p o s i t i o n == 0 ;
}
RT (ICS @ UIBK)
Programmiermethodik
366/613
Generische Programmierung
Generizität
Beispiel mit konkretem Typargument: Anwendung
public s t a t i c void t e s t ( ) {
S t r i n g S t a c k s t a c k = new S t r i n g S t a c k ( ) ;
s t a c k . push ( "foo" ) ;
Stack <S t r i n g > s s t a c k = s t a c k ;
S t r i n g s = s s t a c k . pop ( ) ;
// s s t a c k . push ( 5 ) ;
// s t a c k . push ( 5 ) ;
}
RT (ICS @ UIBK)
Programmiermethodik
367/613
Generische Programmierung
Generizität
Beispiel mit generischem Typargument
p u b l i c c l a s s L i s t S t a c k <T> implements Stack <T> {
p r i v a t e Node<T> r o o t = n u l l ;
p u b l i c boolean i s E m p t y ( ) {
r e t u r n t h i s . r o o t == n u l l ; }
p u b l i c v o i d push (T d a t a ) {
t h i s . r o o t = new Node<T>( data , t h i s . r o o t ) ; }
p u b l i c T pop ( ) {
T data = t h i s . root . data ;
this . root = this . root . next ;
return data ; }
}
c l a s s Node<T> {
T data ;
Node<T> n e x t ;
Node (T data , Node<T> n e x t ) {
t h i s . data = data ;
this . next = next ; }
}
RT (ICS @ UIBK)
Programmiermethodik
368/613
Generische Programmierung
Generizität
Beispiel mit generischem Typargument: Anwendung
public s t a t i c void t e s t ( ) {
L i s t S t a c k <S t r i n g > s t a c k = new L i s t S t a c k <S t r i n g > ( ) ;
s t a c k . push ( "foo" ) ;
Stack <S t r i n g > s s t a c k = s t a c k ;
S t r i n g s = s s t a c k . pop ( ) ;
// s s t a c k . push ( 5 ) ;
// s t a c k . push ( 5 ) ;
Stack <I n t e g e r > i s t a c k = new L i s t S t a c k <I n t e g e r > ( ) ;
i s t a c k . push ( 5 ) ;
i n t i = i s t a c k . pop ( ) ;
// i s t a c k . push ( " f o o " ) ;
Stack <O b j e c t > i s t a c k 2 = new L i s t S t a c k <O b j e c t > ( ) ;
i s t a c k 2 . push ( 1 ) ;
// i = i s t a c k 2 . pop ( ) ;
i s t a c k 2 . push ( "foo" ) ;
}
RT (ICS @ UIBK)
Programmiermethodik
369/613
Generische Programmierung
Generizität
Mehrere Typvariablen
• Generische Klasse kann auch mehrere Typvariablen haben
• Typvariablen sind unabhängig voneinander
• Typargumente können frei gewählt werden
• Statische Typprüfung stellt sicher, dass konsistente Zuweisungen
erfolgen
• Generische Typen sind selbst vollwertige Typen, d.h. sie können auch
als Typargumente verwendet werden
RT (ICS @ UIBK)
Programmiermethodik
370/613
Generische Programmierung
Generizität
Beispiel: Pair
p u b l i c c l a s s P a i r <S , T> {
private f i n a l S f i r s t ;
private f i n a l T second ;
public Pair ( f i n a l S f i r s t , f i n a l T second ) {
this . f i r s t = f i r s t ;
t h i s . second = second ;
}
public S g e t F i r s t () {
return th is . f i r s t ;
}
public T getSecond () {
return t h i s . second ;
}
}
RT (ICS @ UIBK)
Programmiermethodik
371/613
Generische Programmierung
Generizität
Beispiel: Pair-Anwendung
public s t a t i c void t e s t ( ) {
P a i r <S t r i n g , I n t e g e r > p s i ;
p s i = new P a i r <S t r i n g , I n t e g e r >("TEST" , 1 7 ) ;
String s = psi . getFirst ();
i n t i = p s i . getSecond ( ) ;
// p s i = new P a i r <S t r i n g , S t r i n g >("TEST " , " 1 " ) ;
P a i r <I n t e g e r , P a i r <S t r i n g , I n t e g e r >> pp
= new P a i r <I n t e g e r , P a i r <S t r i n g , I n t e g e r >>(2, p s i ) ;
I n t e g e r j = pp . g e t S e c o n d ( ) . g e t S e c o n d ( ) ;
L i s t <L i s t <Double>> m a t r i x ;
L i s t <P a i r <S t r i n g , O b j e c t >> map ;
}
RT (ICS @ UIBK)
Programmiermethodik
372/613
Generische Programmierung
Generizität
Typebounds
• Normalerweise werden beliebige Typen als Typargumente akzeptiert
• Oft möchte man aber spezielle generische Klasse mit bestimmten
Methoden einer Klasse implementieren
• Typargumente können daher eingeschränkt werden
• Nach dem Typ wird ein Typebound genannt
• Typebound kann beliebiger Typ sein (kann auch Typvariablen
einbeziehen)
• Typargumente müssen zum Typebound kompatibel sein
RT (ICS @ UIBK)
Programmiermethodik
373/613
Generische Programmierung
Generizität
public class A { }
p u b l i c c l a s s B extends A {
public void b ( ) { }
}
p u b l i c c l a s s C extends B { }
p u b l i c c l a s s P a i r <T extends B> {
private f i n a l T f i r s t ;
private f i n a l T second ;
p u b l i c P a i r (T f i r s t , T s e c o n d ) {
this . f i r s t = f i r s t ;
t h i s . second = second ;
}
public T g e t F i r s t () {
t h i s . f i r s t . b ( ) ; // p o s s i b l e s i n c e T e x t e n d s B
return t h i s . f i r s t ;
}
}
RT (ICS @ UIBK)
Programmiermethodik
374/613
Generische Programmierung
Generizität
Beispiel Anwendung
public s t a t i c void t e s t ( ) {
P a i r <B> pb = new P a i r <B>(new B ( ) , new B ( ) ) ;
P a i r <C> pc = new P a i r <C>(new C ( ) , new C ( ) ) ;
// P a i r <A> pa = new P a i r <A>(new A ( ) , new A ( ) ) ;
}
RT (ICS @ UIBK)
Programmiermethodik
375/613
Generische Programmierung
Generizität
Typebounds
• Schlüsselwort extends wird bei Typebounds für Klassen und Interfaces
verwendet
• Typvariable kann mit mehreren Typvariablen eingeschränkt werden
(mit & verknüpfen)
public class Pair<T extends A & B & C & ...> { ... }
• Erster Typ (A) kann beliebiger Typ sein
• Spätere Typen (B, C, . . . ) dürfen nur Interfaces sein
RT (ICS @ UIBK)
Programmiermethodik
376/613
Generische Programmierung
Generizität
Typebounds mit Typvariablen
• Typvariable kann auch bei Formulierung von Typebounds verwendet
werden
• Beispiel mit Interface Comparable<T>:
p u b l i c i n t e r f a c e Comparable<T> {
i n t compareTo (T o t h e r ) ;
// n e g a t i v e (<) , 0 (=) , p o s i t i v e (>)
}
• Alle Elemente in SortedList sollten vergleichbar sein, d.h. das Interface
Comparable<T> implementieren
public class SortedList <T extends Comparable<T>> {...}
• Zulässige Deklaration: SortedList <Integer> = ...;
• Unzulässige Deklaration: SortedList <Object> = ...;
(Object implementiert nicht Comparable<Object>)
RT (ICS @ UIBK)
Programmiermethodik
377/613
Generische Programmierung
Generizität
p u b l i c c l a s s S o r t e d L i s t <T extends Comparable<T>> {
p r i v a t e Node<T> r o o t = n u l l ;
p r i v a t e Node<T> i n s e r t (T data , Node<T> node ) {
i f ( node == n u l l | | d a t a . compareTo ( node . d a t a ) < 0 ) {
r e t u r n new Node<T>( data , node ) ;
} else {
node . n e x t = i n s e r t ( data , node . n e x t ) ;
r e t u r n node ;
}
}
p u b l i c v o i d i n s e r t (T d a t a ) {
t h i s . r o o t = i n s e r t ( data , t h i s . r o o t ) ;
}
public void p r i n t ( ) {
f o r ( Node<T> c u r r e n t = t h i s . r o o t ;
c u r r e n t != n u l l ;
current = current . next )
System . o u t . p r i n t l n ( c u r r e n t . d a t a ) ;
}
}
RT (ICS @ UIBK)
Programmiermethodik
378/613
Generische Programmierung
Generizität
Anwendung
public s t a t i c void t e s t ( ) {
S o r t e d L i s t <S t r i n g > l i s t = new S o r t e d L i s t <S t r i n g > ( ) ;
l i s t . i n s e r t ( "foo" ) ;
l i s t . i n s e r t ( "bar" ) ;
l i s t . i n s e r t ( "com" ) ;
l i s t . p r i n t ( ) ; // b a r com f o o
}
RT (ICS @ UIBK)
Programmiermethodik
379/613
Generische Programmierung
Generizität
Generizität und Vererbung
• Abgeleitete Typargumente implizieren nicht abgeleitete generische
Typen
public class A { . . . }
p u b l i c c l a s s B extends A { . . . }
...
P a i r <A> pa ;
pa = new P a i r <B>(new B ( ) , new B ( ) ) ; // e r r o r
• Generischer Typ G1 ist nur dann Subtyp von G2, wenn
• Typargumente gleich sind
• Rawtype (wird noch besprochen) von G1 ein Subtyp des Rawtypes von
G2 ist
RT (ICS @ UIBK)
Programmiermethodik
380/613
Generische Programmierung
Generizität
Generizität und Vererbung
• Generische Klassen werden bei Vererbung wie gewöhnliche Klassen
behandelt (gilt auch für generische Interfaces)
• Generische Klasse darf erben
• Von nicht generischer Klasse
public class MyGen1<T> extends A { ... }
• Von konkretisierter generischer Klasse
public class MyGen2<T> extends Gen1<Integer> { ... }
• Von generischer Klasse mit gleichem Platzhalter
public class MyGen3<T> extends Gen2<T> { ... }
• Von generischer Klasse mit gleichem Platzhalter und Typebound
p u b l i c c l a s s MyGen4<T extends Comparable<T>>
extends S o r t e d L i s t <T> { . . . }
• Nicht generische Klasse sollte nur von konkretisierter generischer
Klasse erben
public class B extends Gen3<Integer> { /∗ok ∗/ ... }
public class C extends Gen4<T> { /∗not ok ∗/... }
RT (ICS @ UIBK)
Programmiermethodik
381/613
Generische Programmierung
Generizität
Generizität und Vererbung
• Zuweisungskompatibilität (vorherige Beispiele)
• Bei nicht generischer Klasse
A a1 = new MyGen1<Integer>();
A a2 = new MyGen1<Double>();
• Bei konkreter generischer Klasse
Gen1<Integer> a3 = new MyGen2<Integer>();
Gen1<Integer> a4 = new MyGen2<Double>();
• Bei generischer Klasse müssen aktuelle Typparameter gleich sein
Gen2<Integer> a5 = new MyGen3<Integer>();
Gen2<Integer> a6 = new MyGen3<Double>(); //error
RT (ICS @ UIBK)
Programmiermethodik
382/613
Generische Programmierung
Generizität
Generizität und Vererbung
• Überschreiben bei konkretisierter generischer Klasse
• Typparameter werden durch konkrete Typen ersetzt
p u b l i c c l a s s M y L i s t extends S o r t e d L i s t <I n t e g e r > {
...
public void i n s e r t ( I n t e g e r x ) { . . . }
}
• Überschreiben bei generischer Klasse
• Typparameter bleiben erhalten
p u b l i c c l a s s MyList<T extends Comparable<T>>
extends S o r t e d L i s t <T> {
...
p u b l i c v o i d i n s e r t (T x ) { . . . }
}
RT (ICS @ UIBK)
Programmiermethodik
383/613
Generische Programmierung
Generizität
Wildcards
• Generische Typen können unbestimmtes Typargument nennen
• Als Typargument wird Wildcardzeichen ? angegeben (Wildcardtyp)
• Alle generischen Typen der gleichen generischen Klasse sind
kompatibel zu Wildcardtyp
• Beispiel
P a i r <?> p ;
...
p = new P a i r <I n t e g e r > ( 3 , 2 ) ;
p = new P a i r <Double > ( 3 . 0 , 2 . 0 ) ;
...
RT (ICS @ UIBK)
Programmiermethodik
384/613
Generische Programmierung
Generizität
Anwendung
• Wildcards eignen sich für Situationen, in denen konkretes Typargument
keine Rolle spielt
public class U t i l {
p u b l i c s t a t i c v o i d p r i n t P a i r ( P a i r <?> p a i r ) {
System . o u t . p r i n t l n ( p a i r . g e t F i r s t ( ) +
" " + p a i r . getSecond ( ) ) ;
}
...
}
...
P a i r <I n t e g e r > p i = new P a i r <I n t e g e r > ( 1 0 , 1 0 ) ;
Util . printPair ( pi );
• Wildcardtyp ist ein beliebiger Typ mit unbekannten Eigenschaften
• Kann nicht direkt an generische Variable zugewiesen werden
Pair<T> p; Pair<?> q; ... q = p; /∗ ok ∗/ p = q; /∗ not ok ∗/
RT (ICS @ UIBK)
Programmiermethodik
385/613
Generische Programmierung
Generizität
Typebounds mit Wildcardtypen
• Wildcardtypen können auch mittels Typebounds eingeschränkt werden
• Einschränkung von oben mit extends (Upper-Typebound)
• Einschränkung von unten mit super (Lower-Typebound)
• Für folgende Beispiele wird folgende Hierarchie angenommen:
public class A { . . . }
p u b l i c c l a s s B extends A { . . . }
p u b l i c c l a s s C extends B { . . . }
RT (ICS @ UIBK)
Programmiermethodik
386/613
Generische Programmierung
Generizität
Kovarianter Wildcardtyp
• Beispiel
P a i r <? extends B> pb ;
pb = new P a i r <B>(new B ( ) , new B ( ) ) ; // ok
pb = new P a i r <C>(new C ( ) , new C ( ) ) ; // ok
pb = new P a i r <A>(new A ( ) , new A ( ) ) ; // n o t ok
• Allgemein gilt: D<E> ist kompatibel zu D<? extends F>, wenn E zu
F kompatibel ist
• Benutzung wird eingeschränkt
• Schreibende Zugriffe (Methodenaufrufe, die parametrisierten Typ als
Parameter enthalten) sind nicht erlaubt
• Lesende Zugriffe, die parametrisierten Typ zurückgeben, sind erlaubt
RT (ICS @ UIBK)
Programmiermethodik
387/613
Generische Programmierung
Generizität
Kovarianz bei Arrays (Wiederholung)
• Kovarianz bei Arrays in Java
Object [] s = new String [10]; // ok
• Bringt statische Typprüfung des Compilers zu Fall
• Beispiel:
Number [ ] a = new I n t e g e r [ 2 3 ] ; // ok
a [ 0 ] = new Double ( 3 . 1 4 ) ; // ok , b u t r u n t i m e −e x c .
• Liefert erst zur Laufzeit ArrayStoreException
• Ohne weitere Maßnahmen würde Lücke auch bei kovarianten
Wildcardtypen vorhanden sein
RT (ICS @ UIBK)
Programmiermethodik
388/613
Generische Programmierung
Generizität
Beispiele für kovarianten Wildcardtyp
...
A r r a y L i s t <? extends Number> l i s t ;
l i s t = new A r r a y L i s t <I n t e g e r > ( ) ;
l i s t = new A r r a y L i s t <Double > ( ) ;
l i s t = new A r r a y L i s t <Long > ( ) ;
...
l i s t . set (1 , 2.3 d ) ;
// n o t ok
Number x = l i s t . g e t ( 1 ) ;
// ok
...
RT (ICS @ UIBK)
Programmiermethodik
389/613
Generische Programmierung
Generizität
Kontravarianter Wildcardtyp
• Beispiel
P a i r <? super B> pb ;
pb = new P a i r <B>(new B ( ) , new B ( ) ) ; // ok
pb = new P a i r <C>(new C ( ) , new C ( ) ) ; // n o t ok
pb = new P a i r <A>(new A ( ) , new A ( ) ) ; // ok
• Allgemein gilt: D<E> ist kompatibel zu D<? super F>, wenn F zu E
kompatibel ist
• Benutzung wird eingeschränkt
• Schreibende Zugriffe sind erlaubt
• Lesende Zugriffe sind nicht erlaubt
RT (ICS @ UIBK)
Programmiermethodik
390/613
Generische Programmierung
Generizität
Beispiele für kontravarianten Wildcardtyp
...
A r r a y L i s t <? super Double> l i s t ;
l i s t = new A r r a y L i s t <Number > ( ) ;
l i s t = new A r r a y L i s t <Double > ( ) ;
l i s t = new A r r a y L i s t <O b j e c t > ( ) ;
...
l i s t . set (1 , 2.3 d ) ;
// ok
Double x = l i s t . g e t ( 1 ) ;
// n o t ok
...
RT (ICS @ UIBK)
Programmiermethodik
391/613
Generische Programmierung
Generizität
Varianzen (Zusammenfassung)
Typ
Lesen
Schreiben
Invarianz
C<T>
3
3
Bivarianz
C<?>
7
Kovarianz
C<? extends B>
Kontravarianz
C<? super B>
∗
3
7
∗
7
7
3
Kompatible
Typargumente
T
alle
B und
Unterklassen
B und
Oberklassen
7 ∗ : Variable vom Typ Object kann jeder Wert zugewiesen werden
RT (ICS @ UIBK)
Programmiermethodik
392/613
Generische Programmierung
Generizität
Einsatz von Wildcardtypen
• Erlaubt flexiblen Code
• Methoden mit Parametern von Wildcardtypen sind möglich
• Argumente unterschiedlicher generischer Typen sind möglich
• Benötigt Einschränkungen, um statische Prüfung durchzuhalten
• Zuweisungen verhindern, die zur Laufzeit Fehler produzieren könnten
RT (ICS @ UIBK)
Programmiermethodik
393/613
Generische Programmierung
Generizität
Java 7 – Vereinfachung von Typangaben
• Einsatz von Generics erfordert hohen Schreibaufwand
• Angabe der Typinformationen bei Deklaration und Erzeugung
• Beispiel:
P a i r <I n t e g e r , P a i r <S t r i n g , I n t e g e r >> pp =
new P a i r <I n t e g e r , P a i r <S t r i n g , I n t e g e r >>(2, p s i ) ;
• Schwer zu lesen
• Kann mit generischen Fabriksmethoden (siehe kommendes Kapitel
Entwurfsmuster) umgangen werden
• Ab Java 7 gibt es Diamond-Operator <> für kürze Schreibweise
• Compiler wählt korrekten Typ (durch Type-Inference)
• Beispiel
P a i r <I n t e g e r , P a i r <S t r i n g , I n t e g e r >> pp =
new P a i r <>(22, p s i ) ;
RT (ICS @ UIBK)
Programmiermethodik
394/613
Generische Programmierung
Generizität
Java 7 – Probleme mit dem Diamond-Operator
• Nicht immer funktioniert automatische Type-Inference
• Beispiel
Set<Number> s =
new HashSet <>( A r r a y s . a s L i s t ( 0 L , 0L ) ) ;
• Welchen Typ soll der Compiler wählen?
• Typ des Ausdrucks auf linken Seite (Set<Number>, d.h. Number)?
• Typ des Konstruktorarguments (Long)?
• Klare Regel
• Compiler überprüft immer zuerst Typ des Konstruktorarguments
• Beispiel: Einem Set<Number> kann dann nicht ein HashSet<Long>
zugewiesen werden
• Beispiel
Set<Number> s =
new HashSet <>( A r r a y s . a s L i s t ( ( Number ) 0L , 0L ) ) ;
RT (ICS @ UIBK)
Programmiermethodik
395/613
Generische Programmierung
Type-Erasure
Übersicht
Generische Programmierung
Motivation
Generizität
Type-Erasure
Polymorphe Methoden
RT (ICS @ UIBK)
Programmiermethodik
396/613
Generische Programmierung
Type-Erasure
Homogene bzw. Heterogene Übersetzung
• Es gibt zwei Realisierungsmöglichkeiten für generische Datentypen
• Heterogene Variante
• Für jedes Typargument (etwa String, Integer , Point usw.) wird
individueller Code erzeugt, also drei Klassen (String−Stack,
Integer −Stack, Point−Stack usw.)
• Beispiel: C++
Homogene Übersetzung
• Für jede parametrisierte Klasse wird eine Klasse erzeugt, die statt
generischen Typs allgemeine Klasse (wie z.B. Object) einsetzt
• Für konkreten Typ werden Typanpassungen in Anweisungen eingebaut
• Beispiel: Java
RT (ICS @ UIBK)
Programmiermethodik
397/613
Generische Programmierung
Type-Erasure
Type-Erasure
• Mechanismus hinter Übersetzung generischer Klassen etc. wird als
Type-Erasure bezeichnet
• Generics (und deren Anwendungen) werden in 2 Schritten übersetzt
• Type-Erasure reduziert generischer Code auf normalen, nicht
generischen Java-Quelltext
• Dieser Quelltext wird normal weiterverarbeitet (wie bisher)
• Generics werden nur vom Compiler verarbeitet
• Laufzeitsystem (und JVM) sehen nichts davon
• Bei generischen Klassen werden im Zuge der Type-Erasure
• Typvariablen in spitzen Klammern gelöscht,
• Vorkommen von Typvariablen mit einem oder mehreren Typebounds
durch den einzigen bzw. erstgenannten Typebound ersetzt,
• Vorkommen von Typvariablen ohne Typebound durch Object ersetzt
(Default-Typebound)
RT (ICS @ UIBK)
Programmiermethodik
398/613
Generische Programmierung
Type-Erasure
Beispiel
• Vor Type-Erasure
p u b l i c c l a s s P a i r <T> {
private T f i r s t ;
private T second ;
p u b l i c P a i r (T f i r s t , T l a s t ) { . . . }
...
}
• Nach Type-Erasure
public class Pair {
private Object f i r s t ;
private Object second ;
public Pair ( Object f i r s t , Object l a s t ) { . . . }
...
}
RT (ICS @ UIBK)
Programmiermethodik
399/613
Generische Programmierung
Type-Erasure
Type-Erasure bei generischen Typen
• Zuerst statische Typprüfung
• Typargumente müssen, falls angegeben, allen Typebounds genügen
• Generische Typen müssen untereinander korrekt verwendet werden
• Danach Type-Erasure
• Typargumente in spitzen Klammern löschen, inklusive Wildcards
• Typecasts einfügen, wenn Wert des Typarguments benutzt wird
• Vor Type-Erasure
P a i r <I n t e g e r > p = new P a i r <I n t e g e r > ( 1 , 1 ) ;
Integer i = p. getFirst ();
• Nach Type-Erasure
P a i r p = new P a i r ( 1 , 1 ) ;
Integer i = ( Integer ) p. getFirst ();
RT (ICS @ UIBK)
Programmiermethodik
400/613
Generische Programmierung
Type-Erasure
Type-Erasure (Zusammenfassung)
• Alle generischen Typen teilen sich eine einzige Implementierung ihrer
Klasse
• Zur Laufzeit existieren keine
•
•
•
•
Typvariablen
Typargumente
Typebounds
Wildcards
RT (ICS @ UIBK)
Programmiermethodik
401/613
Generische Programmierung
Type-Erasure
Rawtypes
• Durch Type-Erasure reduzierte Definition liefert sogenannten Rawtype
der generischen Klasse
• Es gibt genau einen Rawtype zu einer generischen Klasse
• Ist normale, nicht-generische Klasse
• Kann verwendet werden, z.B. Pair p = new Pair(10,10)
• Vorteil
• Alte Applikationen (vor Java 1.5) können mit generischen Klassen
zusammenarbeiten
• Nachteil
• Keine statische Prüfung
• Warnungen
RT (ICS @ UIBK)
Programmiermethodik
402/613
Generische Programmierung
Type-Erasure
Grenzen generischer Typen in Java
• Statische Elemente
• Statische Datenelemente und statische Methoden einer generischen
Klasse können keine Typvariablen der Klasse benutzen
• Dynamische Typprüfung
• Typvariable kann nicht mit Operator instanceof überprüft werden
if (x instanceof T) ...
• Compiler kann beim Übersetzen noch nicht den Typ kennen
• Type-Erasure würde Bedingung auf sinnlosen Test
if (x instanceof Object) ... reduzieren
• Test auf Rawtypes möglich
i f ( x i n s t a n c e o f P a i r ) . . . // ok
i f ( x i n s t a n c e o f P a i r <I n t e g e r >) . . . // n o t ok
RT (ICS @ UIBK)
Programmiermethodik
403/613
Generische Programmierung
Type-Erasure
Grenzen generischer Typen in Java
• Typecasts
p u b l i c c l a s s S t o r e <T> {
private T info ;
public void s e t I n f o ( Object x ){
i n f o = (T) x ; // Warnung , p r o b l e m a t i s c h
}
public T getInfo (){
return i n f o ;
}
}
..
S t o r e <S t r i n g > s t = new S t o r e <S t r i n g > ( ) ;
s t . s e t I n f o ( 2 3 ) ; // k e i n e Warnung
S t r i n g s = s t . g e t I n f o ( ) ; // b e i A u s f u e h r u n g
// C l a s s C a s t E x c e p t i o n
RT (ICS @ UIBK)
Programmiermethodik
404/613
Generische Programmierung
Type-Erasure
Grenzen generischer Typen in Java
• Konstruktoren
• Wegen fehlenden Information über spätere Typargumente können in
generischer Klasse keine Konstruktoren von Typvariablen aufgerufen
werden (T kann auch nicht als Basisklasse verwendet werden)
p u b l i c c l a s s S t o r e <T> {
private T info ;
public Store () {
i n f o = new T ( ) ; // n o t ok
}
...
}
p u b l i c c l a s s S t o r e <T> {
private T info ;
public Store () {
i n f o = n u l l ; // ok
}
...
}
RT (ICS @ UIBK)
Programmiermethodik
405/613
Generische Programmierung
Type-Erasure
Grenzen generischer Typen in Java
• Arrays von Typvariablen können nicht angelegt werden
p u b l i c c l a s s C o n t a i n e r <T> {
p r i v a t e T [ ] a = new T [ 1 0 0 ] ;
... }
// c o m p i l e e r r o r
• Um trotzdem mit Arrays zu arbeiten
p u b l i c c l a s s C o n t a i n e r <T> {
p r i v a t e T [ ] a = (T [ ] ) new O b j e c t [ 1 0 0 ] ;
... }
• Kovarianz von Arraytypen ausnutzen
• Code wird mit Warnung übersetzt und statische Typprüfung wird
unterlaufen
• Annotation @SuppressWarnings("unchecked") vor entsprechender
Klasse benutzen
• Man muss korrekte Zugriffsmethoden implementieren, die nur
T-Objekte im Array ablegen können
RT (ICS @ UIBK)
Programmiermethodik
406/613
Generische Programmierung
Type-Erasure
Grenzen generischer Typen in Java
• Arrays von parametrisierten Typen werden nicht zugelassen
• Beispiel: Comparable<String>[] ist nicht erlaubt
• Grund: Programme wären nicht typsicher: Nach fehlerfreien
Übersetzung könnte es noch immer zu unerwarteter ClassCastException
kommen (also ohne expliziten Cast)
• Beispiel
• Folgender Code muss zur Übersetzungszeit unterbunden werden
P a i r <I n t e g e r > [ ] p a r r = new P a i r <I n t e g e r > [ 9 ] ; // e r r o
Object [ ] a r r = parr ;
a r r [ 0 ] = new P a i r <S t r i n g >("a" , "b" ) ;
Zur Laufzeit keine ArrayStoreException wegen Type-Erasure
• Zulässig ist aber
O b j e c t [ ] a r r = new P a i r <? >[9];
a r r [ 0 ] = new P a i r <S t r i n g >("a" , "b" ) ;
Aber:
P a i r <S t r i n g > p = a r r [ 0 ] ; // e r r o r
p = ( P a i r <S t r i n g >) a r r [ 0 ] ; // w a r n i n g
RT (ICS @ UIBK)
Programmiermethodik
407/613
Generische Programmierung
Type-Erasure
Grenzen generischer Typen in Java
• Ausnahmen
• Es ist nicht erlaubt, parametrisierten Typ direkt oder indirekt von
Throwable abzuleiten
⇒ parametrisierte Exception-Typen sind nicht erlaubt
• Exception-Handling-Mechanismus ist Laufzeit-Mechanismus
• Laufzeitsystem (JVM) weiß nichts von Java Generics
• Class-Literal
• Man kann von parametrisiertem Typ kein Class-Literal bilden
• Ausdruck wie z.B. LinkedList <String>.class ist unzulässig
• In Java gibt es keine exakte Laufzeitrepräsentation eines
parametrisierten Typs
• Der Laufzeittyp ist immer nur der nicht parametrisierte Rawtype
(im Beispiel LinkedList )
RT (ICS @ UIBK)
Programmiermethodik
408/613
Generische Programmierung
Type-Erasure
Brückenmethoden
• Spezielle Situationen müssen vom Compiler selbst aufgelöst werden
• Programmierer muss sich keine Gedanken machen
• Besonderes Beispiel sind Brückenmethoden
• Brückenmethoden werden eingefügt, wenn Klasse von
parametrisierbarem Typ (Klasse, Interface) abgeleitet wird
RT (ICS @ UIBK)
Programmiermethodik
409/613
Generische Programmierung
Type-Erasure
Beispiel
p u b l i c c l a s s O<T> {
p u b l i c i n t g e t (T param ) {
return 5;
}
}
p u b l i c c l a s s U extends O<S t r i n g > {
@Override
p u b l i c i n t g e t ( S t r i n g param ) {
return 10;
}
}
• Was passiert nach Type-Erasure?
• Haben get-Methoden gleiche Signatur?
• Wird hier noch überschrieben?
RT (ICS @ UIBK)
Programmiermethodik
7
3
410/613
Generische Programmierung
Type-Erasure
Beispiel nach Type-Erasue
public class O {
p u b l i c i n t g e t ( O b j e c t param ) {
return 5;
}
}
p u b l i c c l a s s U extends O {
p u b l i c i n t g e t ( S t r i n g param ) {
return 10;
}
// Brueckenmethode e i n g e f u e g t
p u b l i c i n t g e t ( O b j e c t param ) {
r e t u r n g e t ( ( S t r i n g ) param ) ;
}
}
RT (ICS @ UIBK)
Programmiermethodik
411/613
Generische Programmierung
Type-Erasure
Brückenmethode im vorherigen Beispiel
• Brückenmethode (2. get-Methode in U) wurde vom Compiler eingefügt
• Überschreibt Methode der Klasse O und ruft jetzt die theoretisch
überschreibende Methode der Klasse U auf
• Klasse U verhält sich so, als wäre Methode überschrieben worden
• Programmierer merkt davon nichts
• Nur im Bytecode ersichtlich
• Nachfolgende Decompilierung zeigt das auch
• Brückenmethoden werden auch bei Methoden verwendet, die sich nach
Type-Erasure nur im Rückgabewert unterscheiden
RT (ICS @ UIBK)
Programmiermethodik
412/613
Generische Programmierung
Type-Erasure
Brückenmethoden bei Rückgabewerten: Vorher
p u b l i c i n t e r f a c e I t e r a t o r <E> {
p u b l i c boolean h a s N e x t ( ) ;
public E next ( ) ;
}
public class Alphabet
implements I t e r a t o r <C h a r a c t e r > {
p r i v a t e char c u r r e n t = ’A’ ;
p u b l i c boolean h a s N e x t ( ) {
r e t u r n t h i s . c u r r e n t <= ’Z’ ;
}
public Character next () {
r e t u r n new C h a r a c t e r ( t h i s . c u r r e n t ++);
}
}
RT (ICS @ UIBK)
Programmiermethodik
413/613
Generische Programmierung
Type-Erasure
Brückenmethoden bei Rückgabewerten: Nachher
public interface I t e r a t o r {
p u b l i c boolean h a s N e x t ( ) ;
public Object next ( ) ;
}
p u b l i c c l a s s A l p h a b e t implements I t e r a t o r {
p r i v a t e char c u r r e n t = ’A’ ;
p u b l i c boolean h a s N e x t ( ) {
r e t u r n c u r r e n t <= ’Z’ ;
}
public Character next () {
r e t u r n new C h a r a c t e r ( c u r r e n t ++);
}
// d o p p e l t e s n e x t ( ) n i c h t i n J a v a m o e g l i c h
public Object next () {
return next ( ) ;
}
}
RT (ICS @ UIBK)
Programmiermethodik
414/613
Generische Programmierung
Polymorphe Methoden
Übersicht
Generische Programmierung
Motivation
Generizität
Type-Erasure
Polymorphe Methoden
RT (ICS @ UIBK)
Programmiermethodik
415/613
Generische Programmierung
Polymorphe Methoden
Polymorphe Methoden
• Generische Methoden werden als polymorphe Methoden bezeichnet
• Sind unabhängig von generischen Typen
• Können in nicht-generischen Klassen definiert und aufgerufen werden
• Auch Konstruktoren und statische Methoden können polymorph sein
• Beim Aufruf muss immer explizit Zielobjekt angegeben werden
(gegebenenfalls auch this, bei statischen Methoden muss Klasse
angegeben werden)
RT (ICS @ UIBK)
Programmiermethodik
416/613
Generische Programmierung
Polymorphe Methoden
Beispiel
public class Voter {
p u b l i c s t a t i c <T> T v o t e (T x , T y , T z ) {
i f (x . equals (y )) {
return x ;
}
i f (y . equals ( z )) {
return y ;
}
i f ( z . equals (x )) {
return x ;
}
return n u l l ;
}
}
...
S t r i n g s = V o t e r .< S t r i n g > v o t e ( " ATEST " , "TEST" , " ATEST " ) ;
// S t r i n g s = V o t e r .< S t r i n g > v o t e ( "ATEST" , "TEST " , 1 ) ;
System . o u t . p r i n t l n ( s ) ; // ATEST
RT (ICS @ UIBK)
Programmiermethodik
417/613
Generische Programmierung
Polymorphe Methoden
Typebounds
• Auch bei polymorphen Methoden können Typebounds verwendet
werden
• Beispiel
• Methode median soll von drei Werten den Median zurückgeben
p u b l i c <T extends Comparable <? super T>> T median
(T x , T y , T z ) {
i n t c x y = x . compareTo ( y ) ;
i f ( c x y == 0 ) {
return x ;
}
i f ( cxy < 0) . . .
}
• Erlaubter Aufruf: Integer i = v.<Integer>median(3,2,5);
• Nicht erlaubt: Object i = v.<Object>median(3,2,5);
RT (ICS @ UIBK)
Programmiermethodik
418/613
Generische Programmierung
Polymorphe Methoden
Type-Inference
• In vielen Fällen können konkrete Typargumente beim Aufruf einer
polymorphen Methode weggelassen werden
• Compiler erkennt aus dem Kontext durch Type-Inference die korrekten
Typargumente
• Funktioniert auch über mehrere Stufen (verschachtelte
Methodenaufrufe) hinweg
• Beispiel (voriges Beispiel)
System . o u t . p r i n t l n (
V o t e r . v o t e ( " ATEST " , " TEST " , " ATEST " ) ) ;
System . o u t . p r i n t l n (
V o t e r . v o t e ( " ATEST " , " TESTC " , V o t e r . v o t e ( " TESTA " ,
" TESTC " , " TESTC " ) ) ) ;
RT (ICS @ UIBK)
Programmiermethodik
419/613
Generische Programmierung
Polymorphe Methoden
Gemischte Typargumente
• Werden bei polymorpher Methode Argumente mit unterschiedlichen
Typen für gleiche Typvariable verwendet:
• Type-Inference fällt auf den nähesten gemeinsamen Basistyp zurück
• Beispiel mit polymorpher Methode vote
• Möglich: Object n = Voter.vote(1, 1, "1");
• Nicht möglich: Integer n = Voter.vote(1, 1, "1");
RT (ICS @ UIBK)
Programmiermethodik
420/613
Generische Programmierung
Polymorphe Methoden
Polymorphe Methoden und Überladen
• Normale Methode darf nicht so definiert werden, dass sie nach
Type-Erasure mit polymorpher Methode kollidiert
• Unzulässig
p u b l i c <T> T v o t e (T x , T y , T z )
public Object vote ( Object x , Object y , Object z )
• Zulässig
p u b l i c <T extends Comparable <? super T>> T median
(T x , T y , T z ) { . . . }
p u b l i c I n t e g e r median
( Integer x , Integer y , Integer z) { . . . }
• Beim Aufruf überladener Methoden werden polymorphe Methoden erst
dann berücksichtigt, wenn keine normalen Methoden passen
RT (ICS @ UIBK)
Programmiermethodik
421/613
Generische Programmierung
Polymorphe Methoden
Varargs und Generics
• Varargs und Generics können zusammen verwendet werden
• Im JDK findet man zahlreiche Beispiele dafür
• Es kann aber zu Problemen kommen
• Beispiel: Polymorphe varargs-Methode
p r i v a t e s t a t i c <T> L i s t <T> a s L i s t (T . . . e l e m e n t s ) {
L i s t <T> l i s t = new L i n k e d L i s t <T> ( ) ;
f o r (T t : e l e m e n t s ) {
l i s t . add ( t ) ;
}
return l i s t ;
}
• Übersetzt ohne Fehler und ohne Warning (bis Java 1.6)
• Aufruf der Methode (Beispiel mit Pair<String>) ist aber problematisch
P a i r <S t r i n g > a , b , c ;
...
L i s t <P a i r <S t r i n g >> l i s t = a s L i s t ( a , b , c ) ;
RT (ICS @ UIBK)
Programmiermethodik
422/613
Generische Programmierung
Polymorphe Methoden
Varargs und Generics
• Problem im Beispiel auf vorherigenr Folie
• Compiler erzeugt aus variabler Argumentliste ein Array
• Wenn Aufrufargumente von parametrisiertem Typ sind, dann produziert
der Compiler eine unchecked-Warnung
• Parametrisierter Typ (wie Pair<String>) hat aufgrund der
Type-Erasure im Byte-Code keine exakte Darstellung
• In Java sind normalerweise Arrays mit Elementen eines parametrisierten
Typs unzulässig (siehe Folie 407)
• In diesem Fall gibt es aber nur Warnung bei Verwendung der Methode
• Java 7
• Compiler erzeugt nun schon Warnung bei Definition der Methode
(deutet eine sogenannte Heap-Pollution an)
• Kann mit Annotation unterdrückt werden
RT (ICS @ UIBK)
Programmiermethodik
423/613
Java Collection Framework
Übersicht
Java Collection Framework
Einleitung
Ausgewählte Klassen
Iteratoren
Weiteres Wissenswertes
RT (ICS @ UIBK)
Programmiermethodik
424/613
Java Collection Framework
Einleitung
Übersicht
Java Collection Framework
Einleitung
Ausgewählte Klassen
Iteratoren
Weiteres Wissenswertes
RT (ICS @ UIBK)
Programmiermethodik
425/613
Java Collection Framework
Einleitung
Motivation
• Programmierer benötigt sehr oft bestimmte Datenstrukturen
• Datenstrukturen sollten schon vorhanden sein
• Datenstrukturen sollten generisch sein
• Allgemeine Algorithmen (anwendbar auf unterschiedliche
Datenstrukturen) sollten vorhanden sein
• Lösung?
• Java Collection-Framework
RT (ICS @ UIBK)
Programmiermethodik
426/613
Java Collection Framework
Einleitung
Grundlagen
• Collection-Framework befindet sich im Paket java . util
• Für unterschiedliche Datenstrukturen stehen unterschiedliche Interfaces
zur Verfügung
• Interfaces geben Schnittstellen für Zugriff auf Datenstrukturen an
• Konkrete Verwaltung wird durch konkrete Implementierungen dieser
Interfaces bestimmt
• Seit Java 1.5: Collection-Framework ist generisch
• Jedes Interface kann durch unterschiedliche Implementierungen
unterstützt werden
• Es gibt polymorphe Algorithmen, die auf Collection-Objekte (Listen
etc.) angewandt werden können
RT (ICS @ UIBK)
Programmiermethodik
427/613
Java Collection Framework
Einleitung
Interfaces (Überblick)
• Interfaces sind die Grundlage
• Applikationen sollten ihren Code ausschließlich auf Interfaces aufbauen
• Interfaces bilden Hierarchien
Map
Collection
Set
List
Queue
SortedMap
SortedSet
RT (ICS @ UIBK)
Programmiermethodik
428/613
Java Collection Framework
Einleitung
Collection-Interfaces (Seit Java 1.5)
• Collection
• Collection verwaltet Objekte (Elemente)
• Interface enthält generelle Methoden (für alle Collection -Typen)
• Es gibt keine direkte Implementierung dieses Interfaces
• Set
• Collection ohne Duplikate (bzgl. equals)
• List
• Geordnete Collection (mit Duplikaten)
• Elemente können über einen Index angesprochen werden
(nicht immer effizient)
• Queue
• Verwaltung von Warteschlangen (ähnlich zu Listen)
• FIFO, Prioritätswarteschlangen
• Map
• Maps verwalten Schlüssel mit dazugehörigen Werten
• zu jedem Schlüssel maximal ein Eintrag
• SortedSet und SortedMap
• verwalten Elemente / Schlüssel in sortierter aufsteigender Reihenfolge
RT (ICS @ UIBK)
Programmiermethodik
429/613
Java Collection Framework
Einleitung
Implementierung
• Unterschiedliche Ansätze bei der Implementierung von konkreten
Collection-Klassen
• Generelle Implementierungen, die häufig in Applikationen verwendet
werden
• Spezielle Implementierungen
• Nebenläufige Implementierungen (für Multithreaded-Applikationen,
siehe Entwurf von Softwaresystemen)
• Wrapper-Implementierungen, die mit anderen Implementierungen
benutzt werden (oft generelle Implementierungen) und zusätzliche oder
eingeschränkte Funktionalität zur Verfügung stellen
• Einfache effiziente Implementierungen (Mini-Implementierungen) für
spezielle Collections
• Abstrakte Implementierungen, die Implementierungsskelett zur
Verfügung stellen und damit Implementierung eigener
Collection-Klassen erleichtern
RT (ICS @ UIBK)
Programmiermethodik
430/613
Java Collection Framework
Einleitung
Generelle Implementierungen
Interface
Set
Hash-Tabellen
Dynamische Arrays
Bäume
Verkette Liste
Hash-Tabelle
+
Verkettete Liste
HashSet
RT (ICS @ UIBK)
List
Queue
Map
HashMap
ArrayList
TreeSet
TreeMap
LinkedList
Linked
HashSet
Programmiermethodik
LinkedList
Linked
HashMap
431/613
Java Collection Framework
Einleitung
Generelle Implementierungen
• Es gibt generelle Implementierungen für Interfaces Set, List und Map
• Interfaces SortedSet und SortedMap werden von TreeSet bzw.
TreeMap zusätzlich implementiert
• Queue-Interface wird z.B. von den folgenden Klassen implementiert
• LinkedList : FIFO Warteschlangen
• PriorityQueue: Prioritätswarteschlange (ist eher eine spezielle
Implementierung)
RT (ICS @ UIBK)
Programmiermethodik
432/613
Java Collection Framework
Einleitung
Erweiterungen bei Java 1.6
• Deque (Double ended queue)
• Einfügen und Löschen an beiden Enden
• Wird u.a. von der Klasse LinkedList implementiert
• NavigableSet und NavigableMap
• Sollen SortedSet und SortedMap ersetzen
• Sind Erweiterungen, die Navigieren (aufsteigend, absteigend) erlauben
• Zusätzliche nebenläufige Implementierungen
• Zusätzliche Hilfsmethoden
RT (ICS @ UIBK)
Programmiermethodik
433/613
Java Collection Framework
Ausgewählte Klassen
Übersicht
Java Collection Framework
Einleitung
Ausgewählte Klassen
Iteratoren
Weiteres Wissenswertes
RT (ICS @ UIBK)
Programmiermethodik
434/613
Java Collection Framework
Ausgewählte Klassen
Eigenschaften ausgewählter Klassen
• ArrayList
• Indexzugriff auf Elemente überall schnell (O(1))
• Einfügen und Löschen am Listenende schnell (amortisiert: O(1)) und
mit wachsender Entfernung vom Listenende langsamer (O(n))
• LinkedList
• Indexzugriff auf Elemente an Enden schnell (O(1)) und zur Mitte hin
langsamer (O(n))
• Einfügen und Löschen ohne Indexzugriff überall gleich schnell (O(1))
• Ansonsten abhängig vom Indexzugriff (O(n))
• HashSet
• null-Elemente zulässig
• Auf Elementen muss hashCode sinnvoll definiert sein
• Einfügen, Suchen und Löschen immer gleich schnell (O(1))
• Achtung bei Rehashing (siehe API-Beschreibung)
• TreeSet
• null-Elemente nicht erlaubt
• Auf Elementen eines TreeSets muss Ordnung definiert sein (d.h.
Interface Comparable<T> implementieren)
• Geschwindigkeit von Einfügen, Suchen und Löschen: O(log(n))
RT (ICS @ UIBK)
Programmiermethodik
435/613
Java Collection Framework
Ausgewählte Klassen
Methoden (Beispiele, E ist Elementtyp)
// i n C o l l e c t i o n
int size ()
boolean add ( E e )
boolean a d d A l l ( C o l l e c t i o n <? extends E> c )
boolean remove ( O b j e c t o )
boolean r e m o v e A l l ( C o l l e c t i o n <?> c )
boolean r e t a i n A l l ( C o l l e c t i o n <?> c )
boolean c o n t a i n s ( O b j e c t o )
boolean c o n t a i n s A l l ( C o l l e c t i o n <?> c )
// i n L i s t
E get ( int i )
E set ( int i , E t )
int indexOf ( Object o )
E remove ( i n t i )
boolean a d d A l l ( i n t i , C o l l e c t i o n <? extends E> c )
RT (ICS @ UIBK)
Programmiermethodik
436/613
Java Collection Framework
Ausgewählte Klassen
Beispiel
import j a v a . u t i l . ∗ ;
L i s t <I n t e g e r > i l = new A r r a y L i s t < >();
f o r ( i n t x = 1 ; x < 1 0 ; x++) {
i l . add ( x ) ;
}
System . o u t . p r i n t l n ( i l ) ; // [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]
System . o u t . p r i n t l n ( i l . g e t ( 3 ) ) ; // 4
System . o u t . p r i n t l n ( i l . s i z e ( ) ) ; // 9
System . o u t . p r i n t l n ( i l . remove ( 2 ) ) ; // 3
System . o u t . p r i n t l n ( i l ) ; // [ 1 , 2 , 4 , 5 , 6 , 7 , 8 , 9 ]
System . o u t . p r i n t l n ( i l . c o n t a i n s ( 7 ) ) ; // t r u e
System . o u t . p r i n t l n ( i l . s e t ( 5 , 2 2 ) ) ;
System . o u t . p r i n t l n ( i l ) ; // [ 1 , 2 , 4 , 5 , 6 , 2 2 , 8 , 9 ]
System . o u t . p r i n t l n ( i l . i n d e x O f ( 2 2 ) ) ; // 5
RT (ICS @ UIBK)
Programmiermethodik
437/613
Java Collection Framework
Ausgewählte Klassen
Maps
• Arrays und Collections speichern einzelne Werte des Elementtyps
(über Indexwerte adressiert, Typ der Indexwerte ist int)
• Maps sind Verallgemeinerung von Arrays mit beliebigem Indextyp
• Beispiel Telefonbuch
• Name mit Telefonnummer verknüpft.
• Indextyp ist daher String (Name)
• Map-Eintrag hat
• Schlüssel (key)
• Wert (value)
RT (ICS @ UIBK)
Programmiermethodik
438/613
Java Collection Framework
Ausgewählte Klassen
Maps (key-value)
• Jedem Schlüssel ist genau ein Wert zugeordnet
• Map ist Menge von Schlüssel-Werte Paaren
• Schlüssel müssen innerhalb einer Map eindeutig sein
• Werte müssen nicht eindeutig sein
• Wie bei Sets gibt es grundsätzlich zwei Versionen
• HashMap
• Ungeordnet
• Mittels Hashing implementiert
• TreeMap
• Geordnet
• Rot-Schwarz-Baum (balanciert)
• Methoden wie put, get, containsKey, containsValue, remove etc.
werden angeboten
RT (ICS @ UIBK)
Programmiermethodik
439/613
Java Collection Framework
Ausgewählte Klassen
Beispiel
import j a v a . u t i l . ∗ ;
import s t a t i c j a v a . l a n g . System . o u t ;
Map<S t r i n g , Double> w i s h l i s t = new HashMap < >();
w i s h l i s t . p u t ( " Handy " , 1 9 9 . 9 9 ) ;
w i s h l i s t . p u t ( " Book " , 1 3 . 9 9 ) ;
w i s h l i s t . p u t ( " Friend " , Double . NaN ) ;
out . p r i n t l n ( w i s h l i s t ) ;
// { Book =13.99 , F r i e n d=NaN , Handy =199.99}
o u t . p r i n t l n ( w i s h l i s t . g e t ( " Book " ) ) ; // 1 3 . 9 9
o u t . p r i n t l n ( w i s h l i s t . c o n t a i n s K e y ( " Friend " ) ) ; // t r u e
o u t . p r i n t l n ( w i s h l i s t . remove ( " Handy " ) ) ; // 1 9 9 . 9 9
o u t . p r i n t l n ( w i s h l i s t ) ; // {Book =13.99 , F r i e n d=NaN}
RT (ICS @ UIBK)
Programmiermethodik
440/613
Java Collection Framework
Ausgewählte Klassen
Maps (equals, hashCode)
• HashMap und andere Klassen des Collection-Frameworks rufen
Methode equals auf, um Gleichheit von Schlüsselobjekten / Elementen
festzustellen
• Von einigen Klassen wird Methode hashCode verwendet
• Daher sollten alle Schlüssel/Element-Klassen die Methoden equals und
hashCode überschreiben
• Von Klasse Object geerbte Versionen dieser Methoden sind selten
ausreichend (nur Referenzgleichheit)
RT (ICS @ UIBK)
Programmiermethodik
441/613
Java Collection Framework
Ausgewählte Klassen
Maps und Collections
• Maps implementieren nicht Interface Collection , sind aber Teil des
Collection-Frameworks
• Maps und Collections können verknüpft werden (hier: Map<K,V>)
• Methode keySet liefert Menge aller Schlüssel einer Map als Set<K>
• Methode values liefert Menge aller Werte als Collection <V>
• Methode entrySet liefert Menge aller Einträge als
Set<Map.Entry<K,V>>
• Map.Entry<K,V> definiert Methoden K getKey() und V getValue()
• Maps kennen keine Iteratoren, Sets und Collections hingegen schon
⇒ Man kann auf diesem Wege über Maps iterieren
• Über Organisation von keySet, values, entrySet ist nichts bekannt
RT (ICS @ UIBK)
Programmiermethodik
442/613
Java Collection Framework
Ausgewählte Klassen
Maps und Collections
• Methoden keySet, values und entrySet erzeugen keine neue Collection
• Sie liefern sogenannte Sichten (views)
• Daher sind diese Methoden auch bei großen Datenmengen effizient
• Es werden keine Daten kopiert
• Sichten greifen direkt auf zugrunde liegende Map zu
• Änderungen an Sichten wirken sich auf darunterliegende Map aus und
umgekehrt
⇒ Wird Map geändert, dann wirkt sich das auf alle Sichten aus
RT (ICS @ UIBK)
Programmiermethodik
443/613
Java Collection Framework
Ausgewählte Klassen
Beispiel
import s t a t i c j a v a . l a n g . System . ∗ ;
import j a v a . u t i l . ∗ ;
Map<S t r i n g , Double> w i s h l i s t = new HashMap < >();
w i s h l i s t . p u t ( " Handy " , 1 9 9 . 9 9 ) ;
w i s h l i s t . p u t ( " Book " , 1 3 . 9 9 ) ;
w i s h l i s t . p u t ( " Friend " , Double . NaN ) ;
Set<S t r i n g > w i s h e s = w i s h l i s t . k e y S e t ( ) ;
o u t . p r i n t l n ( w i s h e s ) ; // [ Book , F r i e n d , Handy ]
w i s h l i s t . remove ( " Book " ) ;
o u t . p r i n t l n ( w i s h e s ) ; // [ F r i e n d , Handy ]
w i s h e s . remove ( " Friend " ) ;
o u t . p r i n t l n ( w i s h l i s t ) ; // { Handy =199.99}
RT (ICS @ UIBK)
Programmiermethodik
444/613
Java Collection Framework
Iteratoren
Übersicht
Java Collection Framework
Einleitung
Ausgewählte Klassen
Iteratoren
Weiteres Wissenswertes
RT (ICS @ UIBK)
Programmiermethodik
445/613
Java Collection Framework
Iteratoren
Iteratoren allgemein
• Iteratoren sind Verallgemeinerung von Indexwerten
• Werden ähnlich wie Indexwerte verwendet, aber innerer Aufbau bleibt
verborgen
• Alle Iteratoren implementieren generisches Interface Iterator <T>
• Iteratoren haben gleichen Elementtyp wie zugrunde liegende Collection
• Iterator wird durch eine Methode (z.B. iterator ()) angeboten
• Iterator bietet folgende Methoden an
• hasNext: testet, ob es weitere Elemente gibt (true) oder nicht (false )
• next: liefert nächstes Element und rückt Iterator gleichzeitig weiter, d.h.
aufeinanderfolgende Aufrufe von next liefern immer neue Elemente
• remove: entfernt zuletzt zurückgegebenes Element (optional, d.h. wirft
evtl. UnsupportedOperationException)
RT (ICS @ UIBK)
Programmiermethodik
446/613
Java Collection Framework
Iteratoren
Eigenschaften von Iteratoren
• Iterator läuft von Beginn an Element für Element durch Collection
(keine Sprünge, kein Start an beliebiger Stelle)
• Iterator steht immer zwischen zwei Elementen (oder vor erstem, nach
letztem)
• Iterator ist verbraucht, wenn er am Ende angekommen ist (keine
Wiederverwendung)
• Für neuen Durchlauf muss neuer Iterator erzeugt werden
• Innerhalb einer Collection können gleichzeitig mehrere Iteratoren
unterwegs sein
• Mehrere Iteratoren sind unabhängig voneinander und können einzeln
bewegt werden
RT (ICS @ UIBK)
Programmiermethodik
447/613
Java Collection Framework
Iteratoren
Beispiel: Iterator von Listen
...
L i s t <S t r i n g > l s = new L i n k e d L i s t <S t r i n g > ( ) ;
l s . add ( "A" ) ;
l s . add ( "B" ) ;
l s . add ( "A" ) ;
l s . add ( "B" ) ;
...
I t e r a t o r <S t r i n g > i s = l s . i t e r a t o r ( ) ;
while ( i s . hasNext ( ) ) {
String s = i s . next ( ) ;
i f ( s . e q u a l s ( "A" ) )
i s . remove ( ) ;
}
System . o u t . p r i n t l n ( l s ) ; // [ B B ]
RT (ICS @ UIBK)
Programmiermethodik
448/613
Java Collection Framework
Iteratoren
Beispiel: Iterator von Maps
Map<S t r i n g , Double> m = new HashMap<S t r i n g , Double > ( ) ;
m. p u t ( "PC1" , 1 1 9 9 . 9 0 ) ;
m. p u t ( "PC2" , 1 9 9 9 . 9 0 ) ;
m. p u t ( "PC3" , 9 8 0 . 0 0 ) ;
System . o u t . p r i n t l n (m) ;
// {PC3 =980.0 , PC1 =1199.9 , PC2=1999.9}
I t e r a t o r <Map . E n t r y <S t r i n g , Double>> i m e s ;
i m e s = m. e n t r y S e t ( ) . i t e r a t o r ( ) ;
while ( imes . hasNext ( ) ) {
Map . E n t r y <S t r i n g , Double> i t e m = i m e s . n e x t ( ) ;
i f ( item . getValue ( ) < 1500) {
System . o u t . p r i n t l n ( i t e m . g et Ke y ( ) ) ; // PC3 , PC1
}
}
// b e i LinkedHashMap / S e t w i r d i n R e i h e n f o l g e
// d e s E i n f u e g e n s i t e r i e r t
RT (ICS @ UIBK)
Programmiermethodik
449/613
Java Collection Framework
Iteratoren
Listen-Iteratoren
• Für Listen gibt noch eigene Iteratoren
• Diese implementieren Interface ListIterator <T>
• Listen-Iterator kann sich vorwärts und rückwärts bewegen
• Zusätzlich zu den Methoden von Iterator werden zum Beispiel
angeboten:
• previous und hasPrevious, die sich auf vorhergehendes Element
beziehen
• previousIndex und nextIndex liefern Indexwerte des vorhergehenden und
nächsten Elements
• Listen-Iterator ist nicht verbraucht, wenn er am Ende der Liste
angekommen ist
RT (ICS @ UIBK)
Programmiermethodik
450/613
Java Collection Framework
Iteratoren
Modifikation und Iteratoren
• Wird Collection modifiziert (z.B. neues Element eingefügt), dann
werden alle Iteratoren ungültig
• Beim nächsten Zugriffsversuch auf Iterator nach Änderung wirft dieser
ConcurrentModificationException
• Wird als fail-fast bezeichnet
• Iterator gerät nicht irgendwann in inkonsistenten Zustand
• Iterator wird sofort unbrauchbar gemacht
• Iteratoren reagieren nur auf strukturelle Änderungen, d.h. Ersetzen
eines Elements verändert Struktur nicht und lässt Iteratoren intakt
RT (ICS @ UIBK)
Programmiermethodik
451/613
Java Collection Framework
Iteratoren
Modifikation und Iteratoren
• Iteratoren bieten selbst Änderungsoperationen an, bei denen der
betreffende Iterator funktionsfähig bleibt
• Alle Iteratoren definieren Methode remove, die das zuletzt überquerte
Element aus Collection entfernt
• Aber
• Iterator muss sich zuerst bewegen, dann erst kann remove aufgerufen
werden
• Nach einem Aufruf muss erst weiteres Element überquert werden
• Bei Listen-Iteratoren ist zuletzt überquertes Element abhängig von
Laufrichtung
(kann vom Listenanfang aus gesehen vor oder hinter dem Iterator sein)
• Bei Struktur-Änderungen mittels Iterator bleibt dieser Iterator intakt
• Andere Iteratoren, die in gleicher Collection unterwegs sind, werden
ungültig
RT (ICS @ UIBK)
Programmiermethodik
452/613
Java Collection Framework
Iteratoren
Modifikation bei Listen-Iteratoren
• Bei Listen-Iteratoren gibt es neben remove noch zusätzliche Methoden
• add: fügt Element in der Lücke ein, in der der Iterator steht
• set: ersetzt zuletzt überquertes Element durch übergebenes Element
RT (ICS @ UIBK)
Programmiermethodik
453/613
Java Collection Framework
Iteratoren
foreach-Schleife
• So wie Arrays können auch Collections mit foreach-Schleife
durchlaufen werden
• Beispiel
L i s t <I n t e g e r > i l = new A r r a y L i s t < >();
...
i n t sum = 0 ;
for ( Integer i : i l )
sum += i ;
}
• foreach-Schleifen arbeiten wie Iteratoren
• Änderung der Collection während des Durchlaufens führt zur Ausnahme
• Implementiert Klasse das Interface Iterable <T>, dann können
Objekte dieser Klasse mit foreach-Schleife durchlaufen werden
i n t e r f a c e I t e r a b l e <T> { I t e r a t o r <T> i t e r a t o r ( ) ; }
RT (ICS @ UIBK)
Programmiermethodik
454/613
Java Collection Framework
Weiteres Wissenswertes
Übersicht
Java Collection Framework
Einleitung
Ausgewählte Klassen
Iteratoren
Weiteres Wissenswertes
RT (ICS @ UIBK)
Programmiermethodik
455/613
Java Collection Framework
Weiteres Wissenswertes
Abstrakte Collection-Klassen
• Unterstützen die Entwicklung neuer Collection-Klassen
• Abstrakte Klassen implementieren schon großen Teil eines Interfaces
und lassen bestimmte Teile offen
• Neue Collection-Klasse kann auf abstrakte Klasse aufbauen
(muss nicht alle Methoden eines Interfaces implementieren)
• Vorgehensweise bei Implementierung einer neuen Collection-Klasse
• Auswählen einer geeigneten abstrakten Klasse, von der geerbt wird
• Implementierung aller abstrakten Methoden
• Sollte Collection modifizierbar sein, dann müssen auch einige konkrete
Methoden überschrieben werden
(Beschreibung in API-Dokumentation der abstrakten Klasse)
• Testen der neuen Klasse (inklusive Performance)
RT (ICS @ UIBK)
Programmiermethodik
456/613
Java Collection Framework
Weiteres Wissenswertes
Beispiele für abstrakte Klassen
• Beispiele
• AbstractCollection
• AbstractSet
• AbstractList (basierend auf Array)
• AbstractSequentialList (basierend auf verketteter Liste)
• AbstractQueue
• AbstractMap
• In API-Dokumentation jeder abstrakten Klasse wird beschrieben, wie
man Klasse davon ableiten muss
• Grundlegende Implementierung
• Welche Methoden müssen implementiert werden
• Welche Methoden müssen überschrieben werden, wenn man
Modifikationen zulassen möchte
RT (ICS @ UIBK)
Programmiermethodik
457/613
Java Collection Framework
Weiteres Wissenswertes
Algorithmen im Collection-Framework
• Collection-Framework bietet neben vordefinierten Containerklassen
auch Algorithmen für Verarbeitung von Container-Klassen an
• Algorithmen werden als statische Methoden (polymorphe Methoden) in
Hilfsklasse Collections gesammelt
• Algorithmen (Beispiele)
• sort : Sortiert Elemente einer generischen Liste nach aufsteigender Größe
• binarySearch: Sucht Element in sortierter Liste (Voraussetzung) und
liefert Index zurück, wenn Element gefunden wurde
(sonst: negative Zahl)
• max: Liefert größtes Element einer Collection
• shuffle : Mischt Elemente einer generischen Liste zufällig
RT (ICS @ UIBK)
Programmiermethodik
458/613
Java Collection Framework
Weiteres Wissenswertes
Vergleiche
• Viele Methoden (z.B. sort , binarySearch) vergleichen Elemente der
Größe nach
• Benötigt Vergleichsoperation
⇒ Klassen müssen generisches Interface Comparable<T> implementieren
(siehe Folie 377)
RT (ICS @ UIBK)
Programmiermethodik
459/613
Java Collection Framework
Weiteres Wissenswertes
Comparator
• Oft sollen Objekte nach verschiedenen Kriterien verglichen werden
• Daher sind viele Collection-Methoden mit zusätzlichem Parameter,
einem Comparator, überladen
• Erfüllt gleichen Zweck
• Zum Vergleich wird aber übergebenes Comparator-Objekt benutzt
• Comparator<T> ist generisches Interface mit einer Methode compare
Methode akzeptiert zwei Objekte des Elementtyps und liefert ein
int-Ergebnis für den Vergleich zweier Objekte
RT (ICS @ UIBK)
Programmiermethodik
460/613
Java Collection Framework
Weiteres Wissenswertes
Beispiel
p u b l i c s t a t i c v o i d main ( f i n a l S t r i n g [ ] a r g s ) {
L i s t <S t r i n g > s s = new A r r a y L i s t <S t r i n g > ( ) ;
s s . add ( "Hans" ) ;
s s . add ( "eva" ) ;
s s . add ( " Gretel " ) ;
System . o u t . p r i n t l n ( s s ) ; // Hans e v a G r e t e l
Collections . sort ( ss );
System . o u t . p r i n t l n ( s s ) ; // G r e t e l Hans e v a
Comparator<S t r i n g > i g n o r e C a s e C o m p a r a t o r ;
i g n o r e C a s e C o m p a r a t o r = new Comparator<S t r i n g >() {
p u b l i c i n t compare ( S t r i n g s1 , S t r i n g s 2 ) {
r e t u r n ( s 1 . t o L o w e r C a s e ( ) . compareTo (
s2 . toLowerCase ( ) ) ) ;
}
};
C o l l e c t i o n s . s o r t ( ss , ignoreCaseComparator ) ;
System . o u t . p r i n t l n ( s s ) ; // e v a G r e t e l Hans
}
RT (ICS @ UIBK)
Programmiermethodik
461/613
Java Collection Framework
Weiteres Wissenswertes
Anonyme Klassen
• können eingesetzt werden, um schnell ein Interface zu implementieren
• kein Klassen Name erforderlich
• keine eigene Java-Datei erforderlich
• Syntax:
. . . code w i t h i n some method . . .
new I n t e r f a c e N a m e ( ) {
public void m e t h o d O f I n t e r f a c e ( ) {
...
}
}
. . . code w i t h i n some method
• innerhalb der anonymen Klasse hat man Zugriff auf
• finale Variablen der umgebenen Methode
• Member-Variablen der umgegebenen Klasse
(mittels ClassName.this.varName )
RT (ICS @ UIBK)
Programmiermethodik
462/613
Java Collection Framework
Weiteres Wissenswertes
p u b l i c c l a s s R e v e r s e I t e r a b l e <T> implements I t e r a b l e <T> {
private f i n a l T [ ] data ;
p u b l i c R e v e r s e I t e r a b l e (T [ ] d a t a ) {
t h i s . data = data ; }
p u b l i c I t e r a t o r <T> i t e r a t o r ( ) {
r e t u r n new I t e r a t o r <T>() {
i n t pos = R e v e r s e I t e r a b l e . t h i s . data . l e n g t h ;
p u b l i c boolean h a s N e x t ( ) {
return t h i s . pos > 0 ; }
public T next () {
i f ( t h i s . hasNext ( ) ) {
t h i s . pos −−;
return R e v e r s e I t e r a b l e . t h i s . data [ t h i s . pos ] ;
} e l s e throw new N o S u c h E l e m e n t E x c e p t i o n ( ) ;
}
p u b l i c v o i d remove ( ) {
throw new U n s u p p o r t e d O p e r a t i o n E x c e p t i o n ( ) ;
}
};
}
}
RT (ICS @ UIBK)
Programmiermethodik
463/613
Java Collection Framework
Weiteres Wissenswertes
Unveränderliche Collection-Klassen
• Manchmal möchte man Container-Klassen zur Verfügung stellen, die
unveränderlich sind
• Klasse Collections bietet statische Methoden, mit denen
unveränderliche Sichten auf vorhandene Container erzeugt werden
können
• Sichten auf Datenstruktur kopieren zugrunde liegende Datenstruktur
nicht
• Bieten eingeschränkte Darstellung (z.B. Sperren aller schreibenden
Methoden)
⇒ Datenstruktur kann nicht verändert werden
RT (ICS @ UIBK)
Programmiermethodik
464/613
Java Collection Framework
Weiteres Wissenswertes
Beispiele
• Methoden (Auswahl)
p u b l i c s t a t i c <T> L i s t <T> u n m o d i f i a b l e L i s t
( L i s t <? extends T> l )
p u b l i c s t a t i c <K, V> Map<K, V> u n m o d i f i a b l e M a p
(Map<? extends K, ? extends V> m)
p u b l i c s t a t i c <T> Set<T> u n m o d i f i a b l e S e t
( Set <? extends T> s )
• Anwendung
HashMap<S t r i n g , I n t e g e r > m = new HashMap < >();
...
Map<S t r i n g , I n t e g e r > rom ;
rom = C o l l e c t i o n s . u n m o d i f i a b l e M a p (m) ;
rom . p u t ( " TEST " , 1 ) ; // E x c e p t i o n
m. p u t ( " TEST " , 1 ) ;
// k e i n F e h l e r , g e f a e h r l i c h
r e t u r n rom ;
// n o r m a l e Anwendung
RT (ICS @ UIBK)
Programmiermethodik
465/613
Java Collection Framework
Weiteres Wissenswertes
Übersicht (wichtige Klassen)
Typ
ArrayList
LinkedList
HashSet
LinkedHashSet
TreeSet
HashMap
LinkedHashMap
TreeMap
RT (ICS @ UIBK)
Ordnung bleibt
null-Werte
Duplikate
3
3
7
3
3
7
3
3
3
3
3
3
7
3
3
keys: 7, values: 3
3
3
7
7
7
keys: 7, values: 3
keys: 7, values: 3
keys: 7, values: 3
Programmiermethodik
466/613
Unit Tests
Übersicht
Unit Tests
Testen
Unit-Tests mit JUnit
RT (ICS @ UIBK)
Programmiermethodik
467/613
Unit Tests
Testen
Übersicht
Unit Tests
Testen
Unit-Tests mit JUnit
RT (ICS @ UIBK)
Programmiermethodik
468/613
Unit Tests
Testen
Testen allgemein
• Testen ist der Vorgang, ein Programm oder Teil davon mit der Absicht
auszuführen, möglicherweise enthaltene Fehler zu finden
• Testen dient zur Sicherstellung von Softwarequalität
• Dazu werden spezifizierte Anforderungen mit gelieferten Ergebnissen
verglichen
RT (ICS @ UIBK)
Programmiermethodik
469/613
Unit Tests
Testen
Abgrenzung zur Verifikation
• Verifikation = formaler Korrektheitsbeweis
• Es wird versucht, mit formalen Methoden den Nachweis zu führen, dass
Programm nur richtige Ergebnisse produzieren kann
• Liefert endgültige Aussage zur Korrektheit
• Schon für kleine Programme kann Ansatz sehr aufwändig sein
• Testen = systematisches Ausprobieren
• Es wird bestimmte Anzahl von Tests konstruiert, mit denen das
Programm probeweise ausgeführt wird
• Mit Testen kann nur die Anwesenheit von Fehlern nachgewiesen
werden, nicht aber deren Abwesenheit
• Eigentlich benötigt man große Anzahl von Testfällen, um Programm
ausführlich zu testen
• Das verursacht aber meist sehr hohe Kosten
• Endgültiger Korrektheitsbeweis ist damit auch nicht möglich
RT (ICS @ UIBK)
Programmiermethodik
470/613
Unit Tests
Testen
Testen
• Um Anzahl der Tests möglichst klein zu halten, wählt man jene Tests
aus, die Programm in kritische Situationen bringen
• In diesen Situationen sind Fehler am ehesten zu erwarten
• Zwei Vorgehensweisen beim Testen
• Black-Box-Test
•
•
•
•
Nur die Anforderungen des Programms werden berücksichtigt
Schnittstelle gibt Testfälle vor
Source-Code spielt keine Rolle, Programm wird als Black-Box betrachtet
Änderungen am Quelltext (nicht Schnittstelle) erfordern keine neue
Implementierung der Tests
• White-Box
• Test orientiert sich am Quelltext des Programms
• Mit den Testfällen möchte man alle Codeabschnitte erfassen und die
einzelnen Zweige, Schleifen etc. explizit austesten
• Änderungen am Quelltext erfordern teilweise neue Tests bzw. alte Tests
werden überflüssig
RT (ICS @ UIBK)
Programmiermethodik
471/613
Unit Tests
Testen
Tests (Überblick)
einfach
aufwändig
Programmiermethodik
selten
RT (ICS @ UIBK)
häufig
• Kunde
• Abnahmetest (Applikation)
Handarbeit
• Tester
• Funktionstest (Teilsystem, Gesamtsystem)
• Applikationstest (Gesamtsystem, Applikation)
automatisierbar
• Entwickler
• Unit-Test (Methode, Klasse)
• Komponententest (Klasse, Package)
• Integrationstest (Teilsystem)
472/613
Unit Tests
Unit-Tests mit JUnit
Übersicht
Unit Tests
Testen
Unit-Tests mit JUnit
RT (ICS @ UIBK)
Programmiermethodik
473/613
Unit Tests
Unit-Tests mit JUnit
Unit-Test
• Beim Unit-Test wird kleine Einheit eines Programms betrachtet und
auf mögliche Fehler untersucht
• Einheit wird isoliert vom Rest des Gesamtsystems betrachtet
• Man testet nur den speziellen Softwarebaustein
• Testfälle werden direkt als Java-Programme erstellt
(Entwickler können ihre Stärken ausnutzen)
• Es gibt Programmiermethoden, bei denen dieses Testen elementarer
Teil des Programmierens ist
• Extreme Programming
• Test-Driven Development
RT (ICS @ UIBK)
Programmiermethodik
474/613
Unit Tests
Unit-Tests mit JUnit
JUnit
• JUnit bietet einheitliches Framework zur Organisation und
systematischen Durchführung von Unit-Tests
• Bibliothek ist nicht Teil des JDK sondern kann unter
http://www.junit.org/ heruntergeladen werden
• weiterführende Links
• http://www.junit.org/
• http://junit.sourceforge.net/doc/faq/faq.htm
RT (ICS @ UIBK)
Programmiermethodik
475/613
Unit Tests
Unit-Tests mit JUnit
Verwendung
• Entsprechendes jar-Archiv (junit-version.jar) muss in CLASSPATH
eingebunden werden
• JUnit wird für Unit-Tests verwendet, die die Korrektheit von isolierten
Klassen prüfen
• Entweder Test gelingt (grün) oder misslingt (rot)
• Das Misslingen kann als Ursache einen Fehler (Error) oder ein falsches
Ergebnis (Failure) haben, die beide durch Ausnahme signalisiert werden
• Unterschied zwischen den Begriffen liegt darin, dass Failures erwartet
werden, während Errors eher unerwartet auftreten
RT (ICS @ UIBK)
Programmiermethodik
476/613
Unit Tests
Unit-Tests mit JUnit
Vorgehen
• Zuerst werden Ergebnisse in Form von Testfällen implementiert
• Danach wird Code entwickelt
• Nach Testfällen werden zunächst leere Methoden oder Methoden mit
einer einzigen return-Anweisung definiert
• Übersetzung funktioniert, Tests schlagen noch alle fehl
• Danach werden Methodenrümpfe schrittweise vervollständigt, bis am
Ende alle Tests fehlerfrei durchlaufen werden
• Vorteile bei diesem Vorgehen
• Tests werden zuerst erstellt
• Ausgeglichene Sicht auf die geforderten Ergebnisse
• Tests können nicht verdrängt werden
• Tests geben notwendige Funktionalität vor
RT (ICS @ UIBK)
Programmiermethodik
477/613
Unit Tests
Unit-Tests mit JUnit
Vorgehen
• In JUnit sind Tests Java-Objekte
• Vor JUnit 4 musste man Testfälle von bestimmten JUnit-Klasse erben
lassen
• Ab Version 4 sollte man das aber nicht mehr machen
• Diese Vorlesung: aktuelle stabile Version von JUnit (4.11)
• Testmethoden müssen mit einer @Test-Annotation versehen werden
• Daneben gibt es noch weitere Annotationen
• Man kann mehrere Testklassen in Test-Suites zusammenfassen
• Damit Testklasse mit älteren Tests zusammenarbeiten kann
public s t a t i c j u n i t . framework . Test s u i t e ( ) {
r e t u r n new J U n i t 4 T e s t A d a p t e r ( Example . c l a s s ) ;
}
RT (ICS @ UIBK)
Programmiermethodik
478/613
Unit Tests
Unit-Tests mit JUnit
Testmethoden
• Eine Testmethode pro Test
• Signatur der Testmethoden ist vorgegeben, Methodenname ist beliebig:
@Test public void someName()
• Berechnet tatsächliches Ergebnis (have), vergleicht es mit korrektem
Ergebnis (want)
• Beide gleich ⇒ Test erfolgreich
• Verschieden ⇒ Test gescheitert
• Schematischer Aufbau einer Testmethode
@Test
public void t e s t ( ) {
i n t want = . . . ;
i n t hav e = . . . ;
a s s e r t E q u a l s ( want , h a v e ) ;
}
RT (ICS @ UIBK)
Programmiermethodik
479/613
Unit Tests
Unit-Tests mit JUnit
Vergleiche
• JUnit bietet verschiedene Methoden zum Vergleich von den Werten
want und have (Klasse Assert):
•
•
•
•
•
•
assertFalse (boolean condition)
assertTrue (boolean condition)
assertEquals (long w, long h)
assertEquals (double w, double h)
assertEquals (double w, double h, double d)
assertEquals (Object w, Object h)
• Viele weitere, siehe API-Dokumentation
• Alle Vergleichsmethoden sind überladen mit zusätzlichem ersten
Parameter message, zum Beispiel:
• assertFalse ( String message, boolean condition)
• assertEquals (Object w, Object h) erfordert Definition von equals
RT (ICS @ UIBK)
Programmiermethodik
480/613
Unit Tests
Unit-Tests mit JUnit
Testklasse
• Es gibt eine Testklasse für jede zu testende Klasse
• Testklasse importiert benötigte JUnit-Klassen und Methoden
• Testklasse definiert Testmethoden und Verwaltungsmethoden
• Zweck der Methoden wird festgelegt mit einer Annotation
• @Test: Testmethode (mehrfach)
• @Before: Wird vor jedem einzelnen Test aufgerufen
• @After: Wird nach jedem einzelnen Test aufgerufen
• @BeforeClass: Wird einmal vor allen Tests aufgerufen
• @AfterClass: Wird einmal nach allen Tests aufgerufe
RT (ICS @ UIBK)
Programmiermethodik
481/613
Unit Tests
Unit-Tests mit JUnit
Einfaches Beispiel
• Zu testende Klasse GCD mit folgender Methode
public static int gcd(int a, int b)
• Testfall für gcd(1, 1) = 1:
@Test
public void t e s t 1 ( ) {
i n t want = 1 ;
i n t hav e = GCD . gcd ( 1 , 1 ) ;
a s s e r t E q u a l s ( want , h a v e ) ;
}
RT (ICS @ UIBK)
Programmiermethodik
482/613
Unit Tests
Unit-Tests mit JUnit
Komplexeres Beispiel
• Wenn man z.B. auf gemeinsames Objekt mehrere verschiedene Tests
ausführen möchte, dann kann man mit sogenannter Test-Fixture
Code-Duplizierung vermeiden
• Siehe Eclipse-Beispiel StackTest. java
RT (ICS @ UIBK)
Programmiermethodik
483/613
Unit Tests
Unit-Tests mit JUnit
Erwarteter Fehler
• Reaktion auf unzulässige Eingaben (z.B. Exception)
• Vorgabe der erwarteten Exception
• Test scheitert, wenn Exception nicht geworfen wird
• Testfall für gcd(1, 0):
@Test ( e x p e c t e d = A r i t h m e t i c E x c e p t i o n . c l a s s )
public void t e s t 1 0 ( ) {
i n t dummy = 0 ;
i n t hav e = GCD . gcd ( 1 , 0 ) ;
a s s e r t E q u a l s (dummy , h a v e ) ;
}
• Beispiel: popEmptyTest();
RT (ICS @ UIBK)
Programmiermethodik
484/613
Unit Tests
Unit-Tests mit JUnit
Testabwicklung
• Im Java-Programm selbst
• org . junit .runner.JUnitCore. runClasses (TestClass1 . class ,
...);
oder
• org . junit .runner.JUnitCore.main("TestClass1");
• Unterschied: runClasses liefert Ergebnis, das weiterverarbeitet werden
kann
• Start der Testklasse auf der Konsole
• Testklasse(n) und JUnit im Classpath
• java org.junit.runner.JUnitCore TestClass1 ...
• java -cp "../hamcrest-core-1.3.jar:../junit-4.11.jar:."
org.junit.runner.JUnitCore junit.StackTest
• Testabwicklung in Eclipse
• Unter Run – Run As – JUnit Test kann Test gestartet werden
• Neben Package-Explorer gibt es dann zusätzliches Subfenster, in dem
Testergebnisse angezeigt werden
RT (ICS @ UIBK)
Programmiermethodik
485/613
Entwurfsmuster
Übersicht
Entwurfsmuster
Einführung
Überblick
Erzeugungsmuster
Strukturmuster
Verhaltensmuster
RT (ICS @ UIBK)
Programmiermethodik
486/613
Entwurfsmuster
Einführung
Übersicht
Entwurfsmuster
Einführung
Überblick
Erzeugungsmuster
Strukturmuster
Verhaltensmuster
RT (ICS @ UIBK)
Programmiermethodik
487/613
Entwurfsmuster
Einführung
Wiederholung (Objektorientierte Konzepte)
• Bisher besprochen
• Klassen und Interfaces
• Vererbung
• Überladen
• Überschreiben
• Polymorphismus
• Dynamisches Binden
• Wie verwendet man diese Konzepte?
• Was bildet man auf Klassen ab?
• Wie sehen Beziehungen zwischen Klassen aus?
• Vererbung?
• Komposition?
• Wo werden bestimmte Methoden definiert?
RT (ICS @ UIBK)
Programmiermethodik
488/613
Entwurfsmuster
Einführung
Wiederholung (Wiederverwendung von Software)
• Vererbung (Implementierung)
• Subklasse erbt Implementierung der Superklasse
• Teile der Superklasse sind in Subklasse sichtbar (White Box Reuse)
• Komposition
• Objekte benutzen andere Objekte
• Internas sind aufrufendem Objekt nicht bekannt
• Nur Schnittstelle ist bekannt (Black Box Reuse)
RT (ICS @ UIBK)
Programmiermethodik
489/613
Entwurfsmuster
Einführung
Vererbung
• Vorteile
• Einfache Methode für Wiederverwendung
• Polymorphismus
• Sprachunterstützung
• Nachteile
• Statischer Mechanismus, da Implementierung der Superklasse nicht
dynamisch geändert werden kann
• Veränderungen an Superklasse können Subklassen beeinflussen
(Problem der instabilen Basisklassen)
• Wiederverwendung der Subklasse eingeschränkt
(Abhängigkeit von der Superklasse)
RT (ICS @ UIBK)
Programmiermethodik
490/613
Entwurfsmuster
Einführung
Komposition
• Vorteile
• Dynamischer Mechanismus, da Referenz auf ein anderes Objekt zur
Laufzeit bestimmt werden kann
• Kapselung wird nicht verletzt (nur Interface berücksichtigen)
• Nachteile
• Code muss oft mehrmals implementiert werden
• Mehr Klassen müssen implementiert werden
• Systemverhalten ist nicht mehr in einer Klasse definiert
(hängt von Klassenbeziehungen ab)
• Komposition sollte in einigen Fällen der Vererbung vorgezogen werden
(z.B. bei Abhängigkeit von fremden Klassen)
RT (ICS @ UIBK)
Programmiermethodik
491/613
Entwurfsmuster
Einführung
Einleitendes Beispiel
Shape
•
+display()
⇒
Rectangle
Triangle
Circle
+display()
+display()
+display()
• Wie modelliert man das?
RT (ICS @ UIBK)
Programmiermethodik
492/613
Entwurfsmuster
Einführung
Einleitendes Beispiel
• Lösung?
• Neue Implementierung der Shape-Klasse?
• Andere (externe) Klasse?
• Welche Methoden?
• Wie werden Figuren zusammengesetzt?
• Viele unterschiedliche Lösungen möglich
• Problem dieser Komposition kann auch in anderen Bereichen
auftauchen
• Z.B. Dateisystem
• Ordner beinhalten Dateien oder weitere Ordner, die wiederum Dateien
und Ordner enthalten, die . . .
RT (ICS @ UIBK)
Programmiermethodik
493/613
Entwurfsmuster
Einführung
Mögliche Lösung
• 2 Arten (Elemente)
• Atomare Komponenten (Blätter in Hierarchie)
• Container (beinhalten weitere Elemente)
• Container sollte atomare Elemente und Container aufnehmen können
und diese auch gleich behandeln
• Beide Elemente sind Komponenten (gleiche Klasse)
• Basisstruktur
Component
Atomic Component
RT (ICS @ UIBK)
*
Intermediate Container
Programmiermethodik
494/613
Entwurfsmuster
Einführung
Funktionalität
• Komponente kann andere Komponenten beinhalten
• Methode add(Component)
• Jede Komponente sollte zumindest eine Operation ausführen
• Methode operation ()
• Operation auf Container sollte auf allen Teilkomponenten ausgeführt
werden
• Methode operation () muss entsprechend überschrieben / implementiert
werden
RT (ICS @ UIBK)
Programmiermethodik
495/613
Entwurfsmuster
Einführung
Verbessertes Design
• Neues Design mit minimaler Funktionalität
Component
Composite Client
«use»
*
+operation()
+add(c : Component)
Atomic Component
+operation()
Intermediate Container
+operation()
+add(c : Component)
operation(): for
each g in children:
g.operation()
RT (ICS @ UIBK)
Programmiermethodik
496/613
Entwurfsmuster
Einführung
Anwendung auf ursprüngliches Beispiel
Shape
«use»
Screen
*
+display()
+add(c : Shape)
Circle
Triangle
Rectangle
+display()
+display()
+display()
ComposedShape
+display()
+add(c : Shape)
display(): for each
g in children:
g.display()
RT (ICS @ UIBK)
Programmiermethodik
497/613
Entwurfsmuster
Einführung
Generalisierung
• Gleiche Lösung kann in verschiedenen Situationen verwendet werden
• Rollen wurden eindeutig identifiziert
• Man muss nicht nochmals über Design nachdenken
• Wiederverwendung der Architektur
⇒ Entwurfsmuster (Design Pattern)
• Konkretes Beispiel wird als Kompositum (Composite Pattern)
bezeichnet
RT (ICS @ UIBK)
Programmiermethodik
498/613
Entwurfsmuster
Überblick
Übersicht
Entwurfsmuster
Einführung
Überblick
Erzeugungsmuster
Strukturmuster
Verhaltensmuster
RT (ICS @ UIBK)
Programmiermethodik
499/613
Entwurfsmuster
Überblick
Historisches
• Entwurfsmuster sind nicht neu
• Beispiel Architektur
• Architektur von Häusern
• Stadtplanung
• In der Softwareentwicklung
• Entwurfsmuster (Design Pattern) beschreibt bewährte Schablone für
Entwurfsproblem
• Ideen aus der Architektur übernommen
• Softwareerstellung basiert auf bekannten (bewährten) Mustern
• “Das Rad nicht immer neu erfinden”
• Etablierte Lösungen aus der Vergangenheit verwenden bzw. anpassen
• Hauptreferenz:
Erich Gamma, Richard Helm, Ralph Johnson und John Vlissides
Design Patterns: Elements of Reusable Object-Oriented Software
Addison-Wesley
RT (ICS @ UIBK)
Programmiermethodik
500/613
Entwurfsmuster
Überblick
Entwurfsmuster
• Entwurfsmuster beschreibt Problem, welches immer wieder auftritt
• Es beschreibt allgemeinen Kern der Lösung
• Muster kann dann zum Lösen eines neuen Problems verwendet werden
• Ein gutes Muster sollte . . .
• Ein oder mehrere Probleme lösen
• Ein erprobtes Konzept bieten
• Auf realen Designs basieren
• Über das rein Offensichtliche hinausgehen
• Den Benutzer in den Entwurfsprozess einbinden
• Beziehungen aufzeigen, die tiefergehende Strukturen und Mechanismen
eines Systems umfassen
RT (ICS @ UIBK)
Programmiermethodik
501/613
Entwurfsmuster
Überblick
Entwurfsmuster: Elemente
• Name
• Beschreibt kurz und bündig, worum es geht
• Erweitert das Design-Vokabular
• Problem
• Beschreibt die Anwendung
• Es wird das Problem und entsprechender Kontext beschrieben
• Lösung
• Beschreibt die einzelnen Elemente
• Beteiligte Klassen mit Verantwortungen
• Beziehungen
• Verantwortung und Zusammenspiel der Klassen
• Kann als allgemeine Schablone (Template) aufgefasst werden
• Abstrakte Beschreibung eines Design-Problems und seiner Lösung
• Auswirkungen
• Wie wirkt sich der Einsatz aus?
• Vor- bzw. Nachteile?
RT (ICS @ UIBK)
Programmiermethodik
502/613
Entwurfsmuster
Überblick
Klassifikation
• Erzeugungsmuster
• Wie kann man Erzeugung von Objekten unterstützen?
• Erzeugungsmuster entkoppeln die Konstruktion eines Objekts von seiner
Repräsentation
• Strukturmuster
• Wie kann man Klassen/Interfaces verbinden, um Objekte zu erzeugen,
die neue Funktionalität realisieren?
• Verhaltensmuster
• Wie kann man Interaktion zwischen Objekten und komplexen
Algorithmen/Kontrollflüssen beschreiben?
• Wie gruppiert man Objekte, um Aufgaben zu lösen, die nicht von einem
Objekt alleine gelöst werden können?
RT (ICS @ UIBK)
Programmiermethodik
503/613
Entwurfsmuster
Überblick
Klassifikation
Bereich
Erzeugungsmuster
Bereich
Strukturmuster
Klasse
Fabrikmethode
Adapter (klassenbasiert)
Objekt
Abstrakte
Erbauer
Prototyp
Singleton
Adapter (objektbasiert)
Brücke
Dekorierer
Fassade
Fliegengewicht
Kompositum
Stellvertreter
RT (ICS @ UIBK)
Fabrik
Programmiermethodik
Verhaltensmuster
Interpreter
Schablonenmethode
Befehl
Beobachter
Besucher
Iterator
Memento
Strategie
Vermittler
Zustand
Zuständigkeitskette
504/613
Entwurfsmuster
Überblick
Klassifikation
Bereich
Bereich
Erzeugungsmuster Strukturmuster
Verhaltensmuster
Klasse
Factory Method
Adapter (class)
Objekt
Abstract Factory
Builder
Prototype
Singleton
Adapter (object)
Bridge
Decorator
Facade
Flyweight
Composite
Proxy
RT (ICS @ UIBK)
Programmiermethodik
Interpreter
Template Methode
Command
Observer
Visitor
Iterator
Memento
Strategy
Mediator
State
Chain of Responsibility
505/613
Entwurfsmuster
Überblick
Weitere Muster
• Bisher beschriebene Muster sind grundlegende Muster
• Es wurden mittlerweile viele weitere Muster vorgeschlagen, die aber
nicht zu den Entwurfsmustern gezählt werden
• Analysemuster
• Typische Fälle der Anforderungsanalyse
• Architekturmuster
• Beschreiben typische Softwarearchitekturen
• Idiom (Softwaretechnik)
• Muster, die unterhalb der Ebene des Entwurfs bei der Programmierung
auftreten
• Kommunikationsmuster
• Beziehen sich auf Kommunikationswege zwischen Personen einer
Organisation
• Organisationsmuster
• Beschreiben Elemente der Strukturen von Organisationen
• Antimuster
• Beschreiben, wie man es nicht machen sollte
• Beispiele: “Gott-Objekt” (Objekt, das alles weiß und kann),
“Spaghetti-Code” (Code ohne Struktur) , Programmierung mittels Copy
& Paste
RT (ICS @ UIBK)
Programmiermethodik
506/613
Entwurfsmuster
Erzeugungsmuster
Übersicht
Entwurfsmuster
Einführung
Überblick
Erzeugungsmuster
Strukturmuster
Verhaltensmuster
RT (ICS @ UIBK)
Programmiermethodik
507/613
Entwurfsmuster
Erzeugungsmuster
Singleton
• Name
• Singleton
• Zweck
• Es sollte nur eine Instanz einer Klasse angelegt werden
• Die Erzeugung sollte nur an einer Stelle geschehen
• Motivation
• Bestimmte Klasse sollte nur einmal vorhanden sein
• Z.B. nur ein Drucker-Spooler, nur ein Window-Manager etc.
• Globale Variable würde OO-Prinzipien verletzen
• Klasse sollte selbst für Verwaltung Ihrer Instanz verantwortlich sein
• Anwendbarkeit
• Es sollte nur genau ein Exemplar dieser Klasse vorhanden sein und diese
sollte nur über einen Zugriffspunkt erreichbar sein
• Es muss möglich sein, eine Erweiterung des Singletons zu realisieren
und die Klienten müssen sich nicht darum kümmern
RT (ICS @ UIBK)
Programmiermethodik
508/613
Entwurfsmuster
Erzeugungsmuster
Singleton
• Struktur
Singleton
–instance: Singleton
–singletonData
return instance;
–Singleton()
+getInstance()
+operation()
+getData()
• Beteiligte Akteure
• Singleton
• Definiert Operation für Zugriff auf einzige Instanz
• Ist für die Erzeugung der einzigen Instanz verantwortlich
• Zusammenspiel
• Klienten greifen nur über entsprechende Methode auf Instanz zu
RT (ICS @ UIBK)
Programmiermethodik
509/613
Entwurfsmuster
Erzeugungsmuster
Singleton
• Vorteile
• Kontrollierter Zugriff auf einzige Instanz
• Reduzierter Namensraum (im Vergleich zu statischen Konstanten)
• Erlaubt auch variable Anzahl von Instanzen
• Nur Methode getInstance () ändern
• Flexibler als Klassenmethoden
• Erlaubt auch Vererbung
• Nachteile
• Exzessive Verwendung von Singletons simuliert globale Variablen
• Testbarkeit von Singletons ist schlecht
• Synchronisation muss bei nebenläufigen Programmen berücksichtigt
werden
• In einigen objektorientierten Programmiersprachen gibt es keine
Möglichkeit, Klassenmethoden zu schreiben
RT (ICS @ UIBK)
Programmiermethodik
510/613
Entwurfsmuster
Erzeugungsmuster
Singleton
• Implementierung
• Sicherstellen, dass nur eine Instanz existiert
• Ableiten von Singleton-Klasse
• Implementierungsabhängig
• Praxiseinsatz
• Weit verbreitet
• Typischerweise bei GUIs
• Querverweise
• Viele andere Muster können als Singleton implementiert werden
• Siehe zum Beispiel Abstrakte Fabrik
RT (ICS @ UIBK)
Programmiermethodik
511/613
Entwurfsmuster
Erzeugungsmuster
Singleton: Beispielcode
public class C l a s s i c S i n g l e t o n {
private static ClassicSingleton instance = null ;
p r i v a t e C l a s s i c S i n g l e t o n ( ) {}
public static C l a s s i c S i n g l e t o n getInstance () {
i f ( i n s t a n c e == n u l l ) { // n o t t h r e a d s a f e
i n s t a n c e = new C l a s s i c S i n g l e t o n ( ) ;
}
return i n s t a n c e ;
}
}
public class Singleton {
// t h r e a d s a f e i n i t d u r i n g c l a s s l o a d i n g
p r i v a t e s t a t i c S i n g l e t o n i n s t a n c e = new S i n g l e t o n ( ) ;
p r i v a t e S i n g l e t o n ( ) {}
public static Singleton getInstance () {
return i n s t a n c e ;
}
}
RT (ICS @ UIBK)
Programmiermethodik
512/613
Entwurfsmuster
Erzeugungsmuster
Abstrakte Fabrik
• Name
• Abstrakte Fabrik (engl.: Abstract Factory, Kit)
• Zweck
• Schnittstelle für Erzeugen von Objektfamilien oder verwandten
Objekten anbieten
• Konkrete Klassen sind nicht bekannt
• Motivation
• Beispiel GUIs
• Unterschiedliche Look-and-feel-Standards implementieren
• Für Portierbarkeit sollte Applikation nicht die einzelnen
GUI-Komponenten für jeden Standard extra kodieren
• Benutzer sollte unabhängig von Standard arbeiten können
• Lösung (siehe Beispiel)
RT (ICS @ UIBK)
Programmiermethodik
513/613
Entwurfsmuster
Erzeugungsmuster
Abstrakte Fabrik
• Anwendbarkeit
• Wenn System unabhängig von Art der Erzeugung seiner Produkte
arbeiten soll
• Wenn System mit einer oder mehreren Produktfamilien konfiguriert
werden soll
• Wenn Gruppe von Produkten erzeugt und gemeinsam genutzt werden
soll
• Wenn in Klassenbibliothek die Schnittstellen von Produkten ohne deren
Implementierung bereitgestellt werden sollen
RT (ICS @ UIBK)
Programmiermethodik
514/613
Entwurfsmuster
Erzeugungsmuster
Abstrakte Fabrik: Struktur
AbstractFactory
ProductClient
+createProductA()
+createProductB()
ConcreteFactory1
ConcreteFactory2
+createProductA()
+createProductB()
+createProductA()
+createProductB()
AbstractProductA
ProductA1
ProductA2
AbstractProductB
ProductB1
RT (ICS @ UIBK)
ProductB2
Programmiermethodik
515/613
Entwurfsmuster
Erzeugungsmuster
Abstrakte Fabrik
• Beteiligte Akteure
• AbstractFactory
• Schnittstelle für Operationen, die zur Erzeugung abstrakter Produkte
dienen
• ConcreteFactory
• Implementiert Operationen zur Erzeugung konkreter Produktobjekte
• AbstractProduct
• Definiert eine Schnittstelle für Produkttyp
• ConcreteProduct
• Konkrete Implementierung eine Produkts
• Client
• Benutzt nur die Schnittstellen AbstractFactory und AbstractProduct
• Zusammenspiel
• Eine Instanz einer ConcreteFactory zur Laufzeit
• Erzeugt Produktobjekte mit bestimmter Implementierung
RT (ICS @ UIBK)
Programmiermethodik
516/613
Entwurfsmuster
Erzeugungsmuster
Abstrakte Fabrik
• Konsequenzen
• Vorteile
• Isoliert konkrete Klassen
• Austausch von Produktfamilien sehr einfach
• Fördert Konsistenz zwischen Produkten einer Produktfamilie
• Nachteile
• Erweiterung mit neuen Produktfamilien ist umständlich
• Schnittstelle der abstrakten Fabrik legt Produkte fest
• Implementierung
• Fabriken werden oft als Singletons implementiert
• Konkrete Fabrik muss alle Methoden überschreiben
• Erweiterbarkeit
• Abstrakte Fabrik bietet nur eine make-Methode mit Parameter an
• Parameter gibt die Art des Produkts an
• Querverweise
• Singleton (siehe Implementierung)
RT (ICS @ UIBK)
Programmiermethodik
517/613
Entwurfsmuster
Erzeugungsmuster
Struktur: Konkretes Beispiel
WidgetFactory
WidgetClient
+createScrollbar()
+createWindow()
MotifWidgetFactory
MetalWidgetFactory
+createScrollbar()
+createWindow()
+createScrollbar()
+createWindow()
AbstractScrollbar
MotifScrollbar
MetalScrollbar
AbstractWindow
MotifWindow
RT (ICS @ UIBK)
MetalWindow
Programmiermethodik
518/613
Entwurfsmuster
Erzeugungsmuster
Beispiel
public abstract c l a s s GUIFactory {
private f i n a l s t a t i c GUIFactory f a c t o r y ;
static {
i n t s y s ; // . . . d e t e r m i n e s s y s t e m
f a c t o r y = ( s y s == 0 ?
new W i n F a c t o r y ( ) : new OSXFactory ( ) ) ;
}
public s t a t i c GUIFactory getFactory () {
r e t u r n f a c t o r y ; // s i n g l e t o n w i t h i n h e r i t a n c e
}
p u b l i c a b s t r a c t Button c r e a t e B u t t o n ( ) ;
}
p u b l i c c l a s s W i n F a c t o r y extends G U I F a c t o r y {
p u b l i c Button c r e a t e B u t t o n ( ) {
r e t u r n new WinButton ( ) ;
}}
p u b l i c c l a s s OSXFactory extends G U I F a c t o r y {
p u b l i c Button c r e a t e B u t t o n ( ) {
r e t u r n new OSXButton ( ) ;
RT (ICS @ UIBK)
Programmiermethodik
519/613
Entwurfsmuster
Erzeugungsmuster
Beispiel
p u b l i c i n t e r f a c e Button {
public void p a i n t ( ) ;
}
p u b l i c c l a s s WinButton implements Button {
public void p a i n t ( ) {
System . o u t . p r i n t l n ( " WinButton : " ) ;
}
}
p u b l i c c l a s s OSXButton implements Button {
public void p a i n t ( ) {
System . o u t . p r i n t l n ( " OSXButton : " ) ;
}
}
public class Application {
p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) {
GUIFactory f a c t o r y = GUIFactory . getFactory ( ) ;
Button b u t t o n = f a c t o r y . c r e a t e B u t t o n ( ) ;
button . paint ( ) ;
...
RT (ICS @ UIBK)
Programmiermethodik
520/613
Entwurfsmuster
Erzeugungsmuster
Weitere Erzeugungsmuster
• Fabrikmethode
• Definiert Klassenschnittstelle mit Operationen zum Erzeugen eines
Objektes, aber lässt Unterklassen entscheiden, von welcher Klasse das
zu erzeugende Objekt ist
• Erbauer
• Trennt Konstruktion eines komplexen Objekts von seiner Repräsentation
so, dass derselbe Konstruktionsprozess unterschiedliche
Repräsentationen erzeugen kann
• Prototyp
• Bestimmt Arten zu erzeugender Objekte durch Verwendung eines
prototypischen Exemplars, und erzeugt neue Objekte durch Kopieren
dieses Prototypen
RT (ICS @ UIBK)
Programmiermethodik
521/613
Entwurfsmuster
Strukturmuster
Übersicht
Entwurfsmuster
Einführung
Überblick
Erzeugungsmuster
Strukturmuster
Verhaltensmuster
RT (ICS @ UIBK)
Programmiermethodik
522/613
Entwurfsmuster
Strukturmuster
Adapter
• Name
• Klassenbasierter Adapter, Objektbasierter Adapter
• engl.: Adapter(class), Adapter(object) (synonym: Wrapper)
• Zweck
• Schnittstelle einer Klasse in andere von Klienten erwartete Schnittstelle
konvertieren
• Motivation
• Oft möchte man Bibliothek verwenden, die aber keine kompatible
Schnittstelle hat (die vom Benutzer erwartet wird)
• Meist kann man Bibliothek nicht ändern
• Man hat nicht den Quellcode
• Man sollte nicht für jede neue Applikation die Schnittstelle einer
Bibliothek ändern
RT (ICS @ UIBK)
Programmiermethodik
523/613
Entwurfsmuster
Strukturmuster
Adapter
• Lösung
• Es wird Klasse benutzt, die die Schnittstelle adaptiert
• 2 Arten
• Klassenbasierter Adapter basierend auf (Mehrfach)-Vererbung
(Adapter implementiert Schnittstelle, erbt von Bibliotheksklasse)
• Objektbasierter Adapter basierend auf Komposition
(Adapter implementiert Schnittstelle, nutzt Bibliotheksklasse)
• Anwendbarkeit
• Wenn man Klasse benutzen möchte, deren Schnittstelle nicht der
erwarteten Schnittstelle entspricht
• Man möchte wiederverwendbare Klasse erzeugen, die mit nicht
verwandten oder unvorhergesehenen Klassen zusammenarbeiten kann
RT (ICS @ UIBK)
Programmiermethodik
524/613
Entwurfsmuster
Strukturmuster
Adapter: Struktur (Klassenbasiert)
AdapterClient
«interface»
Target
+request()
Adaptee
+specificRequest()
Adapter
+request()
... specificRequest() ...
RT (ICS @ UIBK)
Programmiermethodik
525/613
Entwurfsmuster
Strukturmuster
Adapter: Struktur (Objektbasiert)
Target
Adaptee
+request()
+specificRequest()
AdapterClient
-adaptee
Adapter
+request()
... adaptee.specificRequest() ...
RT (ICS @ UIBK)
Programmiermethodik
526/613
Entwurfsmuster
Strukturmuster
Adapter
• Beteiligte Akteure
• Target
• Definiert spezifische Schnittstelle, die Client benutzt
• Client
• Arbeitet mit Objekten zusammen, die die Target-Schnittstelle
implementieren
• Adaptee
• Definiert existierende Schnittstelle, die adaptiert werden muss
• Adapter
• Adaptiert Schnittstelle von Adaptee auf erwartete Target-Schnittstelle
• Zusammenspiel
• Klienten können Target-Schnittstelle benutzen
• Adapter ruft Operationen im Adaptee auf, um Aufrufe weiterzuleiten
RT (ICS @ UIBK)
Programmiermethodik
527/613
Entwurfsmuster
Strukturmuster
Adapter: Konsequenzen
• Klassenbasierter Adapter
• Kann nicht angewandt werden, wenn man Klasse und ihre Subklassen
adaptieren möchte
• Erlaubt dem Adapter das Überschreiben
• Objektbasierter Adapter
• Einzelner Adapter kann mit mehreren zu adaptierbaren Klassen (Klasse
und Subklassen davon) zusammenarbeiten
• Überschreiben von Verhalten wird schwieriger
• Wie umfangreich fällt die Adaptierung aus?
• Einfache Schnittstellenkonvertierung
• Andere Namen für Operationen
• Ändern der Anzahl oder Anordnung der Parameter
• Änderung der Operationen
• Spezielle Adapter (z.B. n-Weg Adapter)
• Eine Adapterklasse kann mehrere Interfaces implementieren
• So wird Klasse für 2 oder mehrere Klienten benutzbar
RT (ICS @ UIBK)
Programmiermethodik
528/613
Entwurfsmuster
Strukturmuster
Adapter
• Implementierung
• Abhängig von der Sprache (Mehrfachvererbung beim klassenbasierten
Adapter oder Implementierung von Interfaces)
• Implementierung von speziellen Adaptern
• Unterschiedliche Ansätze (siehe Gamma-Buch)
• Querverweise
• Ähnlich zum Stellvertreter-Muster (siehe später)
RT (ICS @ UIBK)
Programmiermethodik
529/613
Entwurfsmuster
Strukturmuster
Kompositum
• Name
• Kompositum (engl.: Composite)
• Zweck
• Erstellt Baumstruktur von Objekten, um Teile-Ganzes-Hierarchie zu
repräsentieren
• Erlaubt Klienten, individuelle Objekte und zusammengesetzte Objekte
einheitlich zu benutzen
• Motivation
• GUI-Applikationen
• Verschiedene Komponenten, die wiederum in größere Komponenten
gruppiert werden können.
• Es wird rekursive Komposition benötigt, damit Klient keine
Unterscheidung machen muss
• Anwendbarkeit
• Wenn man Teile-Ganzes-Beziehungen repräsentieren möchte
• Klienten sollten Objekte (individuell, zusammengesetzt) einheitlich
behandeln können
RT (ICS @ UIBK)
Programmiermethodik
530/613
Entwurfsmuster
Strukturmuster
Kompositum: Struktur
Component
+operation()
+add(c : Component)
+remove(c : Component)
+getChild(ch : int)
«use»
Composite Client
*
-children
Composite
Leaf
+operation()
+operation()
+add(c : Component)
+remove(c : Component)
+getChild(ch : int)
for each g in children:
g.operation()
RT (ICS @ UIBK)
Programmiermethodik
531/613
Entwurfsmuster
Strukturmuster
Kompositum
• Beteiligte Akteure
• Component
• Definiert Schnittstelle für Objekte
• Liefert Default-Implementierungen für Operationen, die allen Klassen
gemeinsam sind (falls möglich)
• Definiert Schnittstelle für Zugriff (und das Management) von
Kindkomponenten
• Optional: Definiert Schnittstelle für den Zugriff auf Vaterknoten in
Kompositionsstruktur
• Leaf
• Repräsentiert Blatt, d.h. konkrete Klasse
• Definiert Verhalten für primitive Komponenten
• Composite
• Definiert Verhalten für zusammengesetzte Komponenten
• Speichert Kindkomponenten
• Implementiert Operationen zur Verwaltung der Kindkomponenten
• Client
• Manipuliert Objekte in Komposition mit Hilfe der
Component-Schnittstelle
RT (ICS @ UIBK)
Programmiermethodik
532/613
Entwurfsmuster
Strukturmuster
Kompositum
• Zusammenspiel
• Klienten benutzen Component-Schnittstelle, um mit Objekten in
Komposition zu interagieren
• Handelt es sich um Blatt, dann wird Operation direkt ausgeführt
• Handelt es sich um zusammengesetzte Komponente, dann wird Aufruf
an die Kindkomponenten weitergeleitet
• Konsequenzen
• Definiert Klassenhierarchien (rekursiv)
• Einfacher Klient
• Klient muss sich nicht um Art der Komponente kümmern
• Erleichtert Hinzufügen von Komponenten
• Neue Komponenten funktionieren automatisch in bestehenden
Hierarchien und mit bestehendem Code
• Klienten müssen nicht verändert werden.
• Manchmal zu generell
• Einschränkungen (Anzahl der Komponenten) möglich, aber umständlich
• Einschränkungen auf Klassen umständlich (Typsystem hilft hier nicht)
RT (ICS @ UIBK)
Programmiermethodik
533/613
Entwurfsmuster
Strukturmuster
Kompositum: Implementierung
• Explizite Referenzen auf Vaterknoten berücksichtigen
• Maximierung der Komponenten-Schnittstelle
• Implementierung der Management-Operationen (add()-Methode)
• Unterstützung von Transparenz
• Methode wird in Superklasse implementiert
• Hat Implementierung mit Fehlerbehandlung
• Im Blatt nicht sinnvoll
• Container muss Methode sinnvoll überschreiben
• Unterstützung von Sicherheit
• Methode wird im Container implementiert
• Klient muss aber nun testen, ob er Blatt oder Container benutzt
• Verwaltung der Komponenten
• Datenstruktur hängt von Applikation ab
• Ordnung der Kindkomponenten (z.B. für Überlappungen in Grafiken)
• Caching (von Durchläufen)
• Löschen von Objekten (in Sprachen ohne Garbage-Collection)
RT (ICS @ UIBK)
Programmiermethodik
534/613
Entwurfsmuster
Strukturmuster
Kompositum
• Beispielcode
• Siehe CompositeClient.java
• Querverweise
• Beziehung bestehen zu einigen Entwurfsmustern
• Iterator kann zum Traversieren benutzt werden
RT (ICS @ UIBK)
Programmiermethodik
535/613
Entwurfsmuster
Strukturmuster
Stellvertreter
• Name
• Stellvertreter (engl.: Proxy, Synonym: Surrogate)
• Zweck
• Bereitstellen eines Stellvertreters (Platzhalters) für Objekt, durch den
Zugriff auf Objekt kontrolliert wird
• Motivation
• Zugriff auf Objekt soll nicht über direkte Referenz erfolgen
• Beispiele
• Z.B. Erzeugung des realen Objekts benötigt sehr viele Ressourcen und
wird nur dann durchgeführt, wenn Objekt auch wirklich benötigt wird
(ansonsten wird mit dem Platzhalter gearbeitet)
• Zugriff erfordert Authentifizierung
• Lösung
• Gemeinsame Schnittstelle für reales Objekt und Stellvertreter
• Stellvertreter hat Referenz auf reales Objekt
• Benutzer verwendet Stellvertreter, der möglicherweise reales Objekt
verwendet
RT (ICS @ UIBK)
Programmiermethodik
536/613
Entwurfsmuster
Strukturmuster
Stellvertreter: Anwendbarkeit
• Immer wenn man eine “intelligente” Referenz auf Objekt benötigt
• Remote Proxy
• Entfernter Zugriff (Objekt in anderem Adressraum, über Netzwerk)
• Virtual Proxy
• Erzeugung speicherintensiver Objekte (reales Objekt wird erst beim
ersten Zugriff erzeugt)
• Protection Proxy
• Zugriffsüberprüfung, differenzierter Zugriff für unterschiedliche Benutzer
• Cache Proxy
• Zwischenspeicherung von Resultaten für schnelleren Zugriff
• Smart Reference
• Zählen der Zugriffe
• Persistenzoperationen
• Locking
RT (ICS @ UIBK)
Programmiermethodik
537/613
Entwurfsmuster
Strukturmuster
Stellvertreter: Struktur
«interface»
Subject
Proxy Client
+request()
RealSubject
+request()
Proxy
-subject
+request()
... subject.request() ...
RT (ICS @ UIBK)
Programmiermethodik
538/613
Entwurfsmuster
Strukturmuster
Stellvertreter
• Beteiligte Akteure
• Proxy
•
•
•
•
•
Verwaltet Referenz auf reales Subjekt
Hat gleiche Schnittstelle wie Subjekt
Kontrolliert Zugriff auf Subjekt
Kann auch für Erzeugen und Löschen des Subjekts verantwortlich sein
Weitere Verantwortung hängt von Art des Proxys ab
• Subject
• Definiert gemeinsame Schnittstelle für reales Subjekt und Proxy, damit
Proxy als Stellvertreter benutzt werden kann
• RealSubject
• Definiert reales Subjekt, das der Proxy repräsentiert
• Zusammenspiel
• Proxy leitet Aufrufe an Subjekt weiter (abhängig vom Kontext und Art
des Proxys)
RT (ICS @ UIBK)
Programmiermethodik
539/613
Entwurfsmuster
Strukturmuster
Stellvertreter
• Konsequenzen
• Zusätzliche Indirektion
• Abhängig von Art des Proxys kann das unterschiedliche Konsequenzen
haben:
• Remote Proxy kann Umstand verbergen, dass sich angesprochenes
Subjekt in einem anderen Adressraum befindet
• Virtual Proxy kann Optimierungen vornehmen (z.B. copy-on-write)
• Protection Proxy kann Zugriffsrechte eines Aufrufers überprüfen
• Implementierung
• Proxy muss nicht immer Typ des Subjekts kennen (nur Interface)
• Vorteil: Proxy kann für mehrere konkrete Klassen verwendet werden
• Nachteil: kein create-on-demand
• Querverweise
• Ähnlichkeit zu Adapter
• Proxy hat aber gleiche Schnittstelle
• Proxy kann Zugriffe unterbinden
• Dekorierer
• Dekorierer gibt aber Funktionalität dazu
RT (ICS @ UIBK)
Programmiermethodik
540/613
Entwurfsmuster
Strukturmuster
Weitere Strukturmuster
• Fassade
• Bietet einheitliche Schnittstelle zu Menge von Schnittstellen eines
Subsystems
• Brücke
• Entkoppelt Abstraktion von Implementierung, so dass beide unabhängig
voneinander variiert werden können
• Dekorierer
• Erweitert Objekt dynamisch um Zuständigkeiten
• Fliegengewicht
• Nutzt Objekte kleinster Granularität gemeinsam, um große Mengen von
ihnen effizient verwenden zu können
RT (ICS @ UIBK)
Programmiermethodik
541/613
Entwurfsmuster
Verhaltensmuster
Übersicht
Entwurfsmuster
Einführung
Überblick
Erzeugungsmuster
Strukturmuster
Verhaltensmuster
RT (ICS @ UIBK)
Programmiermethodik
542/613
Entwurfsmuster
Verhaltensmuster
Iterator
• Name
• Iterator (Synonym: Cursor)
• Zweck
• Ermöglicht sequentiellen Zugriff auf Sammlung (komplexes Objekt),
ohne die darunter liegende Struktur offen zu legen
• Motivation
• Sammlung von Elementen sollte Benutzer Möglichkeit für Traversierung
aller Elemente anbieten
• Benutzer sollte sich nicht um interne Struktur kümmern müssen
• Traversieren sollte auf unterschiedliche Art und Weise stattfinden
können (ohne Schnittstelle mit vielen Operationen)
• Lösung: Spezielles Objekt für Zugriff und Traversierung (Iterator)
• Schnittstelle; verwaltet aktuelle Traversierung (aktuelles Element)
• Sammlung selbst ist für Erzeugung des Iterators verantwortlich
RT (ICS @ UIBK)
Programmiermethodik
543/613
Entwurfsmuster
Verhaltensmuster
Iterator
• Anwendbarkeit
• Wenn man auf komplexes Objekt ohne Kenntnis der internen Struktur
zugreifen möchte
• Wenn man unterschiedliche Traversierungsarten unterstützen möchte
• Wenn man einheitliche Schnittstelle für Traversieren verschiedener
Strukturen unterstützen möchte (Polymorphie ausnutzen)
RT (ICS @ UIBK)
Programmiermethodik
544/613
Entwurfsmuster
Verhaltensmuster
Struktur
«interface»
Aggregate
«interface»
Iterator
«use»
Iterator Client
«use»
+createIterator()
+first()
+next()
+isDone()
+currentItem()
ConcreteIterator
ConcreteAggregate
«use»
+createIterator()
+first()
+next()
+isDone()
+currentItem()
return new ConcreteIterator(this)
RT (ICS @ UIBK)
Programmiermethodik
545/613
Entwurfsmuster
Verhaltensmuster
Iterator
• Beteiligte Akteure
• Iterator
• Definiert Schnittstelle für Zugriff und Traversieren
• ConcreteIterator
• Implementiert Schnittstelle
• Verwaltet aktuelle Position beim Traversieren
• Aggregate
• Definiert Schnittstelle für Erzeugung eines Iterators
• ConcreteAggregate
• Implementiert Schnittstelle für Erzeugung eines konkreten Iterators
• Zusammenspiel
• Konkreter Iterator verwaltet Traversieren und kann Nachfolger des
aktuellen Elements berechnen
• Konsequenzen
• Unterschiedliche Traversierungsvarianten werden unterstützt
• Iteratoren vereinfachen Schnittstelle
• Es können gleichzeitig mehrere Traversierungen stattfinden
• Aber erhöhte Laufzeit- und Speicherkosten
RT (ICS @ UIBK)
Programmiermethodik
546/613
Entwurfsmuster
Verhaltensmuster
Iterator: Implementierung
• Wer kontrolliert das Iterieren?
• Externer Iterator
• Im Klienten, flexibler, mehrere Operationen (hasNext, next, etc.)
• Interner Iterator
• Im Iterator, Klient kann nur eine Operation für alle Elemente ausführen
lassen
• Wer definiert den Algorithmus?
• Der Iterator ⇒ besser für unterschiedliche Variationen, unterläuft aber
Kapselung
• Die Sammlung selbst ⇒ Iterator verwaltet nur den aktuellen Zustand
beim Traversieren
• Umgang mit Modifikationen
• Robuste Iteratoren erlauben Einfügen/Löschen (Kein Einfluss auf
Traversierung, keine Kopie der Sammlung notwendig)
• Erweiterung der Schnittstelle ( previous (), etc.)
• Privilegierte Iteratoren (nicht auf alle Elemente zugreifen)
• Iteratoren für Kompositum (interner Iterator einfacher)
RT (ICS @ UIBK)
Programmiermethodik
547/613
Entwurfsmuster
Verhaltensmuster
Iterator
• Beispielcode
• Java Collection-Framework
• Über die iterator ()-Methode
• Beispiel mit Composite-Pattern
p u b l i c c l a s s ComplexPart extends P a r t {
p r i v a t e f i n a l L i s t <Part > p a r t s ;
...
p u b l i c double g e t P r i c e ( ) {
double sum = 0 . 0 ;
f o r ( I t e r a t o r <Part > i = p a r t s . i t e r a t o r ( ) ; i . h a s N e x t ( ) ; )
sum += i . n e x t ( ) . g e t P r i c e ( ) ;
r e t u r n sum ;
}
...
}
• Querverweise
• Kompositum (siehe Implementierung)
RT (ICS @ UIBK)
Programmiermethodik
548/613
Entwurfsmuster
Verhaltensmuster
Beobachter
• Name
• Beobachter (engl.: Observer, Synonyme: Dependent, Publish-Subscribe)
• Zweck
• Definition einer 1-zu-n Beziehung zwischen Objekten, damit
Zustandsänderung eines Objekts (Subjekt, Observable) an alle
abhängigen Objekte (Beobachter, Observer) automatisch weitergeleitet
wird
• Motivation
• Wie implementiert man 1-zu-n Beziehung zwischen Objekten
• Wenn Objekt seinen Zustand ändert, dann sollen alle anderen Objekte
automatisch ein Update erhalten
• Objekt, das Daten erzeugt, sollte nicht von den anderen Objekten
abhängen
RT (ICS @ UIBK)
Programmiermethodik
549/613
Entwurfsmuster
Verhaltensmuster
Beobachter
• Motivation (Beispiel)
• Wir verwalten mehrere Werte
• Wir wollen Werte auf unterschiedliche Art und Weise darstellen
• Alle Komponenten sollen immer die gleichen Daten darstellen
RT (ICS @ UIBK)
Programmiermethodik
550/613
Entwurfsmuster
Verhaltensmuster
Beobachter
• Motivation (Lösung)
• Beobachtetes Objekt/Subjekt (Subject, Observable) bietet
Mechanismus, um Beobachter (Observers) an- und abzumelden und
diese über Änderungen zu informieren
• Anwendbarkeit
• Wenn Änderung eines Objekts Änderungen in anderen Objekten nach
sich zieht, und man Anzahl der abhängigen Objekte nicht von
vornherein kennt
• Wenn ein Objekt anderen Objekten Nachrichten schicken muss und
dabei keine Annahmen über die Art dieser Objekte treffen möchte
• Man will lose Kopplung erreichen
RT (ICS @ UIBK)
Programmiermethodik
551/613
Entwurfsmuster
Verhaltensmuster
Beobachter: Struktur
Subject
«interface»
Observer
-observers
+register(o : Observer)
+unregister(o : Observer)
+notify()
+update()
... for all o in observers: o.update() ...
ConcreteSubject
ConcreteObserver
-subjectState
+getState()
+setState(...)
-observerState
-subject
+update()
... observerState = subject.getState() ...
RT (ICS @ UIBK)
Programmiermethodik
552/613
Entwurfsmuster
Verhaltensmuster
Beobachter
• Beteiligte Akteure
• Subject
• Kennt seine Beobachter (Observer), die Anzahl der Beobachter ist aber
nicht festgelegt
• Stellt Schnittstelle für Hinzufügen, Entfernen und Benachrichtigen von
Beobachtern zur Verfügung
• Observer
• Definiert Schnittstelle für das Aktualisieren der Beobachter
• ConcreteSubject
• Speichert relevanten Zustand
• Verschickt Benachrichtigungen an Beobachter bei Zustandsänderung
• ConcreteObserver
• Verwaltet Referenz auf ConcreteSubject
• Speichert Zustand, der mit Zustand des Subjekts konsistent sein sollte
• Implementiert entsprechende Schnittstelle für Beobachter
RT (ICS @ UIBK)
Programmiermethodik
553/613
Entwurfsmuster
Verhaltensmuster
• Zusammenspiel
• ConcreteSubject benachrichtigt Beobachter bei jeder
Zustandsänderung, die den gespeicherten Zustand bei den Beobachtern
in inkonsistent Zustand bringen könnte
• ConcreteObserver kann nach Benachrichtigung die Zustandsänderung
abfragen und seinen gespeicherten Zustand aktualisieren
• ConcreteObserver kann Zustandsänderung im ConcreteSubject auslösen
• Wartet aber auf Benachrichtigung und ändert erst dann den lokal
gespeicherter Zustand
RT (ICS @ UIBK)
Programmiermethodik
554/613
Entwurfsmuster
Verhaltensmuster
Beobachter
• Vorteile
• Abstrakte (minimale) Kopplung zwischen beobachteten Objekt und
Beobachtern
• Subjekt und Beobachter können auch ohne jeweils andere Komponente
in neuen Umgebungen verwendet werden
• Beobachter können ohne Änderung des Subjekts hinzugefügt werden
• Subjekt und Beobachter können sich auf unterschiedlichen
Abstraktionsstufen befinden
• Unterstützung von Multicasting
• Mehrere Observer können gleichzeitig benachrichtigt werden
RT (ICS @ UIBK)
Programmiermethodik
555/613
Entwurfsmuster
Verhaltensmuster
Beobachter
• Nachteile
• Hohe Änderungskosten
• Viele Beobachter
• Eine Aktualisierung kann viele weitere Aktualisierungen in anderen
Objekten nach sich ziehen
• Zusätzliches Protokoll bei Zustandsänderung, wenn man genauere
Informationen haben möchte
• Probleme bei Zustandsänderung während einer Aktualisierung
RT (ICS @ UIBK)
Programmiermethodik
556/613
Entwurfsmuster
Verhaltensmuster
Beobachter
• Implementierung
• Effiziente Zuordnung von Subjekten und Beobachtern
• Einfache Variante: Subjekt verwaltet seine Beobachter
• Nicht immer effizient (z.B. viele Subjekte und wenige Beobachter)
• Alternative: globale Map “Subject → Observers”
• Mehrere Subjekte beobachten
• Erweiterung der Schnittstelle (update(Object subj) mit Referenz auf
konkretes Subjekt)
• Wer löst die Aktualisierung aus (wer ruft notify () auf)?
• Subjekt: einfach, aber umständlich (bei jeder Änderung aufrufen)
• Beobachter / Applikation: flexibler (Beobachter kann warten, notify ()
erst nach Serie von Änderungen), aber zusätzliche Verantwortung
• Dangling Reference
• Wenn Subjekt gelöscht wird, dann müssen Beobachter darüber
informiert werden
• Konsistenz im Subjekt selbst sicherstellen
• 2 Varianten (Push , Pull)
RT (ICS @ UIBK)
Programmiermethodik
557/613
Entwurfsmuster
Verhaltensmuster
Beobachter: Push-Variante
RT (ICS @ UIBK)
Programmiermethodik
558/613
Entwurfsmuster
Verhaltensmuster
Beobachter: Pull-Variante
RT (ICS @ UIBK)
Programmiermethodik
559/613
Entwurfsmuster
Verhaltensmuster
Beobachter: Implementierung
• Push-Variante
• Beobachter bekommt Zustandsänderung mit Benachrichtigung
• Information wird zum Beobachter “geschickt”
• Aktualisierung kann bestimmte Parameter bekommen
• Pull-Variante
• Beobachter bekommt nur Benachrichtigung, dass Zustandsänderung
aufgetreten ist
• Beobachter muss Zustandsänderung selbst abfragen (Subjekt
kontaktieren)
• Subjekt muss entsprechende Methoden anbieten
• Datenvolumen
• Push: groß bis sehr groß
• Pull: geringer
RT (ICS @ UIBK)
Programmiermethodik
560/613
Entwurfsmuster
Verhaltensmuster
Beobachter: Implementierung
• Erweiterung der Schnittstelle für bestimmte Änderungen (Ereignisse)
• Wenn bestimmtes Ereignis eintritt, dann werden nur entsprechenden
Beobachter informiert
• Kapselung komplexer Aktualisierungssemantik
• Für komplexe Beziehungen zwischen mehreren Subjekten und
Beobachtern kann man Aktualisierungsklasse dazwischen schalten
(ChangeManager)
• Verwaltet Zuordnung zwischen Subjekten und Beobachtern
• Definiert Aktualisierungsstrategie
• Aktualisiert alle abhängigen Beobachter bei Nachricht eines Subjekt
• Subjekt und Beobachter in einer Klasse implementieren
• Abhängig von Spracheneigenschaften
• Beispiel Smalltalk
• Subjekt- und Beobachterschnittstelle werden im Wurzelobjekt Object
implementiert
RT (ICS @ UIBK)
Programmiermethodik
561/613
Entwurfsmuster
Verhaltensmuster
Beobachter
• Beispielcode (siehe Beispiel ObserverClient.java)
• Querverweise
• Singleton und Mediator (ChangeManager)
RT (ICS @ UIBK)
Programmiermethodik
562/613
Entwurfsmuster
Verhaltensmuster
Beispiel: Unterstützung in Java
public interface Observer {
void update ( Observable o , Object arg ) ;
}
public class Observable {
...
p u b l i c O b s e r v a b l e ( ) {}
public synchronized void addObserver ( Observer o ) { . .
public synchronized void d e l e t e O b s e r v e r ( Observer o )
public void n o t i f y O b s e r v e r s ( ) { . . . }
public void n o t i f y O b s e r v e r s ( Object arg ) { . . . }
public synchronized void d e l e t e O b s e r v e r s ( ) { . . . }
protected synchronized void setChanged ( ) { . . . }
protected synchronized void clearChanged ( ) { . . . }
p u b l i c s y n c h r o n i z e d boolean hasChanged ( ) { . . . }
public synchronized i n t c o u n t O b s e r v e r s ( ) { . . . }
}
RT (ICS @ UIBK)
Programmiermethodik
563/613
Entwurfsmuster
Verhaltensmuster
Probleme (Java-spezifisch)
• Potentielles Subjekt (Observable) erbt schon von anderer Klasse
• Keine Mehrfachvererbung in Java
⇒ Delegation benutzen
• Potentielles Subjekt beinhaltet eigentliches Subjekt
• Aufrufe werden weitergeleitet
• Delegate-Objekt muss Observable entsprechend überschreiben
• setChanged und clearChanged müssen dabei Zugriffsmodifikator public
bekommen, damit Aufrufe entsprechend weitergeleitet werden können
RT (ICS @ UIBK)
Programmiermethodik
564/613
Entwurfsmuster
Verhaltensmuster
Weitere Verhaltensmuster
• Interpreter
• Definiert für gegebene Sprache eine Repräsentation der Grammatik
sowie einen Interpreter, der die Repräsentation nutzt, um Sätze in der
Sprache zu interpretieren
• Schablonenmethode
• Definiert Skelett eines Algorithmus in einer Operation und delegiert
einzelne Schritte an Unterklassen
• Befehl
• Kapselt Befehl als Objekt
• Besucher
• Kapselt eine auf Elementen einer Objektstruktur auszuführende
Operation als Objekt (Analogie zum internen Iterator)
• Memento
• Erfasst und externalisiert internen Zustand eines Objekts ohne seine
Kapselung zu verletzen, so dass Objekt später in diesen Zustand
zurückversetzt werden kann
RT (ICS @ UIBK)
Programmiermethodik
565/613
Entwurfsmuster
Verhaltensmuster
Weitere Verhaltensmuster
• Strategie
• Definiert Familie von Algorithmen, kapselt jeden einzelnen und macht
sie austauschbar
• Vermittler
• Definiert Objekt, welches Zusammenspiel einer Menge von Objekten in
sich kapselt
• Zustand
• Ermöglicht Objekt, sein Verhalten zu ändern, wenn interner Zustand
sich ändert
• Zuständigkeitskette
• Vermeidet Kopplung eines Auslösers einer Anfrage an Empfänger, indem
mehr als ein Objekt die Möglichkeit erhält, die Anfrage zu erledigen
• Verkettet empfangenen Objekte, und leitet die Anfrage an Kette
entlang, bis ein Objekt sie erledigt
RT (ICS @ UIBK)
Programmiermethodik
566/613
Entwurfsmuster
Verhaltensmuster
Zusammenfassung
• Entwurfsmuster
• Entwurfsmuster beschreibt Problem, welches immer wieder auftritt
• Es beschreibt allgemeinen Kern der Lösung
• Muster kann dann zum Lösen eines neuen Problems verwendet werden
• Nutzen von Entwurfsmustern
• Objekte / Klassen identifizieren
• Nicht nur 1:1-Abbildung der realen Welt schaffen
• Für zukünftige Änderungen vorbereiten
• Granularität der Objekte festlegen
• Schnittstellen identifizieren
• Beziehungen zwischen Schnittstellen festlegen und Implementierung
auswählen
• Design-Grundprinzipien berücksichtigen
• Implementierungen austauschbar machen
• Objekterzeugung änderbar gestalten
• Funktionalität änderbar gestalten
RT (ICS @ UIBK)
Programmiermethodik
567/613
GUI-Programmierung in Java
Übersicht
GUI-Programmierung in Java
Überblick
Komponenten und Container
Layout
Ereignisbasierte Programmierung
RT (ICS @ UIBK)
Programmiermethodik
568/613
GUI-Programmierung in Java
Überblick
Übersicht
GUI-Programmierung in Java
Überblick
Komponenten und Container
Layout
Ereignisbasierte Programmierung
RT (ICS @ UIBK)
Programmiermethodik
569/613
GUI-Programmierung in Java
Überblick
GUI
• GUI = Graphical User Interface
• Grafische Benutzeroberfläche
• Steuerung der Anwendung durch Maus- und Tastatur mit Hilfe von
GUI-Komponenten (Fenster, Buttons, Slider, Scrollbar etc.)
• Wichtige Konzepte bei der GUI-Programmierung
• Komponenten
• Hierarchische Anordnung der einzelnen Komponenten
• Layout
• Layout-Manager unterstützen Anordnung der einzelnen Komponenten
am Bildschirm
• Ereignisgesteuerte Programmierung
• Komponenten haben eigene Funktionalität
• Komponenten reagieren auf Ereignisse (Events)
• Abfolge der Benutzereingaben bestimmt Programmablauf
RT (ICS @ UIBK)
Programmiermethodik
570/613
GUI-Programmierung in Java
Überblick
GUI-Programmierung in Java
• Java 1.0: Abstract Windowing Toolkit
• Bestandteil der Java API
• Minimalistisch
• Spezifisch (OS)
• Low-level Programmierung
• Java 1.2: Swing (leichtgewichtige Komponenten)
• Basiert auf AWT
• Bestandteil der Java Foundation Classes (JFC)
• JFC ist Sammlung von Programmierschnittstellen (APIs) zur Erstellung
portabler Java GUIs
• Plattformunabhängig
• Bessere Performance
• Wird in dieser Vorlesung besprochen
• Alle praktischen Beispiele und Abbildungen wurden dem Java Tutorial
entnommen: http://docs.oracle.com/javase/tutorial/uiswing/
RT (ICS @ UIBK)
Programmiermethodik
571/613
GUI-Programmierung in Java
Überblick
Java Swing
• Viele Komponenten
• Leichtgewichtig (direkt von Java gerendert)
• Auf allen Plattformen sehen Komponenten gleich aus
• Look-and-Feel (Erscheinungsbild) konfigurierbar
• Windows, Motif, Metal, Nimbus
• Einige Komponenten zusätzlich zu AWT
• Drag and Drop
• Tooltips
• Automatisches Double Buffering
• Code der Bibliotheksklassen ruft Programmcode des
Anwendungsprogrammierers auf, wenn entsprechendes Grafikelement
bei Programmausführung benutzt wird (z.B. Mausklick)
RT (ICS @ UIBK)
Programmiermethodik
572/613
GUI-Programmierung in Java
Komponenten und Container
Übersicht
GUI-Programmierung in Java
Überblick
Komponenten und Container
Layout
Ereignisbasierte Programmierung
RT (ICS @ UIBK)
Programmiermethodik
573/613
GUI-Programmierung in Java
Komponenten und Container
Grundlagen
• GUI wird aus einzelnen Komponenten aufgebaut
• Container (spezielle Komponenten) können weitere Komponenten
enthalten und anordnen
• Alle Container sind auch wieder Komponenten
⇒ Kompositum
• Container auf oberster Hierarchiestufe basieren auf AWT-Containern
(schwergewichtig)
• Leichtgewichtige Komponenten erben von JComponent
• JComponent ist Basisklasse für die meisten Swing-Komponenten
(Frames, Buttons etc.)
• Stellt Infrastruktur zum Zeichnen der Komponenten zur Verfügung
• API lesen
RT (ICS @ UIBK)
Programmiermethodik
574/613
GUI-Programmierung in Java
Komponenten und Container
Swing-Komponenten
RT (ICS @ UIBK)
Programmiermethodik
575/613
GUI-Programmierung in Java
Komponenten und Container
Swing-Komponenten
RT (ICS @ UIBK)
Programmiermethodik
576/613
GUI-Programmierung in Java
Komponenten und Container
Swing-Komponenten (Container)
RT (ICS @ UIBK)
Programmiermethodik
577/613
GUI-Programmierung in Java
Komponenten und Container
Container und Komponenten
• Top-Level Container in Swing
• Können weitere Komponenten enthalten und anordnen
• Stellen Infrastruktur zum Zeichnen von Komponenten und zur
Ereignisbehandlung bereit
• Es gibt vier solche Container: JFrame, JDialog, JWindow, JApplet
• Container-Komponenten
• Können wie Top-Level Container weitere Komponenten enthalten und
anordnen
• Bestimmen Größe und Position jeder Komponente
• Container in Swing: JScrollPane, JTabbedPane, . . .
• Basiskomponenten
• Benutzer interagiert mit diesen Komponenten
• Beispiele: JComboBox, JTextField, JTable, . . .
RT (ICS @ UIBK)
Programmiermethodik
578/613
GUI-Programmierung in Java
Komponenten und Container
Aufbau
• Verwendete Komponenten lassen sich in Hierarchie anordnen
• Wurzel ist immer ein Top-level Container
• Top-level Container wird mit Fenster verbunden
• In diesem Fenster werden seine (sichtbaren) Komponenten dargestellt
• Swing-Hauptfenster enthält eine Hauptkomponente (RootPane), die
alle anderen Komponenten aufnimmt
• RootPane enthält folgende Komponenten
• Eine GlassPane
• Eine LayeredPane
• LayeredPane enthält ihrerseits zwei Unterkomponenten
• Eine ContentPane
• Eine Menüleiste
RT (ICS @ UIBK)
Programmiermethodik
579/613
GUI-Programmierung in Java
Komponenten und Container
Aufbau
• LayeredPane und GlassPane liegen „übereinander“ und füllen Fenster
jeweils komplett aus
• GlassPane ist normalerweise durchsichtig und wird meist nicht zur
Grafikausgabe benutzt
• Kann verwendet werden, um Effekte zu erzielen, die das Fenster als
Ganzes betreffen
• LayeredPane enthält Menü und Dialogelemente der Anwendung
• Einfügen und Anordnen von Dialogelementen auf einem Hauptfenster
erfolgt über dessen ContentPane
RT (ICS @ UIBK)
Programmiermethodik
580/613
GUI-Programmierung in Java
Komponenten und Container
Komponenten zu Containern hinzufügen
• Mit add-Methode werden Komponenten zu einem Container
hinzugefügt (und damit zu Kindern des Containers in der
Komponentenhierarchie)
• Ein Argument der add-Methode spezifiziert die hinzuzufügende
Komponente
• Achtung: Eine Komponente kann immer nur zu einem Container
gehören
• Wird Komponente zu einem zweiten Container hinzugefügt, dann wird
diese Komponente aus dem ersten Container entfernt
RT (ICS @ UIBK)
Programmiermethodik
581/613
GUI-Programmierung in Java
Komponenten und Container
JFrame
• Java GUI-Applikationen benutzen oft JFrame, um ein Hauptfenster zu
öffnen
• JFrame = einfaches, größenänderbares Fenster mit Rand, Titelleiste
und optionaler Menüleiste
• JFrame bildet Bindeglied zwischen Swing und Betriebssystem
• JFrame registriert sich als Fenster im Betriebssystem und kann wie
herkömmliches Fenster benutzt werden
• Unterstützt Methoden zum
• Lesen/Setzen des Titels,
• Lesen/Setzen des Zustands,
• Sichtbarkeit eines Frames,
• Lesen/Setzen der Position,
• Lesen/Setzen der Größe
• Hinzufügen einer Komponente etc.
RT (ICS @ UIBK)
Programmiermethodik
582/613
GUI-Programmierung in Java
Komponenten und Container
JLabel, JButton, JTextField
• JLabel
• Einfache Komponente zum Beschreiben anderer Komponenten
• Unterstützt Methoden für
•
•
•
•
Lesen/Setzen des Labels
Lesen/Setzen der Position (horizontal/vertikal)
Anbinden an eine Komponente (setLabelFor)
...
• JButton
• Die einfachste Komponente für die Interaktion (Anklicken)
• Bei einer Interaktion wird entsprechender Code ausgeführt
• Muss vom Programmierer bereitgestellt werden (Events)
• Methoden für das Verändern sind sehr ähnlich zu denen von JLabel
• JTextField
• Einfachste Textkomponente in Swing (Texteingabe)
• Lesen/Setzen des Textes in der Komponente
RT (ICS @ UIBK)
Programmiermethodik
583/613
GUI-Programmierung in Java
Komponenten und Container
Ein einfaches Swing-Programm (Nicht Thread-safe)
import j a v a x . s w i n g . ∗ ;
public class HelloWorldSwing {
p r i v a t e s t a t i c v o i d createAndShowGUI ( ) {
// C r e a t e and s e t up t h e window .
JFrame f r a m e = new JFrame ( " HelloWorldSwing " ) ;
f r a m e . s e t D e f a u l t C l o s e O p e r a t i o n ( JFrame . EXIT_ON_CLOSE ) ;
// Add t h e u b i q u i t o u s " H e l l o World " l a b e l .
J L a b e l l a b e l = new J L a b e l ( " Hello World " ) ;
l a b e l . s e t V e r t i c a l A l i g n m e n t ( S w i n g C o n s t a n t s . CENTER ) ;
f r a m e . g e t C o n t e n t P a n e ( ) . add ( l a b e l ) ;
// D i s p l a y t h e window .
f r a m e . pack ( ) ;
frame . s e t V i s i b l e ( true ) ;
}
p u b l i c s t a t i c v o i d main ( f i n a l S t r i n g [ ] a r g s ) {
createAndShowGUI ( ) ;
// . . . w e i t e r e r Code
RT (ICS @ UIBK)
Programmiermethodik
584/613
GUI-Programmierung in Java
Komponenten und Container
Beispiel: TopLevelDemo
• Programm findet man unter http://docs.oracle.com/javase/
tutorial/uiswing/components/toplevel.html
• Aufbau
• Hierarchie (Containment hierarchy) der Komponenten
RT (ICS @ UIBK)
Programmiermethodik
585/613
GUI-Programmierung in Java
Layout
Übersicht
GUI-Programmierung in Java
Überblick
Komponenten und Container
Layout
Ereignisbasierte Programmierung
RT (ICS @ UIBK)
Programmiermethodik
586/613
GUI-Programmierung in Java
Layout
Layout-Manager
• Zu jedem Container gibt es Layout-Manager
• Durch diesen werden Komponenten im Container angeordnet
• Dieser bestimmt Größe und Position jeder Komponente
• Mit setLayout-Methode kann Layout-Manager bestimmt werden
• Dieser übernimmt das Platzieren aller Komponenten, die mit
nachfolgenden add-Aufrufen hinzugefügt werden
• Argumente der add-Methode hängen vom Layout-Manager ab
• Alle JPanel-Objekte benutzen standardmäßig den FlowLayout Manager
• Alle ContentPanes (die Container in JApplet, JDialog, JFrame)
benutzen standardmässig den BorderLayout-Manager
• Layout-Manager kann auf null gesetzt werden
• Dann kann man Komponenten explizit platzieren
RT (ICS @ UIBK)
Programmiermethodik
587/613
GUI-Programmierung in Java
Layout
Verfügbare Layout-Manager
RT (ICS @ UIBK)
Programmiermethodik
588/613
GUI-Programmierung in Java
Layout
Beispiel: BorderLayout
• BorderLayout-Objekt hat 5 Teile (Konstanten)
• PAGE_START, PAGE_END, LINE_START, LINE_END, CENTER
• CENTER bekommt am meisten Platz, der Rest passt sich an
• Beispiel
• http://docs.oracle.com/javase/tutorial/uiswing/layout/
border.html
• Komponenten werden zu einem Frame hinzugefügt
• ContentPane benutzt automatisch BorderLayout
RT (ICS @ UIBK)
Programmiermethodik
589/613
GUI-Programmierung in Java
Layout
Beispiel: GridLayout
• Beim GridLayout werden Komponenten in einem Gitter von Zellen
angeordnet
• Jede Komponenten verbraucht gesamten Platz in einer Zelle
• Wird Fenstergröße verändert, dann wird jede Zellengröße entsprechend
angepasst
• Beispiel
• http://docs.oracle.com/javase/tutorial/uiswing/layout/
grid.html
RT (ICS @ UIBK)
Programmiermethodik
590/613
GUI-Programmierung in Java
Ereignisbasierte Programmierung
Übersicht
GUI-Programmierung in Java
Überblick
Komponenten und Container
Layout
Ereignisbasierte Programmierung
RT (ICS @ UIBK)
Programmiermethodik
591/613
GUI-Programmierung in Java
Ereignisbasierte Programmierung
Ereignisbasierte Programmierung
• Kontrollfluss eines Systems wird durch Ereignisse und nicht durch
Kontrollstrukturen oder Funktionsaufrufe bestimmt
• Beispiele für Ereignisse
• Mausklick
• Eingabe per Tastatur
• ...
• Typische Anwendung
• Interaktive Systeme
• Interaktion zwischen Benutzer und grafischer Benutzerschnittstelle
• Programmierung von Sensoren
• Messwerte bestimmen weiteren Ablauf
RT (ICS @ UIBK)
Programmiermethodik
592/613
GUI-Programmierung in Java
Ereignisbasierte Programmierung
Generelle Idee
• Zuhörer (Listener) registrieren sich für bestimmte Ereignisse
• Quelle schickt Benachrichtigung, wenn ein Ereignis eintritt
register
Listener
Listener
Listener
Listener
Listener
Event Source
notify
RT (ICS @ UIBK)
Programmiermethodik
593/613
GUI-Programmierung in Java
Ereignisbasierte Programmierung
Entwurfsmuster?
• Teilnehmer
• Event-Source (Quelle)
• Event-Listener (registriert sich bei der Quelle)
• Event-Objekt (wird zum Listener geschickt)
• Rollen
• Source = Subjekt
• Listener = Beobachter
• Push-Variante besser
• Listener kann sich bei mehreren Quellen registrieren
• Alle Quellen benutzen gleiche Methode (Callback-Methode) für
Benachrichtigungen
• Beobachter sollten sofort reagieren
RT (ICS @ UIBK)
Programmiermethodik
594/613
GUI-Programmierung in Java
Ereignisbasierte Programmierung
Event-Objekte
• Ereignis wird durch Objekt repräsentiert
• Es gibt unterschiedliche Ereignistypen, von denen Objekte angelegt
werden können
• Ereignistypen erben von AWTEvent
• Ereignisse werden meist von Komponenten erzeugt
• Ereignisobjekt beinhaltet Informationen über
• das Ereignis sowie
• die Quelle des Ereignisses
• Typische Verarbeitung
• Endlosschleife (Event-Schleife), in der Ereignisse generiert werden
• Interne Verwaltung eines Puffers für einzelne Ereignisse
(Event-Warteschlange)
• Kontrollfluss der Event-Schleife sollte unabhängig vom Kontrollfluss der
Empfänger sein
RT (ICS @ UIBK)
Programmiermethodik
595/613
GUI-Programmierung in Java
Ereignisbasierte Programmierung
Listener
• Möchte Objekt von einer Komponente über bestimmtes Ereignis
benachrichtigt werden, dann muss
• Komponente ein passendes Interface implementieren und
• Object sich als Listener bei der Komponente (Source) registrieren
• Implementieren eines passenden Interfaces bedeutet, Methode zur
Verfügung zu stellen, die Ereignis behandeln kann
• Implementierung wird als Event Handler bezeichnet
• Oft als innere (anonyme) Klasse implementiert
• In Swing gibt es große Anzahl an Listener-Interfaces
• Manche Interfaces haben noch zusätzliche Adapter-Klassen, die für
größere Interfaces “Implementierungen” bereitstellen (man muss nur
davon ableiten und benötigte Funktionalität implementieren)
• Liste der Listener-APIs: http:
//docs.oracle.com/javase/tutorial/uiswing/events/api.html
RT (ICS @ UIBK)
Programmiermethodik
596/613
GUI-Programmierung in Java
Ereignisbasierte Programmierung
Listener-Interfaces (mit Beispielen)
• ActionListener
• Benutzer klickt z.B. Button an, drückt Enter-Taste in Textfeld oder
wählt Menüeintrag aus
• WindowListener
• Benutzer öffnet / schließt Fenster
• MouseListener
• Benutzer klickt Maustaste während Mauszeiger über einer Komponente
ist
• MouseMotionListener
• Benutzer bewegt Maustaste über einer Komponente
• ComponentListener
• Komponente wird sichtbar
• FocusListener
• Komponente bekommt Focus
RT (ICS @ UIBK)
Programmiermethodik
597/613
GUI-Programmierung in Java
Ereignisbasierte Programmierung
Beispiel – Mausklick auf Button
• Mausklick führt dazu, dass Button Ereignis vom Typ ActionEvent
erzeugt
• Dieses Ereignis(-Objekt) hat alle Informationen über das Ereignis und
seine Quelle, sowie Beschreibung der ausgeführten Aktion
• Dieses Ereignis wird an alle bei dem Button registrierten
ActionListener -Objekte geschickt
• Jeder Listener implementiert Methode zur Ereignisbehandlung
• In diesem Fall wird mit Methode actionPerformed festgelegt, was beim
Eintreten des Ereignisses passieren soll
• Damit ruft somit Button bei einer Aktion (Mausklick) diesen Code auf
RT (ICS @ UIBK)
Programmiermethodik
598/613
GUI-Programmierung in Java
Ereignisbasierte Programmierung
Registrieren
• Ein Listener muss explizit mit dem Ereignisauslöser verbunden werden
• Dafür gibt es unterschiedliche Methoden der Form
addEventListener( EventListener )
• Nicht jede Komponente kann jedes Ereignis auslösen
• Daher gibt es entsprechende add-Methoden nur für Ereignisse, die die
Komponenten tatsächlich auslösen
• JFrame-Klasse bietet zum Beispiel addWindowListener() für
Fensterereignisse, aber kein addActionListener ()
• Ein JButton hingegen bietet addActionListener () an, damit er die
Aktivierung der Schaltfläche melden kann
• So lassen sich über die angebotenen add-Methoden gut die Ereignisse
ablesen, die eine Komponente auslösen kann
RT (ICS @ UIBK)
Programmiermethodik
599/613
GUI-Programmierung in Java
Ereignisbasierte Programmierung
Beispiel für mehrere Listener
• Beispiele für mehrere Listener-Implementierungen ( ActionListener )
• http://docs.oracle.com/javase/tutorial/uiswing/events/
actionlistener.html
• ActionListener : Einfachste und am meisten benutzte Variante
RT (ICS @ UIBK)
Programmiermethodik
600/613
GUI-Programmierung in Java
Ereignisbasierte Programmierung
Aktionen
• Action-Objekt ist ein ActionListener
• Damit werden Zustand und Funktionalität einer Komponente getrennt
• Action-Objekt wird mit Methode setAction zu Komponente hinzugefügt
• Zustand der Komponente wird dem Zustand des Action-Objektes
angeglichen
• Action-Objekt wird als ActionListener bei Komponente registriert
• Wenn sich der Zustand des Action-Objektes ändert, wird der Zustand
der Komponente ebenfalls geändert
• Um ein Action-Objekt zu erzeugen, leitet man Klasse von der Klasse
AbstractAction ab
• Unterklasse muss Methode actionPerformed implementieren, da
Action-Objekt auch als ActionListener fungiert
• Beispiel
• http://docs.oracle.com/javase/tutorial/uiswing/misc/
action.html
RT (ICS @ UIBK)
Programmiermethodik
601/613
GUI-Programmierung in Java
Ereignisbasierte Programmierung
Event Dispatching Thread (EDT)
• Ereignisbehandlung erfolgt immer im Event Dispatching Thread
• Ein Event-Handler nach dem anderen (Event-Warteschlange)
• Auch die Zeichenroutinen der Komponenten laufen im Event
Dispatching Thread ab
• Während Event-Handler abgearbeitet wird, ist GUI “eingefroren”
(reagiert nicht)
RT (ICS @ UIBK)
Programmiermethodik
602/613
GUI-Programmierung in Java
Ereignisbasierte Programmierung
Regeln zum Umgang mit EDT
• Ändere Zustand einer Komponente nicht während Zeichenroutine
• Grund: Änderung führt zum repaint ()-Event, welches wiederum zur
Änderung führt, . . .
⇒ Event-Warteschlange wird immer weitere repaint ()-Events erhalten und
zu 100 % CPU-Last führen
• Führe keinen langfristigen Berechnungen mit EDT durch
• Grund: Event Abarbeitung friert GUI ein, sollte nicht zu lange dauern
• Lösung: Führe Berechnungen asynchron in extra Thread aus
(siehe auch http://docs.oracle.com/javase/tutorial/uiswing/
concurrency/worker.html)
• Ändere niemals den GUI-Zustand außerhalb des EDTs
• Grund: EDT ändert GUI-Zustand und Swing ist nicht Thread-safe
• Lösung: Führe Änderung mittels
javax .swing. SwingUtilities . invokeLater (...) aus
• Nicht-Befolgung dieser Regeln kann folgende Konsequenzen haben
• Visuelle Artefakte
• Unnötige CPU Belastung
• “Langsame” bis hin zu vollständig eingefrorener GUI
RT (ICS @ UIBK)
Programmiermethodik
603/613
GUI-Programmierung in Java
Ereignisbasierte Programmierung
Model-View-Controller (MVC)
• Anstatt den gesamten Code in einzelne Klasse zu packen, werden beim
MVC-Konzept drei unterschiedliche Bestandteile eines grafischen
Elements unterschieden
• Modell enthält Daten des Dialogelements und speichert seinen Zustand
• View ist für grafische Darstellung der Komponente verantwortlich
• Controller wirkt als Verbindungsglied zwischen beiden. Er empfängt
Tastatur- und Mausereignisse und stößt erforderliche Maßnahmen zur
Änderung von Model und View an
• Vorteil von MVC
• Austauschbarkeit der einzelnen Komponenten, hohe Kohäsion
• Bei Swing-Dialogelementen wird vereinfachte Variante von MVC
verwendet (Model-Delegate-Prinzip)
• Dabei wird die Funktionalität von View und Controller in einem UI
Delegate zusammengefasst
• Dadurch wird die Komplexität reduziert und die in der Praxis oft
unhandliche Trennung zwischen View und Controller aufgehoben
RT (ICS @ UIBK)
Programmiermethodik
604/613
Ausblick
Übersicht
Ausblick
Reflexion
Java 8
RT (ICS @ UIBK)
Programmiermethodik
605/613
Ausblick
Reflexion
Übersicht
Ausblick
Reflexion
Java 8
RT (ICS @ UIBK)
Programmiermethodik
606/613
Ausblick
Reflexion
Wo stehen wir aktuell?
• Was wurde bisher besprochen?
• Objektorientierung allgemein
• Grundlegende Programmierung in Java
• Objektorientierung in Java
• Einige Details von Java
• Entwurfsmuster
• GUI-Programmierung
• Wie geht es weiter?
• Einsatz, Vertiefung und Erweiterung der besprochenen Konzepte in
weiteren Lehrveranstaltungen
• Entwurf von Softwaresystemen
• Softwareentwicklung und Projektmanagement
• Abgrenzung der Konzepte, alternative Programmier-Paradigmen
• Funktionale Programmierung
• Logische Programmierung
• Abgrenzung der Konzepte, formale Spezifikation und Beweise anstelle
von textueller Schnittstellen-Dokumentation und Unit-Tests
• Logik
• Interaktives Beweisen
RT (ICS @ UIBK)
Programmiermethodik
607/613
Ausblick
Reflexion
Und für die Praxis?
• Java ist eine weitverbreitete Programmiersprache
• Kommerzielle Software
• Open-Source-Projekte
• Typische Einsatzgebiete
• Web-Programmierung
• Größere plattformunabhängige Projekte
• Web-Service-Programmierung
• ...
• Unterschiedliche Technologien
• Java SE (Standard Edition)
• In dieser Vorlesung behandelt
• Java EE (Enterprise Edition)
• Industriestandard für die Implementierung von unternehmensspezifischen
Service-Oriented-Architecture-Applikationen und Web-Applikationen
• Java ME (Micro Edition)
• Mobile und eingebettete Systeme (Handy, PDA, Set-top-Boxen,
Drucker etc.)
RT (ICS @ UIBK)
Programmiermethodik
608/613
Ausblick
Reflexion
Verbreitung
• Verbreitung von Sprachen lässt sich nur schwer messen
• Verschiedene Ansätze
• Nicht wissenschaftlich
• Nur grobe Abschätzung/Richtung
• Beispiele
• Language Popularity Web-Seite
• Benutzung bekannter Suchmaschinen
• http://www.langpop.com/
• TIOBE Programming Community Index
• Wird jeden Monat aktualisiert
• Berechnung: “The ratings are based on the number of skilled engineers
world-wide, courses and third party vendors. The popular search engines
Google, MSN, Yahoo!, Wikipedia and YouTube are used to calculate
the ratings.”
RT (ICS @ UIBK)
Programmiermethodik
609/613
Ausblick
Reflexion
TIOBE (Trend Juni 2013, Top 10)
RT (ICS @ UIBK)
Programmiermethodik
610/613
Ausblick
Java 8
Übersicht
Ausblick
Reflexion
Java 8
RT (ICS @ UIBK)
Programmiermethodik
611/613
Ausblick
Java 8
Ausblick auf Java 8
• Lambda Expressions (Closures, Project Lambda)
• Sprachmittel, das aus der funktionalen Programmierung stammt
• Funktionen können als Parameter / Rückgabewert von Methoden
verwendet werden
• Beispiele:
(int x, int y) -> x + y
() -> 42
(String s) -> { System.out.println(s); }
• Beispiel
• Heute
b u t t o n . a d d A c t i o n L i s t e n e r ( new A c t i o n L i s t e n e r ( ) {
public void actionPerformed ( ActionEvent e ) {
ui . dazzle (e . getModifiers ());
}
});
• Java 8 (geplant)
b u t t o n . a d d A c t i o n L i s t e n e r ( e −> u i . d a z z l e (
e . getModifiers ()));
RT (ICS @ UIBK)
Programmiermethodik
612/613
Ausblick
Java 8
Ausblick auf Java 8
• Verwendung von Lambdas im Collection-Framework
• Zusätzlich bessere Unterstützung der Nebenläufigkeit bei Collections
• Parallele Arrays etc.
• Typ-Annotationen
• Annotationen können überall verwendet werden, wo Typen erlaubt sind
• Damit wird es möglich, das Typsystem von Java zu erweitern
(Typen mit Annotations beschreiben)
• Statische Analysewerkzeuge können davon profitieren
• Beispiel
Map<@NonNull S t r i n g ,
@NonEmpty L i s t <@ReadOnly Document>> f i l e s ;
@NonNull O b j e c t @ N u l l a b l e [ ] a r r a y ;
RT (ICS @ UIBK)
Programmiermethodik
613/613
Herunterladen