AOP - Bildungsportal Sachsen

Werbung
Anwendungsorientierte Programmierung I
Heinrich Krämer
Hochschule für Technik, Wirtschaft und Kultur Leipzig (FH)
Fachbereich Informatik, Mathematik und Naturwissenschaften
Folie 2
1 Einleitung
Literatur
http://docs.oracle.com/javase/specs/
The Java™ Language Specification
Hier findet sich die jeweils aktuelle Dokumentation
Christian Ullenboom
Java ist auch eine Insel
Galileo Computing
Anwendungsorientierte Programmierung
Folie 3
1. Einleitung
Schritte bei der Programmierung
– Entwicklung eines Algorithmus
Ein Algorithmus ist eine aus endlich vielen Schritten bestehenden eindeutige
Handlungsvorschrift zur Lösung eines Problems oder einer Klasse von
Problemen
Diese Entwicklung erfolgt mehr oder weniger unabhängig von der
Programmiersprache
– Codierung des Algorithmus
Hier wird der vorher entwickelte Algorithmus in einer bestimmten
Programmiersprache (hier Java) notiert.
Anwendungsorientierte Programmierung
Folie 4
1 Einleitung
Entwicklung eines Algorithmus
 Aufstellen einer Spezifikation
• Eingabe mit genauer Angabe der zulässigen
Wertebereiche
• Ausgabe
• funktionaler Zusammenhang
 Bewährt hat sich bei der Entwicklung die Top-DownMethode
• Zerlegung in Teilprobleme bzw. Teilmodule (mit eigener
Spezifikation)
Wichtig! Es wird nur angegeben was ein Teilmodul leistet
und nicht wie.
• Prüfung ob das Zusammenspiel der Teilmodule das
Problem löst.
• Anwenden der Methode auf die Teilprobleme bis sich
diese elementar lösen lassen.
• Nachteil: Es kann vorkommen, dass eine
Designentscheidung in unteren Schichten nicht lösbar ist.
Anwendungsorientierte Programmierung
Thomas Watson Sr.
Folie 5
1 Einleitung
Beispiel: Sieb des Eratosthenes
Eingabe: Ganzzahliger Bereich der natürliche Zahlen [1..n]
Ausgabe: alle Primzahlen in diesem Bereich
funktionaler Zusammenhang: eine Primzahl ist nur durch 1 und sich selbst teilbar und
ungleich 1
Algorithmus
Datenstruktur: Tabelle mit allen Zahlen 2..n
Idee: Streichen aller Zahlen die Vielfache einer Primzahl sind.
Beobachtung: Es muss nur der Bereich 2.. n auf Vielfache untersucht werden
1. Teilproblem: Streichen der Vielfachen aller Primzahlen im Bereich 2.. n
2. Teilproblem: Ausgabe aller nicht gestrichenen Zahlen
Anwendungsorientierte Programmierung
Folie 6
1. Einleitung
1. Teilproblem:
für die Zahlen in der Tabelle von 2 bis Wurzel(n)
falls Zahl nicht gestrichen (Zahl ist Primzahl)
gebe die Zahl aus
Streiche alle Vielfache (Teilproblem)
2. Teilproblem:
Für die Zahlen von Wurzel(n) +1 bis n
falls Zahl nicht gestrichen
gebe Zahl als Primzahl aus
1.1. Streichen aller Vielfachen
pz ist Primzahl
Für die Zahlen k := pz2 bis k > n
Streiche k
k := k + pz
Anwendungsorientierte Programmierung
Folie 7
1 Einleitung
Programmierparadigmen
Prozedurale (oder imperative) Programmierung
Der Algorithmus wird als Abfolge von Anweisungen aufgefasst, welche jeweils
Zustandsübergänge auf den Daten bewirken.
Die Befehlsausführung wird durch Kontrollstrukturen gesteuert.
Bestimmte Teilfunktionen werden zu Unterprogrammen zusammengefasst.
Typische Programmiersprachen: Fortran, C, Pascal
Objektorientierte Programmierung
Hier werden die Daten in Klassen gekapselt. Auf den Daten werden bestimmte
zu den Klassen gehörende Funktionen (Methoden) ausgeführt.
Durch Polymorphie können verschiedene Kontrollstrukturen ersetzt werden.
Typische Programmiersprachen: C++, Java, Delphi
Anwendungsorientierte Programmierung
Folie 8
2 Programmierspachen
Programmiersprachen sind formale Sprachen mit fest vorgegebenen Syntax und
dazugehörender Semantik.
In der Syntax ist genau festgelegt wie Programme und bestimmte Konstrukte
aufzuschreiben sind. Die Syntax wird in einer (kontextfreien) Grammatik festgelegt.
Die Semantik legt die Bedeutung eines bestimmten Konstrukts fest.
Die Syntax und Semantik für Java ist in
The Java™ Language Specification
festgelegt.
Weiter gibt es meist Konventionen, die allgemein akzeptiert sind. Im Sinne eines
guten Programmierstiel sollten diese Konventionen eingehalten werden.
Anwendungsorientierte Programmierung
Folie 9
2.1 Die Grammatik
Die Grammatik einer Programmiersprache wird durch Produktionen angegeben.
Eine Produktion besteht aus einem linken und einem rechten Teil, die durch einen
Doppelpunkt getrennt sind.
Auf der linken Seite steht ein Nichtterminal. Nichtterminale werden hier kursiv
geschrieben. Auf der rechten Seite können Terminale oder Nichtterminale stehen.
Terminale werden in Courier gesetzt. Ein Konstrukt ist syntaktisch korrekt, wenn
alle Nichtterminale durch Terminale ersetzt sind. Beispiel:
LocalVariableDeclarationStatement:
Type VariableDeclarators ;
Type:
int
VariableDeclarators:
Identifier
int zahl;
Anwendungsorientierte Programmierung
Folie 10
2.1 Die Grammatik
Metazeichen
x | y Auswahl: es kann entweder x oder y verwendet werden
[ x ] das x ist optional.
{ x } das x kann beliebig oft oder keinmal auftreten
Bezeichner (eng. Identifier)
Für Variablen, und alle anderen später eingeführten Konstrukte wie Funktionen,
selbst deklarierte Datentypen, Methoden, Klassen und Schnittstellen müssen
eindeutige Namen, so genannte Bezeichner, vergeben werden.
Ein Bezeichner muss immer mit einem Java-Buchstaben beginnen. Danach können
beliebig Buchstaben und Ziffern folgen. Hierbei wäre es zulässig, beliebige
Buchstaben aus dem Unicode-Alphabet zu verwenden. Nach üblicher Konvention
sollten jedoch nur Buchstaben aus den Bereichen A..Z, a..z und die Ziffern 0..9
verwendet werden.
Anwendungsorientierte Programmierung
Folie 11
2.1 Grammatik
Beispiele für Bezeichner
eineVariable
gültiger Bezeichner
Noch_ne_Variable gültiger Bezeichner, verletzt aber Konvention
__Win
gültiger Bezeichner, kann allerdings zu Problemen führen
$$system
gültiger Bezeichner, kann allerdings zu Problemen führen
Ungültige Bezeichner
1Fehler
beginnt mit Ziffer
Hoppla!
keine Sonderzeichen
auch falsch
keine Leerzeichen
Ein Bezeichner darf keines der nachfolgenden Schlüsselworte sein
abstract assert boolean break byte case catch char class const
continue default do double else extends false final finally
float for goto if implements import instanceof int interface
long native new null package private protected public return
short static strictfp super switch synchronized this throw
throws transient true try void volatile while
Anwendungsorientierte Programmierung
Folie 12
2.1 Grammatik
Bisher wollen wir folgenden Rahmen verwenden
JavaProgramm :
package Bezeichner;
{ImportDeklaration;}
public class Bezeichner {
public static void main() {
{BlockAnweisung}
}
}
Konvention: Bezeichner für Pakete (package) beginnen mit einem
Kleinbuchstaben, Bezeichner für Klassen (class) beginnen mit einem
Großbuchstaben
Anwendungsorientierte Programmierung
Folie 13
2.2 Primitive Datentypen
Typ
Wertebereich
Größe
Format
Ganzzahlen (Numerisch)
byte
-128..+127
8 Bit
Zweierkomplement
short
-32.768..+32.767
16 Bit
Zweierkomplement
int
-2.147.483.648..+ 2.147.483.647
32 Bit
Zweierkomplement
long
-263..+263-1
64 Bit
Zweierkomplement
32 Bit
IEEE 754
64 Bit
IEEE 754
Gleitkommazahlen (Numerisch)
float
1,40239846E-45..3,40282347E+38
double
Weitere Datentypen
boolean
true oder false
nicht def.
char
Unicode (Numerisch)
16 Bit
Anwendungsorientierte Programmierung
16-Bit-Unicode
Folie 14
2.2 Primitive Datentypen
Literale dienen der Darstellung von konstanten Werten im Programm.
Numerische Literale
int–Literale
1234 (Dezimal) 0B10 oder 0b10 (Dual 210) 01234 (Oktal 66810 )
0xFFFF_FFFF (Hexadezimal -110)
long-Literale (es muss immer ein l angehängt werden)
1234L (Dezimal) 0b11L (Dual 310) 01234L (Oktal 66810 )
0xFFFF_FFFFL (Hexadezimal 429496729510)
float-Literale (es muss immer ein f angehängt werden)
1.0f 2F
1e-1f
4.0E+5f 3.1416E1f
double-Literale
1.0
2D
1e-1d
4.0E+5
3.1416E1
Anwendungsorientierte Programmierung
Folie 15
2.2 Primitive Datentypen
char-Literale
'a'
'\0041' (A) '\\' (\) '\'' ( ' ) '\"' ( " ) '\u4EBA' (人)*
Einige Escape-Sequenzen
'\b' Rückschritt (backspace)
'\n' Zeilenumbruch (newline)
'\f' Seitenumbruch (formfeed)
'\r' Wagenrücklauf (return)
*
Eventuell muss in Eclipse ProjectProperties die Codierung auf UTF-8 umgestellt werden
Anwendungsorientierte Programmierung
Folie 16
Wrapper-Datentypen
In manchen Fällen wird statt eines primitiven Datentypen eine Klasse (später) erwartet. Für
diese Fälle gibt es zu die sog. Wrapper-Datentypen.
Für diese Wrapper-Daten sind auch verschiedene Konvertierungen vorgesehen.
Wrapper-Datentyp
primitiver Datentyp
Byte
byte
Short
short
Integer
int
Long
long
Float
float
Double
double
Boolean
boolean
Character
char
Anwendungsorientierte Programmierung
Beispiel
double x = Double.valueOf("3.1415");
Folie 17
Der Datentyp String
String ist eigentlich kein primitiver Datentyp sondern ein Klasse. Diese dient zur
Behandlung von Zeichenketten.
An dieser Stelle sollen nur einige Besonderheiten behandelt werden
Zeichenketten werden in Doppelhochkomma ( " ) eingeschlossen. Bsp.:
"Ich bin eine Zeichenkette" Beachte: "C" 'C'
Soll in der Zeichenkette ein " vorkommen, so muss hier eine Escape-Sequenz
verwendet werden. Auch andere Escape-Sequenzen können nützlich sein.
"Ich sagte:\n\t\"Kann ich was spenden?\"" ergibt die Ausschrift:
Ich sagte:
"Kann ich was spenden?"
Strings können über + verkettet werden. Bsp.
"\"Ich meinte" + "…\"" + '\n' + "\"Ich auch.\""
Ein Vergleich kann nur über die Methode equals(s) erfolgen. Bsp.:
String abc = "Hallo";
abc.equals("Hallo")
// liefert true
abc == "Hallo"
// liefert false
Anwendungsorientierte Programmierung
Folie 18
2.3 Operatoren
Arithmetische Operatoren
Unitäre Operatoren
Typ
Beschreibung
Rang
+
Numerisch
Vorzeichen
1
-
Numerisch
Vorzeichen
1
++
Numerisch
Inkrement (+1)
1
--
Numerisch
Dekrement (-1)
1
Binäre Operatoren
Anwendungsorientierte Programmierung
Typ
Beschreibung
Rang
+
Numerisch
Addition
3
-
Numerisch
Subtraktion
3
*
Numerisch
Multiplikation
2
/
Numerisch
Division
2
%
Numerisch
Modulo (Rest)
2
Folie 19
2.3 Operatoren
Vergleichsoperatoren
Typ
Beschreibung
Rang
<
Numerisch, char kleiner
5
>
Numerisch, char größer
5
<=
Numerisch, char kleiner oder gleich
5
>=
Numerisch, char größer oder gleich
5
==
Numerisch, char ungleich
6
!=
Numerisch, char gleich
6
logische Operatoren (Datentyp boolean)
!
boolean
Negation
1
&&
boolean
UND (Kurzauswertung)
10
||
boolean
ODER (Kurzauswertung)
11
^
boolean
Antivalenz
8
&
boolean
UND
7
|
boolean
ODER
9
Anwendungsorientierte Programmierung
Folie 20
2.3 Operatoren
Bitweise Operatoren
Typ
Beschreibung
Rang
~
Numerisch
bitweises Komplement
1
&
Numerisch
bitweises UND
7
|
Numerisch
bitweises ODER
9
^
Numerisch
bitweise Antivalenz
8
<<
Numerisch
Schieben links
4
>>
Numerisch
log. Schieben rechts
4
>>>
Numerisch
arith. Schieben rechts
4
1
weitere Operatoren
(typ)
alle
Typumwandlung
new
alle
später
instanceof
alle
später
5
Auswahl
12
exp ? exp : exp
Anwendungsorientierte Programmierung
Folie 21
2.3 Operatoren
Zuweisungsoperator (für Typ gilt immer lhs == rhs)
Beschreibung
Rang
=
Zuweisung
13
+=
Diese Art der Zuweisung ist eine
Kurzform für die Zuweisung
lhs = lhs op operand
14
-=
*=
/=
%=
<<=
Beispiel
x = x * 10.0
ist identisch zu
x *= 10.0
>>=
>>>=
&=
|=
^=
Anwendungsorientierte Programmierung
Folie 22
2.4 Ausdrücke
Die Definition der Ausdrücke soll hier informell erfolgen.
Durch die Operatoren können Ausdrücke gebildet werden.
Operatoren mit kleinerem Rang werden vor Operatoren mit höherem Rang
ausgewertet.
Haben Operatoren gleichen Rang so werden diese von links nach rechts
ausgewertet. Einen Ausnahme bildet die Zuweisung, die von rechts nach links
ausgewertet wird.
double x = 1.0 / 2.0 + 3.0 * 4.0 berechnet sich zu
double x = ((1.0 / 2.0) + (3.0 * 4.0))
Bei den logischen Operatoren && und || erfolgt eine Kurzauswertung.
Kann das Ergebnis bereits durch Auswertung des linken Operanden bestimmt
werden, so wird der rechte nicht mehr bewertet.
Post- und Preinkrement bzw. –dekrement
--a
Predekrement
b++
Postinkrement
Anwendungsorientierte Programmierung
Folie 23
2.4 Ausdrücke
Ausdrücke müssen immer einen festen Typ ergeben. Daher müssen sich die einzelnen
Operanden implizit in den Zieltyp umwandeln lassen oder es muss eine explizite
Typumwandlung (Type cast) erfolgen.
Implizite Typkonversion

byte
short
int
X
short
int
long
float
Anwendungsorientierte Programmierung
long
float
double
X
X
X
X
X
X
X
X
X
(X)
X
(X)
(X)
X
Folie 24
2.5 Anweisungen
Vereinfachte Grammatik für Anweisungen
BlockAnweisung:
LokaleVariableDeklarationAnweisung |
Anweisung
LokaleVariableDeklarationAnweisung:
LokaleVariableDeklaration;
LokaleVariableDeklaration
Typ VariablenDeklaratoren
VariablenDeklaratoren:
VariablenDeklarator {, VariablenDeklarator }
VariablenDeklarator:
Bezeichner [= Ausdruck]
Beispiele füe Variablendeklarationen
int eineZahl, meineZahl = 17, nochEineZahl = 0;
double x = 0.0, sigma = 0.1E-3, ergebnis;
Anwendungsorientierte Programmierung
Folie 25
2.5 Anweisungen
BlockAnweisung: //heute
Block
AusdrucksAnweisung
IfAnweisung
WhileAnweisung
DoAnweisung
Block:
{
{BlockAnweisung }
}
Blöcke dienen der Zusammenfassung von mehreren Anweisungen zu einer.
Anwendungsorientierte Programmierung
Folie 26
2.5 Anweisungen
In der AusdrucksAnweisung sind (im Moment) nur
Zuweisung;
Preinkrementausdruck;
Postinkrementausdruck;
Predekrementausdruck;
Postdekrementausdruck ;
erlaubt. Solche Ausdrücke werden durch den Abschluss mit einem Semikolon zu
einer Anweisung.
Beispiele
x = 3.1416;
y = r = 2.0 * x;
a++;
--a;
b = ++a * 10;
Anwendungsorientierte Programmierung
Folie 27
Sichtbarkeit und Lebensdauer
package bezeichner;
{ImportDeklaration;}
public class Bezeichner {
public static void main() {
int n, k = 1; //Variablendeklaration
{ // Block
double x = 2.0;
int n = 5; //illegal
x++; // Postinkrementanweisung
System.out.println(x); // Ausgabe 3.0
n = x + k; // illegal
}
n = k + 3;
System.out.println(n); // Ausgabe 4
System.out.println(x); // illegal
}
}
Anwendungsorientierte Programmierung
Folie 28
Konventionen
Bezeichner für Klassen beginnen immer mit einem Großbuchstaben
Bezeichner für Variablen und Funktionen (Methoden) beginnen mit einem
Kleinbuchstaben
Durch die Verwendung von Groß- Kleinbuchstaben kann der Bezeichner strukturiert
werden.
Bsp.:
MyFirstClass // Klassenbezeichner
thisIsAVariable //Variablenbezeicher
meineErsteFunktion() // Funktionsbezeichner
Variablen sollten immer am Anfang einer Funktion (Methode) deklariert werden.
Die Deklaration von Variablen innerhalb eines Blocks ist auf Hilfsvariablen zu
beschränken.
Anwendungsorientierte Programmierung
Folie 29
2.5 Anweisungen
IfAnweisung :
if (Ausdruck)
Anweisung
[else
Anweisung]
Die IfAnweisung dient zur Fallunterscheidung
Beispiele:
int i = 19, k = 3;
if (k == 0)
System.out.println("nix vorhanden");
if (k == 0)
System.out.println("nix vorhanden");
else {
System.out.println(k);
i /= k;
}
Anwendungsorientierte Programmierung
Folie 30
2.5 Anweisungen
WhileAnweisung: (Schleife)
while ( Ausdruck )
Anweisung
Eine Schleife dient zur mehrfachen Ausführung einer Anweisung.
Beispiele:
int a = 10;
while (a >= 0)
a--;
while (a >= 0)
a--;
System.out.println(a);
//wahrscheinlich fehlerhaft
Anwendungsorientierte Programmierung
while (a >= 0){
a--;
System.out.println(a);
} // Block
Folie 31
2.5 Anweisungen
DoAnweisung: (Schleife)
do
Anweisung
while ( Ausdruck );
Im Gegensatz zur While-Schleife wird die Anweisung immer mindestens einmal
ausgeführt
Beispiele:
int n;
do
n = tastatur.nextInt();
while (n != 0);
Anwendungsorientierte Programmierung
do
n = tastatur.nextInt();
System.out.println(n);
while (n != 0);
// Fehlerhaft
Folie 32
2.5 Anweisungen
ForAnweisung:
for ([ForInit];[Ausdruck];[ForUpdate])
Anweisung
Im optionalen ForInit Teil können mehrere Variablen, durch Komma getrennt,
deklariert und initialisiert werden.
Die Schleife wird solange ausgeführt, wie der Ausdruck true ergibt.
ForUpdate ist ein Ausdruck, der bei nach jedem Schleifendurch ausgewertet wird.
Die in den runden Klammern deklarierten Variablen sind nur innerhalb des
Schleifenrumpfes sichtbar
Beispiel:
int sum = 0;
for(int i = 1; i <= 10; i++)
sum += i;
Anwendungsorientierte Programmierung
Folie 33
2.5 Anweisungen
Verwendung der Schleifen
forAnweisung: Sollte immer verwendet werden, wenn in der Schleife eine Variable um
einen festen Wert inkrementiert oder dekrementiert wird. Vor allem sollte vermieden
werden im Schleifenkopf komplexe Berechnungen durchzuführen.
whileAnweisung: Dient zur Durchführung von aufwändigeren Berechnungen. Es ist
hier darauf zu achten, dass alle Variablen vor der Schleife einen Wert erhalten haben
(initialisiert sind). Weiter ist zu überprüfen, ob die Berechnung zu einem Abbruch
führt.
doAnweisung: Sollte nur verwendet werden, falls es erforderlich ist (z. B. Eingabe).
Vor allem ist darauf zu achten, dass der erste Schleifendurchlauf nicht zu illegalen
Zuständen führt.
Anwendungsorientierte Programmierung
Folie 34
2.5 Anweisungen
ContinueAnweisung:
continue [Label];
Nachtrag: Vor jeder Anweisung kann ein Label stehen.
continue ohne Label : Darf nur in Schleifen stehen. Bei erreichen der Anweisung
wird die Ausführung des Programms am Beginn der innersten Schleife fortgesetzt.
continue mit Label : Der Programmlauf wird an die Anweisung mit dem Label
transferiert.
BreakAnweisung:
break [Label];
break ohne Label : Darf nur in Schleifen (oder SwitchAnweisung) stehen. Bei
erreichen der Anweisung wird die Ausführung der innersten Schleife abgebrochen.
break mit Label : Der Programmlauf wird an die Anweisung mit dem Label
transferiert.
Anwendungsorientierte Programmierung
Folie 35
2.5 Anweisungen
SwitchAnweisung:
switch ( Ausdruck ) {
{ case CaseMarke :
{ Anweisung }
}
[ default:
{ Anweisung }
]
}
CaseMarke kann eine Konstante vom Typ char, byte, short, int, Character, Byte,
Short, Integer, String oder ein Aufzählungtyp (später) sein.
Der Datentyp muss mit dem Typ des Ausdrucks übereinstimmen.
Anwendungsorientierte Programmierung
Folie 36
2.5 Anweisungen
Beispiel
int auswahl;
// hier erhält auswahl einen Wert
switch (auswahl) {
case 1 :
case 2 :
// Anweisungen für die Fälle 1 oder 2
break;
case 3 :
// Anweisungen für den Fall 3
break;
default:
// Anweisungen falls kein Fall zutrifft
}
Anwendungsorientierte Programmierung
Folie 37
2.5 Anweisungen
Regeln für switchAnweisungen
1. Die Anweisungsfolge für jeden Fall (case) oder Fälle muss durch eine
breakAnweisung (break) abgeschlossen werden.
2. Grundsätzlich sollte jede caseAnweisung ein default enthalten. Hier handelt es
sich meist um einen Entwurfsfehler, daher sollte immer eine Fehlermeldung
ausgegeben werden.
Anwendungsorientierte Programmierung
Folie 38
3 Benutzerdefinierte Datentypen
Felder dienen der Zusammenfassung gleichartiger Daten.
Beispiel: Es sollen 10 Messwerte aufgenommen werden.
Deklaration des Feldes
double[] messwerte; (alternativ double messwerte[];)
Bei der Deklaration haben Felder noch keinen Speicherplatz reserviert. Dieser muss
erst durch
int n = 10;
messwerte = new double[n];
angelegt werden.
Der Zugriff auf einzelne Elemente erfolgt durch Angabe eines Indexes
messwerte[0]
greift auf das 0te Element zu. Durch messwerte.length kann die Anzahl der Elemente
ermittelt werden. Die Indices müssen im Bereich
0..messwerte.length-1 liegen.
Anwendungsorientierte Programmierung
Folie 39
3.1 Felder (Arrays)
Beispiel: Einlesen der Messwerte und Ausdrucken
int n = 10;
double[] messwerte = new double[n];
for(int i = 0; i < n; i++) {
System.out.print("Messwert > ");
messwerte[i] = tastatur.nextDouble();
}
for(int i = 0; i < n; i++) {
System.out.print(i+"ter Messwert = " + messwerte[i]);
}
Anwendungsorientierte Programmierung
Folie 40
3.1 Felder
Mehrdimensionale Felder
Es ist möglich, Felder mit einer belieben Anzahl von Indices zu deklarieren
double[][] matrix;
Anlegen des Speichers
matrix = new double[4][4];
deklariert ein zweidimensionales Feld. Der Zugriff auf ein einzelnes Element erfolgt
durch:
matrix[1][2]
Anwendungsorientierte Programmierung
Folie 41
3.1 Felder
Felder können bei der auch mit einem Initialwert belegt werden
String[] haustiere = {"Hund","Katze","Python","Springmaus"};
double[][] em = { { 1.0, 0.0, 0.0 },
{ 0.0, 1.0, 0.0 },
{ 0.0, 0.0, 1.0 } };
Felder und die
erweiterteforAnweisung:
for (elemTyp variable : Feldvariable)
Anweisung
Diese Form der forAnweisung läuft automatisch über das ganze Feld und liefert in der
Variablen das jeweils nächste Feldelement.
Anwendungsorientierte Programmierung
Folie 42
3.1 Felder
Felder können bei der Deklaration auch mit einem Initialwert belegt werden
String[] haustiere = {"Hund","Katze","Python","Springmaus"};
double[][] em = { { 1.0, 0.0, 0.0 },
{ 0.0, 1.0, 0.0 },
{ 0.0, 0.0, 1.0 } };
Felder und die
erweiterteforAnweisung:
for (elemTyp variable : Feldvariable)
Anweisung
Diese Form der forAnweisung läuft automatisch über das ganze Feld und liefert in der
Variablen das jeweils nächste Feldelement.
Anwendungsorientierte Programmierung
Folie 43
3.1 Felder
Beispiel für die Verwendung der erweiterten for-Anweisung
String[] haustiere = {"Hund","Katze","Python","Springmaus"};
for (String tier : haustiere)
System.out.println(s);
double[][] em = { { 1.0, 0.0, 0.0 },
{ 0.0, 1.0, 0.0 },
{ 0.0, 0.0, 1.0 } };
for (double[] row : em) {
for (double x : row)
System.out.print(x);
System.out.println();
}
Anwendungsorientierte Programmierung
Folie 44
3.2 Referenzen
Referenzen
Wird der Speicherplatz einer Variablen durch new erzeugt, handelt es sich um
sogenannte Referenzen.
In der eigentlichen Variablen wird nicht der Wert eines Objekts gespeichert, sondern
nur ein Verweis (Adresse) auf den Speicherbereich.
In anderen Programmiersprachen wird dies als Zeiger (pointer) bezeichnet. Diese
existieren in Java nicht.
Wurde für eine Referenz noch kein Speicherplatz mit new angelegt, handelt es sich
um eine null-Referenz. Vor einem Zugriff, muss sichergestellt werden, dass keine
null-Referenz vorliegt. Sonst erhält man einem Laufzeitfehler
Felder sind immer Referenzen
Anwendungsorientierte Programmierung
Folie 45
3.3 Klassen
Klassen
An dieser Stelle soll nur eine vereinfachte Version für Klassen dargestellt werden.
Im Kapitel objektorientierte Programmierung werden Klassen ausführlicher
dargestellt.
Deklaration (vereinfacht)
[Modifizierer] class Klassennamen {
{ Klassenelemente }
}
Klassenelemente:
Attributdeklaration
Methodendeklaration
Modifizierer (hier)
public
private
Anwendungsorientierte Programmierung
Folie 46
3.3 Klassen
Attributdeklaration:
[Modifizierer] Variablendeklaration
Methodendeklaration:
[Modifizierer] Rückgabetyp Methodenname (Parameter) {
{ Anweisungen }
}
Rückgabetyp:
Typ
void
Anwendungsorientierte Programmierung
Folie 47
3.3 Klassen
// Klasse können überall benutzt werden
public class Zylinder {
// Daten sind von außen nicht sichtbar
private double radius;
private double hoehe;
// Zugriff auf Daten nur über Methoden (setter, getter)
public void setRadius(double r) { radius = r; }
public double getRadius() { return radius; }
public void setHoehe(double h) { hoehe = h; }
public double getHoehe() { return hoehe; }
}
Bem: Wird eine Klasse als public deklariert, so muss durch package->new->class
eine neue Datei erzeugt werden
Anwendungsorientierte Programmierung
Folie 48
3.3 Klassen
Verwendung
Deklaration
Zylinder zylinder;
Anlegen von Speicherplatz (Klassen sind immer Referenzen)
zylinder = new Zylinder();
Setzen von Radius und Höhe
zylinder.setRadius(2.0);
zylinder.setHoehe(10.5);
Lesen der Daten
double r = zylinder.getRadius();
double h = zylinder.getHoehe();
Anwendungsorientierte Programmierung
Folie 49
4 Unterprogramme
Vorbemerkung: Java ist vom ganzen Konzept her eine objektorientierte
Programmiersprache. Eine Verwendung von Java für prozedurale Programmierung ist
nicht vorgesehen. Die hier vorgestellten Methoden sollten daher NICHT für echte
Java-Programme verwendet werden. Es soll jedoch dieses Programmierparadigma
mit Hilfe von Java vorgestellt werden.
Verwendung von Unterprogrammen
– Oftmals gibt es in einem Programm nahezu identische Programmteile. Diese
können zu Unterprogrammen zusammengefasst werden und müssen daher nur
einmal programmiert werden. Unterschiede werden durch Parameter realisiert.
– Unterprogramme werden auch zur Strukturierung eingesetzt. Hierbei sollten die
Unterprogramme den Entwurfsprozess widerspiegeln. Es gilt die Regel, dass
ein fortlaufender Programmtext nicht länger als ein oder zwei Bildschirmseiten
sein sollte.
Anwendungsorientierte Programmierung
Folie 50
4 Unterprogramme
Deklaration eines Unterprogramms
Alle Deklarationen erfolgen in der Klasse die das Hauptprogramm main enthält.
static Rückgabetyp Unterprogrammname( Parameter ) {
{ Anweisungen }
}
Rückgabetyp:
Typ
void
Parameter:
[Typ Parametername {, Typ Parametername} ]
Als Rückgabetyp sind auch Felder und Klassen zulässig
Der Modifizierer static wird später behandelt und muss hier immer stehen.
Anwendungsorientierte Programmierung
Folie 51
4 Unterprogramme
Die returnAnweisung
return;
//1
return Ausdruck; //2
1. Diese Art der returnAnweisung darf nur in Unterprogrammen mit dem
Rückgabetyp void verwendet werden. Hierdurch kann ein vorzeitiger
Rücksprung erreicht werden. In einem Unterprogramm können mehrere
returnAnweisungen vorkommen.
2. Die returnAnweisung mit Ausdruck muss in Unterprogrammen mit Rückgabetyp
ungleich void stehen. Es ist notwendig, dass auf jedem Ausführungspfad eine
returnAnweisung erreicht wird. Durch den Wert des Ausdrucks wird der
zurückgegebene Wert bestimmt.
Anwendungsorientierte Programmierung
Folie 52
4 Unterprogramme
Beispiel
static double max( double a, double b) {
// a und b sind formale Parameter
if ( a > b )
return a;
else
return b;
}
Aufruf
double x = 10, y = 17, z;
z = max(x, y - 10)
// x und (y - 10) sind aktuelle Parameter
Anwendungsorientierte Programmierung
Folie 53
4 Unterprogramme
Signatur
Der Name und die Reihenfolge der Datentypen in der Parameterliste wird als
Signatur bezeichnet
Beispiele:
static void up1(double x, int n, Zylinder z) { … }
hat die Signatur up1(double, int, Zylinder)
static int up2(double y, float a) { … }
hat die Signatur up2(double, float)
Die Namen der Parameter und der Rückgabetyp werden bei der Signatur nicht
berücksichtigt
Es ist unzulässig, in einer Klasse Unterprogramme (Methoden) mit gleicher Signatur
zu deklarieren.
z. B.:
static void up2(double d, float b) { … }
ist eine illegale Deklaration; aber
static int up2(int d, float b) { … }
ist legal.
Anwendungsorientierte Programmierung
Folie 54
4.1 Parameterübergabe
Zunächst sollen primitive Datentypen betrachtet werden
// Deklaration
static double max(double a; double b) {
return (a > b)? a : b;
}
Umgebung von max
a
b
Aufruf von max
double x = 18.1;
double y = 5.9;
Zunächst werden die Ausdrücke bewertet
y * 10.0 = 59.0 und x / 10.0 = 1.81
Diese Werte werden dann in die Umgebung
kopiert
double z = max(y*10.0, x / 10.0);
Die Berechnung erfolgt in der Umgebung, somit ist eine
Änderung der aktuellen Parameter durch das Unterprogramm
nicht möglich (Wertparameter, call by value)
Anwendungsorientierte Programmierung
a
59.0
b
1.81
Folie 55
4.1 Parameterübergabe
Benutzerdefinierte Datentypen (Felder oder Klassen)
Benutzerdefinierte Datentypen sind grundsätzlich Referenzen. Leider wird in Java der
eigentliche Mechanismus verdeckt.
radius
Zylinder z = new Zylinder();
Referenzvariable
z
Adresse
static void weird(Zylinder k) {
k.setRadius(1.0)
// Ändert den Eintrag
Zylinder neu = new Zylinder();
k = neu;
// keine Änderung an z (aber an k)
}
weird(z);
//Aufruf
Anwendungsorientierte Programmierung
k
Adresse von z
hoehe
Speicher für Zylinder
Folie 56
4.2 Rekursive Unterprogramme
Unterprogramme können auch andere Unterprogramme und auch sich selbst aufrufen.
Das wird als rekursiver Aufruf bezeichnet.
Beispiel:
static void fakultaet(int n) {
if (n < 0)
return -1; // Fehler
// Rekursionsbasis
if ((n == 0) || (n == 1))
return 1;
else
// Rekursion
return n * fakultaet(n-1)
}
Anwendungsorientierte Programmierung
Folie 57
5 Verwendung vordefinierter Klassen
Ableitung von Klassen
Oberklasse (Basisklasse)
Unterklasse
(abgeleitete Klasse)
Kutsche
Anzahl Pferde
erben: Sitzpläze
Fahrrad
Kraftfahrzeug
Motorleistung
void kraftfahrstrasse(Kraftfahrzeug f) { …}
PKW ferrari = new PKW();
Fahrrad peugeot = new Fahrrad();
PKW
kraftfahrstrasse(ferrari); // legal da Kraftfahrzeug hat
Sitzplätze
kraftfahrstrasse(peugeot); // kein Kraftfahrzeug
Motorleistung
Anwendungsorientierte Programmierung
LKW
Spezialisierung
Fahrzeug
Sitzplätze
Folie 58
5.1 Die Klasse Exception
package java.lang.Exception (Auszug)
Ableitungsbaum
Exception e
IOException
FileNotFoundException
RuntimeException
IllegalArgumentException
NumberFormatException
nützliche Methoden
• e.getClass().getName() liefert die Ausnahme als String
• e.getMessage()
liefert Fehlermeldung
• e.toString()
liefert Name und Fehlermeldung
• e.printStackTrace()
Stapelabzug
Anwendungsorientierte Programmierung
Folie 59
5.1 Fehlerbehandlung
TryCatchBlock
try {
{ Anweisungen }
} {catch ( ExceptionTyp Name){
{ Anweisungen }
}}
[finally {
{ Anweisungen }
}]
Anwendungsorientierte Programmierung
Folie 60
5.1 Fehlerbehandlung
Beispiel
try {
//
//
//
} catch
if
Anweisungen die eine allgemeine IOException, eine
FilenotFoundException oder eine NumberFormatException
auslösen
(IOException e) {
(e isinstanceof FileNotFoundExcception) {
// Behandlung von dieser Ausnahme
} else {
// allgemeiner Eingabefehler
}
} catch (NumberFormatException e) {
// Behandlung dieser Ausnahme
} finally {
// wird immer ausgeführrt
}
Anwendungsorientierte Programmierung
Folie 61
5.1 Fehlerbehandlung
Weiterleiten
Will ein Unterprogramm Ausnahmen nicht selbst behandeln, so kann es diese an
den Aufrufer weiterleiten
public static void getFile(String filename)
throws FileNotFoundException {
// Anweisungen die eine FileNotFoundException auslösen
// können
}
zeichnen.setText(
Auslösen von Exceptions
public static void setAge( int a)
throws IllegalArgumentException
{
if (a <= 0)
throw new IllegalArgumentException("Age must be > 0!");
age = a;
}
Anwendungsorientierte Programmierung
Folie 62
5.1 Fehlerbehandlung
Checked und Unchecked Exceptions
– Checked Exceptions
Diese Art der Exceptions müssen behandelt werden
• Durch TryCatchBlock
• Durch Weiterleiten mit throws Exception1, Exception2 …
Beispiel: IOException
– Unchecked Exceptions
Diese können zum Aufrufer ohne Behandlung weitergeleited werden.
Hierzu gehören: Error, RunTimeExceptions und alle Unterklassen
Anwendungsorientierte Programmierung
Folie 63
6 Dateien
Die Klasse File
Zur Benutzung dieser Klasse muss diese mit
import java.io.*
importiert werden
Mit der Klasse file wird die Verbindung zwischen Dateien des Betriebssystems
und programminternen Variablen hergestellt.
Einige Methoden der Klasse
File(String pathname) erzeugt ein File Objekt
Die Konstanten File.separatorChar (Typ char) und File.sparator (Typ
String) liefernden Betriebsystem spezifischen Pfadtrenner (z. B. '\' Windows, '/' Unix)
boolean exists() gibt an, dass die Datei vorhanden ist
boolean isDirectory() liefert true für ein Verzeichnis
boolean isFile() liefert true für eine normale Datei
Anwendungsorientierte Programmierung
Folie 64
6 Dateien
Schreiben in Dateien
Dateien werden in Java als Datenströme (streams) gesehen. Daher muss zunächst
ein OutputStream erzeugt werden.
File f = new File("C:\javatexte\daten.txt");
OutputStream ostream = new FileOutputStream(f); // oder
OutputStream ostream = new FileOutputStream(f, true);
// erweitern der Datei
Es kann eine FileNotFoundException ausgelöst werden
Setzen eines Schreibers mit Zeichencodierung
PrintStream writer = new PrintStream(ostream,"ISO8859_1");
Auf der Variablen writer sind nun die von System.out bekannten Methoden
deklariert.
Es kann eine UnsupportedEncodingException ausgelöst werden
Anwendungsorientierte Programmierung
Folie 65
6 Dateien
Schreiboperationen (Bsp.)
writer.print("Ein Text ohne Zeilenumbruch");
writer.println("Ein Text mit Zeilenumbruch");
writer.printf("Eine formatierte Zahl: %6.2f",2.0);
Grundsätzlich werden Schreiboperationen gepuffert. Damit eine Ausgabe
tatsächlich geschrieben wird, muss der Puffer geleert werden:
writer.flush();
Weiter müssen alle geöffneten Dateien spätestens am Ende des Programms
geschlossen werden:
writer.close();
Anwendungsorientierte Programmierung
Folie 66
6 Dateien
Lesen aus Dateien
Das Lesen erfolgt analog dem Schreiben
File f = new File("C:\javatexte\daten.txt");
InputStream istream = new FileInputStream(f);
Es kann eine FileNotFoundException ausgelöst werden
Setzen eines Lesers mit Zeichencodierung
Scanner reader = new Scanner(istream,"ISO8859_1");
Es kann eine UnsupportedEncodingException ausgelöst werden
Es muss der Scanner importiert werden über:
import java.util.Scanner;
Anwendungsorientierte Programmierung
Folie 67
6 Dateien
Leseoperationen
Der Scanner ist ein sehr leistungsfähiges Hilfsmittel. (Bitte nachlesen)
Einige Beispiele
reader.nextXXX(); // XXX = Byte, Int, Double usw. liest einen Wert ein
Damit kein Lesefehler auftritt sollte immer zuerst mit
if (reader.hasNextXXX()) {
reader.nextXXX();
}
geprüft werden ob ein solches Token überhaupt vorhanden ist
Anwendungsorientierte Programmierung
Folie 68
Objektorientierte
Programmierung
Anwendungsorientierte Programmierung
Folie 69
7 Objektorientierte Programmierung
Konzepte und Begriffe
Ein Programm besteht aus mehreren Objekten. Diese können Aufträge erledigen,
den Zustand ändern und berichten und mit anderen Objekten kommunizieren. Die
konkrete Implementierung wird hierbei verborgen.
Gleichartige Objekte werden in Java durch eine Klasse beschrieben. Ein konkretes
Objekt wird als Instanz der Klasse bezeichnet.
Daten werden durch die Attribute der Klassen gehalten.
Das Verhalten wird durch die Methoden der Klasse bestimmt. Eine Änderung von
Attributen darf nur durch Methoden erfolgen.
Aus Klassen lassen sich spezialisiertere Klassen ableiten. Diese erben alle oder
Teile der Eigenschaften der Basisklasse. Durch Polymorphie können sich Methoden
je nach Bindung unterschiedlich verhalten.
Anwendungsorientierte Programmierung
Folie 70
7.1 Schreiben eigener Klassen
Organisation von Java-Programmen
package a // Paket
package b // Unterpaket
…
public class C { … } //Klassen (compilation units)
class D { … }
a.b vollständig qualifizierter Name des Unterpakets b
a.b.C vollständig qualifizierter Name der Klasse C
Der vollständig qualifizierte Name muss eindeutig sein.
Sichtbarkeitsregeln:
Alle compilation units haben Zugriff auf die im Paket deklarierten Typen
und auf als public deklarierte Typen aus java.lang
Auf public deklarierte Typen kann von außen zugegriffen werden. Allerdings muss
das Paket importiert werden.
Anwendungsorientierte Programmierung
Folie 71
7.1 Schreiben eigener Klassen
Klassen
[Modifizierer] class Klassennamen [extends Klassenname]{
{ Klassenelemente }
}
Klassenelemente:
Attributdeklaration
Methodendeklaration
Unterklassen
Modifizierer
public protected private
abstract static final strictfp
Anwendungsorientierte Programmierung
Folie 72
7.1 Schreiben eigener Klassen
Für Klassen auf der obersten Ebene sind die zulässigen Modifizierer nur:
public abstract final (einzelne können/müssen entfallen)
Bedeutung der Modifizierer
public:
Die Klasse ist an jeder Stelle eines Programms sichtbar, falls das Paket sichtbar ist.
Fehlt der Modifizierer public, so ist die Klasse nur innerhalb des Pakets sichtbar.
Nützlich für "lokale" Klassen.
abstract, final später
Klassen können auch innere Klassen besitzen. Innere Klassen können auch
static oder private deklariert werden.
Anwendungsorientierte Programmierung
Folie 73
7.1 Schreiben eigener Klassen
Modifizierer bei Attributen und Methoden
public: analog Klasse
private: Attribute sollten, Methoden können privat deklariert werden. Hierdurch
sind diese nicht mehr von außen zugreifbar. Bei Attributen erfolgt der Zugriff über
Zugriffsfunktionen (setter, getter). Private Methoden dienen der Strukturierung im
Sinne von Unterprogrammen, wobei diese nur für interne Berechnungen benötigt
werden
static: Methoden und Attribute existieren außerhalb von Objektinstanzen.
final: Attribute können nur einmal zugewiesen werden. Es handelt sich also
praktisch um Konstante. Diese werden meist in Großbuchstaben geschrieben und
dürfen auch als public deklariert werden.
Der Modifizierer final für Methoden wird später erklärt.
Anwendungsorientierte Programmierung
Folie 74
7.1 Schreiben eigener Klassen
Beispiel
Bsp obj = obj.read() // zulässig
public class Bsp {
obj.nr = 10; // unzulässig
private int index;
obj.setNr(10); // zulässig
private int nr;
public void setNr(int nrPar) { obj.index = 1; //unzulässig
nr = nrPar;
// index ist nicht zugreifbar
}
obj.print(); // ok
public int getNr() {
Bsp.print(); // unzulässig
return nr;
}
int i = obj.foo()
// unzuässig, da
public void print() { …}
// private
private int foo() {…}
int i = obj.nr;
// s.o.
public Bsp read() {…}
}
Anwendungsorientierte Programmierung
Folie 75
7.1 Schreiben eigener Klassen
nicht statische und statische Elemente
Im allgemeinen werden die Attribute und Methoden einer Klasse nicht statisch
deklariert. Damit sind diese an ein konkretes Objekt (Instanz) der Klasse gebunden.
Statische Attribute und Methoden existieren außerhalb von konkreten Objekten und
sind an die Klasse gebunden. Statische Elemente sollten nur in bestimmten
Spezialfällen verwendet werden.
public class Bsp {
private static int anzahl
= 0;
private int nr = ++anzahl;
public void printNr() {
{ … }
{
System.out.println(nr);
}
public void printAnzahl()
public static Bsp create()
return new
Anwendungsorientierte
Programmierung
}
}
Bsp();
Bsp obj1, obj2, obj3;
obj1 = new Bsp();
obj1.printAnzahl(); // 1
obj2 = Bsp.create();
obj3 = obj2.create(); // ???
obj1.printNr(); // 1
obj2.printNr(); // 2
obj3.printNr(); // 3
obj1.printAnzahl(); // 3
obj2.printAnzahl(); // 3
obj3.printAnzahl(); // 3
Folie 76
7.1 Schreiben eigener Klassen
Anwendungsorientierte Programmierung
Folie 77
7.1 Schreiben eigener Klassen
Datenaustausch durch statische Variablen (bei mehreren Threads sind weitere
Maßnahmen erforderlich)
class ProdCons {
private static int puffer;
public void store(int n) {
Puffer = n;
}
public int get() {
return puffer;
}
}
ProdCons pc1 = new ProdCons(), pc2 = new ProdCons();
pc1.store(5);
System.out.println(pc2.get()); // 5
Anwendungsorientierte Programmierung
Folie 78
7.1 Schreiben eigener Klassen
Die this Referenz.
Mit dem Schlüsselwort this wird auf die aktuelle Klasseninstanz verwiesen.
Hiermit können Namensverwechslungen aufgelöst werden
public class NameClash {
public String name
public setName(String name) {
this.name = name;
}
public copyName(NameClash that) {
this.name = that.name;
}
}
In statischen Methoden ist die Verwendung von this nicht erlaubt.
Anwendungsorientierte Programmierung
Folie 79
7.1 Schreiben eigener Klassen
Der Konstruktor
Für alle mit new angelegten Objekte muss entsprechender Speicherplatz angelegt
werden. Hierbei wird automatisch ein Konstruktor aufgerufen.
Für jede Klasse wird immer ein Konstruktor der Form
public Klassenname() {} // der Standard-Konstruktor
erzeugt. Alle Attribute werden mit 0, 0.0 bzw. null belegt.
Parametrisierter Konstruktor
Es ist möglich, eigene Konstruktoren zu erstellen. Konstruktuktoren können dann
mit Parametern versehen werden. Damit lassen sich bestimme Attribute gezielt
setzen.
Konstruktoren können überladen werden.
Eine Sonderstellung nimm ein Konstruktor ein, der als Parameter die Klasse selbst
enthält. Meist wird dieser dazu eingesetzt, eine Kopie eines Objekts zu erstellen.
Falls eigene Konstruktoren erstellt werden, so fügt der Compiler kein StandardKonstruktor mehr ein. Wird dieser benötigt, so muss er manuell hinzugefügt werden.
Anwendungsorientierte Programmierung
Folie 80
7.1 Schreiben eigener Klassen
public class NameAge {
public NameAge() {} // Standard-Konstruktor
public NameAge(String name) { this.name = name; }
public NameAge(NameAge toCopy) { // Copy-Konstruktor
this.name = toCopy.name;
this.age = toCopy.age;
}
static NameAge read(InputStream istream) {
NameAge ret = new NameAge();
// einlesen; statische Methode als Pseudokonstruktor
return ret;
}
// setter, getter
private String name;
private int age;
}
Anwendungsorientierte Programmierung
Folie 81
7.1 Schreiben eigener Klassen
Initialisierung von Attributen
public class NameAge {
public NameAge() {} // Standard-Konstruktor
// setter, getter
public void printMbrNr() {
System.out.println("Nr: " + MBR_NR);
}

private static memCnt = 1;
 wird in den Konstruktor einkopiert
private final int MBR_NR = memCnt++; 
private String name;
private int age;
}
Der Modifizierer final bei Attributen bewirkt, das diese Attribute nur einmal
zugewiesen werden können. Es handelt sich um eine Art von Konstanten.
Diese sollten groß geschriebenen werden und können public sein.
Anwendungsorientierte Programmierung
Folie 82
7.2 Ableiten von Klassen
Durch die Angabe extends wird eine Klasse aus einer anderen abgeleitet
Beispiel
public class Base {
// Basisklasse, Oberklasse
…
}
public class Sub1 extends Base {// Unterklasse, abgeleitete Klasse
…
}
public class Sub2 extends Base {
…
}
Hierdurch erhält jede Unterklasse alle Attribute und Methoden der Oberklasse.
Werte und Konstruktoren werden nicht vererbt.
Anwendungsorientierte Programmierung
Folie 83
7.2 Ableiten von Klassen
Es kann beliebig viele Hierarchiestufen geben
Jede abgeleitete Klasse (Unterklasse) ist auch vom Typ der Oberklasse
class A
class BA extends A
A a = new DCA();
mit instanceof kann der Typ
geprüft werden
a instanceof
a instanceof
a instanceof
a instanceof
a instanceof
A // true
CA // true
DCA // true
ECA // false
BA // false
Anwendungsorientierte Programmierung
class CA extends A
class DCA extends CA
class ECA extends CA
In Java sind alle Klassen vom Typ Object
Folie 84
7.2 Ableiten von Klassen
Es kann durch Typkonvertierung der ursprüngliche Datentyp zurück gewonnen werden
Beispiel:
public class Base { }
public class Spec1 extends Base {
public void print() {… }
}
public class Spec2 extends Base {
public void write() {… }
}
Base[] basefeld; // gefüllt mit Spec1 oder Spec2
…
if (basefeld[i] instanceof Spec1)
((Spec1)basefeld[i]).print();
if (basefeld[i] instanceof Spec2)
((Spec2)basefeld[i]).write();
Anwendungsorientierte Programmierung
Folie 85
7.2 Ableiten von Klassen
Modifizierer private, protected, public und Sichtbarkeitsregeln
private: Innere Klassen, Attribute und Methoden sind nur innerhalb der Klasse
sichtbar. Allerdings dürfen innere Klassen auf private Methoden und Attribute der
umgebenden Klasse zugreifen.
kein Modifizierer: beschreibt die Paketsichtbarkeit. Klassen, Attribute und Methoden
sind nur innerhalb des gleichen Pakets sichtbar und zugreifbar.
protected: Innere Klassen, Attribute und Methoden haben Paketsichtbarkeit und
sind in allen abgeleiteten Klassen (auch in anderen Paketen) sichtbar.
public: Klassen, Attribute und Methoden sind überall sichtbar.
Die Sichtbarkeit von Elementen ist ein Teil des Entwurfs und sollte überlegt
eingesetzt werden. Grundsätzlich sollte die Sichtbarkeit so eng wie möglich gesetzt
werden.
Anwendungsorientierte Programmierung
Folie 86
7.2 Überschreiben (Polymorphie)
Enthält eine Oberklasse eine Methode mit gleichem Namen und gleicher Signatur
wie eine abgeleitete Klasse, so wird diese Methode überschrieben. Wird bei einem
Objekt diese Methode aufgerufen so wird immer die in der Hierarchiestufe am
nächsten stehende Methode aufgerufen.
Bem.: Es können auch Attribute überschrieben werden (wenig sinnvoll)
public class AType {
public void print() { System.out.println("Ich bin ein A"); }
}
public class BType extends AType {
public void print() { System.out.println("Ich bin ein B"); }
}
AType aInst = new AType();
AType bInst = new BType();
aInst.print();
// Ich bin ein A
bInst.print();
// Ich bin ein B
Anwendungsorientierte Programmierung
Folie 87
7.2 Überschreiben
public class Base {
public void hair(double x) {
System.out.println("Short hair");
}
}
public class Extensions extends Base {
public void hair(int x) {
System.out.println("Long hair");
}
}
Base kopf1 = new Extensions();
Extensions kopf2 = new Extensions();
kopf1.hair(3.1);
// Short hair
kopf1.hair(3);
// Short hair
kopf2.hair(3.1);
// Short hair
kopf2.hair(3);
// Long hair
Anwendungsorientierte Programmierung
Lösung: Direktive
@Override
vor der Methode einfügen
Folie 88
7.2 Super
Eine überschriebene Methode (oder überschriebenes Attribut) kann über die
vordefinierte Referenz super wieder aktiviert werden
public class Basis {
public void print() { System.out.println("Basis"); }
}
public class Lower extends Basis {
@Override
public print() { System.out.println("Lower"); }
public superPrint() { super.print(); }
}
…
Basis lower = new Lower();
lower.print()
// Lower
lower.superPrint()
// Basis
Anwendungsorientierte Programmierung
Folie 89
7.3 Abstrakte Klassen
Abstrakte Klassen und Methoden
• oft kann es sinnvoll sein, in einer Oberklasse lediglich zu deklarieren, welche
Methode alle Unterklassen aufweisen sollen ohne diese in der Oberklasse
auszuprogrammieren.
• eine solche Klasse heißt abstrakt
• Von einer solchen Klasse kann kein Objekt mit new erzeugt werden, da bestimmte
Methoden nicht ausführbar sind.
Damit diese Klasse verwendbar wird, muss es eine nicht abstrakte Unterklasse
geben, die alle abstrakten Methoden der Oberklassen ausprogrammieren.
Anwendungsorientierte Programmierung
Folie 90
7.3 Abstrakte Klassen
Die Deklaration erfolgt durch das Schlüsselwort abstract
public abstract class Basis {
public abstract void methode();
// die Methode erhält keinen Rumpf
}
Falls eine Klasse eine abstrakte Methode enthält, so muss die Klasse ebenfalls
abstrakt sein.
Aus einer abstrakten Klasse können weitere abstrakte Klassen abgeleitet werden, die
einige (oder alle) abstrakten Methoden abstrakt lassen.
Anwendungsorientierte Programmierung
Folie 91
7.3 Abstrakte Klassen
public abstract class Knoten {
private int index;
public abstract double eval();
}
public class Add extends Knoten {
private Knoten leftOp;
private Knoten rightOp;
public double eval() {
return leftOp.eval() + rightOp.eval();
}
}
public class Wert extends Knoten {
private wert;
public double eval() { return wert; }
}
Anwendungsorientierte Programmierung
Folie 92
7.4 Finale Klassen und Methoden
In bestimmten Situationen soll das Ableiten von Unterklassen und das Überschreiben
von Methoden verhindert werden.
Deklaration einer finalen Klasse
public final class ThisIsTheEnd {
…
}
Die nachfolgende Deklaration ist daher unzulässig
public class SoNicht extends ThisIsTheEnd {…}
Deklaration einer finalen Methode
public class Klasse {
public final void bitterEnd(){…}
}
public class UnterKlasse extends Klasse {
@Override
public void bitterEnd(){… } // unzulässig
}
Anwendungsorientierte Programmierung
Folie 93
7.5 Konstruktoren
Wird ein neues Element einer Unterklasse erzeugt, so werden für alle Unterklassen
die Standardkonstruktoren in der Hierarchiereihenfolge ausgeführt.
public class Base {…}
public class Level1 extends Base {…}
public class Level2 extends Level1 {…}
public class Level3 extends Level2 {…}
durch eine Anweisung
Level1 item = new Level3();
wird ein neues Objekt folgendermaßen erzeugt:
Konstruktion Object()
(alle Java-Objekte sind vom Typ Object)
Konstruktion Base()
Konstruktion Level1()
Konstruktion Level2()
Konstruktion Level3() und Rückgabe der Referenz an item
Anwendungsorientierte Programmierung
Folie 94
7.5 Konstruktoren
Wird bei der Deklaration einer Klasse C ein parametrisierter Konstruktor angegeben,
so entfällt der Standardkonstruktor. Daher kann eine von C abgeleitete Klasse D nicht
mehr eindeutig konstruiert werden.
public class C {
public C(int n) {…}
}
public class D extends C{
// Fehlermeldung: Implicit super constructor C() is undefined
…
}
Lösungen:
– Manuelles Einfügen eines Standardkonstruktors in der Klasse C
– Aufruf eines parametrisierten Konstruktors von C durch super(…)
public class D {
public D() { super(1); } // Ausführen von C(int n)
} // super(…) muss immer die erste Anweisung sein
Anwendungsorientierte Programmierung
Folie 95
7.6 Schnittstellen (Interfaces)
Schnittstellen sind Klassenbeschreibungen, die nur
– abstrakte Methoden (ohne Angabe von abstract) und
– finale statische Attribute (ohne Angabe von public static final, Konstanten)
beinhalten
Es wird kein ausführbarer Quelltext vererbt (sog. Schnittstellenvererbung)
Deklaration: interface statt class
Anwendungsorientierte Programmierung
Folie 96
7.6 Schnittstellen (Interfaces)
Beispiele
public interface Position {
void setPoint(double x, double y);
}
public interface GeoObjekt {
double flaeche();
double umfang();
}
Anwendungsorientierte Programmierung
Folie 97
7.6 Schnittstellen (Interfaces)
Interfaces verwenden (implementieren)
– Schnittstellen sind ähnlich wie Oberklassen. Anstatt mit extends wird diese mit
implements angegeben
public class Punkt implements Position {
…
}
– Im Gegensatz zu Oberklassen kann eine Klasse mehrere Schnittstellen
implementieren (Mehrfachvererbung)
public class Rechteck
implements Position, GeoObjekt {
…
}
– Wird eine Methode einer Schnittstelle nicht ausprogrammiert, so ist die Klasse
abstrakt
Anwendungsorientierte Programmierung
Folie 98
7.6 Schnittstellen (Interfaces)
Eine Klasse kann gleichzeitig abgeleitet werden und Schnittstellen implementieren
public class Computer { … }
public class GPSEmpfänger extends Computer
implements Position {
…
}
Die Klasse GPSEmpfänger ist sowohl vom Datentyp Computer als auch Position
Schnittstellen können abgeleitet werden
public interface GeoObjektPlus extends GeoObject {
Punkt getSchwerpunkt();
}
Anwendungsorientierte Programmierung
Folie 99
7.7 Innere Klasse
Klassen können innerhalb einer anderen Klasse deklariert werden
Gründe:
– Strukturierung
– sollen nicht lokal sichtbar sein
– insbesondere in der GUI-Programmierung elegante Technik,
um den Quelltext übersichtlich zu halten
Sichtbarkeitsmodifikatoren (private etc.) sind zulässig
innere Klassen können auf Attribute und Methoden der äußeren Klasse zugreifen
Anwendungsorientierte Programmierung
Folie 100
7.7 Innere Klassen
public class Spieler {
private Stein stein;
Spieler (int wert) {
stein = new Stein(wert);
}
private class Stein {
int wert;
Stein(int wert) {
this.wert = wert;
}
}
int nenneWert() {
return stein.wert;
}
}
Anwendungsorientierte Programmierung
Folie 101
7.7 Innere Klassen
class Aussen {
Innen inner;
…
class Innen {
int y;
…
}
}
Deklaration:
Aussen.Innen abc;
Zugrifff:
Aussen inst;
inst.inner.y = 17;
Anwendungsorientierte Programmierung
Folie 102
7.7 Varianten von inneren Klassen
• Lokale Klassen
werden innerhalb von Methoden oder
Blöcken deklariert
• Anonyme Klassen
lokale Klassen können ohne Namen bleiben
als Implementation einer Schnittstelle
• Statische innere Klassen
wenn die innere Klasse auch ohne Instanzen der äußeren Klasse
Instanzen haben soll
Anwendungsorientierte Programmierung
Folie 103
7.8 Modellierung der Daten
Unterschiedliche Arten von Datenstrukturen
Beispiel: Graph
Datenstrukturen zur Verwaltung:
1
• Liste von Knoten
• Liste von Kanten
6
2
5
3
4
Anwendungsorientierte Programmierung
Datenstrukturen für die Information
Knoten
Index, Farbe
Vorgänger, Nachfolger (Nachbar)
Kanten
Von, Nach bzw.
K1, K2
Folie 104
7.8 Modellierung der Daten
Möglichkeiten der Modellierung von Daten
 Ableiten
 Implementieren von Interfaces
 Komposition
• Aggregation
• Bekanntschaft
Verwendung von Entwurfsmuster
E.Gamma, R. Helm, R. Johnson, J. Vlissides
Design Pattern, Elements of Reusable Object-Oriented Software
Addison Wesley
Anwendungsorientierte Programmierung
Folie 105
7.8 Modellierung der Daten
Ableiten
public class Ware {
protected int preis;
protected int teileNr;
}
public abstract class Blumen extends Ware {
abstract public String pflegeAnleitung();
}
public class Rohre extends Ware {
public double abmessung;
}
public class UsambaraVeilchen extends Blumen {
…
} …
Anwendungsorientierte Programmierung
Folie 106
7.8 Modellierung der Daten
Verwendung von Interfaces
interface Orderable {
void setPreis(double p);
double getPreis()
}
public class Blumen implements Orderable{
private double preis;
public void setPreis() { … }; // usw.
}
public class Rohre implements Orderable {
private double preis;
public void setPreis() { … }; // usw.
}
public class Usambaraveilchen extends Blumen {…} …
Anwendungsorientierte Programmierung
Folie 107
7.8 Modellierung der Daten
Komposition: Hier Aggregation (Lebenszeit des zugeordneten Objekts ist gleich der
des übergeordneten Objekts)
public abstract class Inf {
public abstract String showInf();
}
public class Abmessungen extends Inf {
public String showInf() { … }
}
public class Pflegeanleitung extends Inf { … }
public abstract class Blumen …{
private Inf inf = new Pflegeanleitung();
}
public class Rohre …{
private Inf inf = new Abmessungen();
}
Anwendungsorientierte Programmierung
Folie 108
7.8 Modellierung der Daten
Komposition: Bekanntschaft (Die referenzierten Objekte sind unabhängig)
public class PreisListe {
public void setPreis(int nr, double ezp) { … }
public double getPreis(int nr) { … }
}
public class Blumen {
protected PreisListe plRef; // jede Ware erhält eine Referenz
public Blumen(Preisliste pl) {
plRef = pl;
}
}
public class UsambaraVeilchen extends Blumen {
public UsambaraVeilchen(PreisListe pl) {
super(pl);
plRef.setPreis(id, 2.99); …
}
Anwendungsorientierte Programmierung
Folie 109
7.2.1 Entwurfsmuster: Singleton
Private Konstruktoren (Singletons)
Konstruktoren können auch private deklariert werden. Damit wird verhindert, dass
mehrere Objekte angelegt werden können
public class Fujisan {
private Fujisan() {
aus = "富士山";
}
public static Fujisan getFuji() {
if (fuji = null)
return (fuji = new Fujisan());
else
return fuji;
}
private static Fujisan fuji = null;
private String aus
}
Anwendungsorientierte Programmierung
Folie 110
7.8 Modellierung der Daten
Die Preisliste wird als Singleton implementiert
public class PreisListe {
private PreisListe pl …
static PreisListe getPreisListe() { s.o. }
public void setPreis(int nr, double ezp) { … }
public double getPreis(int nr) { … }
}
public class Blumen { … }
public class UsambaraVeilchen extends Blumen {
public UsambaraVeilchen() {
// keine Referenz notwendig
PreisListe.getPreisListe().setPreis(id, 2.99); …
}
Anwendungsorientierte Programmierung
Folie 111
7.2.2 Entwurfsmuster: Factory
public abstract class Produzent { // oder interface
public static Produzent create(String gebaeude) {
switch (gebaeude) {
case "Schmiede" : return new Schmiede();
case "Bauernhof" : return new Bauernhof();
default: // Fehlerbehandlung
}
}
public abstract void produce();
}
public class Schmiede extends Produzent {
public void produce() { System.out.println("Werzeuge"); }
}
public class Bauernhof extends Produzent {
public void produce() { System.out.println("Weizen"); }
}
Anwendungsorientierte Programmierung
Folie 112
8.1 Entwurfsmuster: Factory
public static void main() {
Produzent[] produzenten = new Produzent[3];
produzenten[0] = Produzent.create("Schmiede")
produzenten[1] = Produzent.create("Bauernhof");
produzenten [2] = Produzent.create("Bauernhof");
for (Produzent p : produzenten) {
p.produce();
}
}
// Ausgabe
Werkzeuge
Weizen
Weizen
Anwendungsorientierte Programmierung
Folie 113
7.2 Modellierung der Daten
Einfügen eines Bestellformulars
public class Formular {
…
public static Formular generateOrderForm(String typ) { … }
}
public class UsambaraVeilchen {
private Formular of = Formular.generateOrderForm("Usambara") {
// Daten können beispielweise aus einer Datei eingelesen
// werden
}
public class VierkantStahlrohr {
public Formular of = Formular.generateOrderForm("20x20") {
}
Anwendungsorientierte Programmierung
Folie 114
7.3 Generische Klassen
Motivation
eine datenhaltende Klasse kann nur eine Art von Information speichern.
was ist, wenn wir unterschiedliche Informationen speichern wollen?
mehrere fast identische Klassen müssen geschrieben werden!
oder: nur Datentyp Object, aber dann fehlt die Kontrolle über die Konsistenz der
gespeicherten Daten
Anwendungsorientierte Programmierung
Folie 115
7.3 Generische Klassen
Idee: Generizität
Vorbild: bei den Feldern wird ein Basisdatentyp angegeben
String[] namen;
Danach ist klar: namen[i] sind vom Typ String
Idee: Klassendefinition mit einem Typparameter T versehen
class Liste < T > {. . . }
T wird innerhalb der Klasse wie ein normaler Typ (als Stellvertreter) benutzt
Anwendungsorientierte Programmierung
Folie 116
7.3 Generische Klassen
Eigene generische Klassen schreiben
public class Paar<Typ> {
private Typ l, r;
public Paar<Typ>(Typ l, Typ r) {
this.l = l;
this.r = r;
}
public Typ getL() {
return l;
}
public Typ getL() {
return l;
}
public String toString() {
return ("(" + l.toString + "," + r.toString +")");
}
}
Anwendungsorientierte Programmierung
Folie 117
7.3 Generische Klassen
Verwendung generischer Klassen
– bei der Deklaration von Variablen/Attributen:
der konkrete Typ wird angegeben
Paar<String> paar;
– auch beim Konstruktor wird der konkrete
Datentyp angegeben
paar = new Paar<String>("A", "B" );
– öffentliche Methoden (und Attribute) werden
einfach so benutzt, als ob die Klasse normal deklariert wäre
Anwendungsorientierte Programmierung
Folie 118
7.3 Generische Klassen
Verwenden generischer Klassen
Paar<String> assoz = new Paar<String >(" Tiger " , " Indien");
String s = assoz. getL ( ) :
System .out.println( assoz) ;
Paar<Integer> quad = new Paar<Integer > (
new Integer( 7 ) , new Integer( 49) ) ;
int i = quad.getR( ).intValue( ) ;
Achtung! Es dürfen keine primitiven Datentypen verwendet werden.
(Für primitive Datentypen werden dann die Wrapper-Typen benutzt)
Anwendungsorientierte Programmierung
Folie 119
7.3 Generische Klassen
Basisdatentyp auf Unterklassen einschränken:
public class Paar<T extends Comparable> {…}
Für T sind nur noch Unterklassen von Comparable zulässig
vom Basisdatentyp unabhängige Methode:
public static void paarAusgeben(Paar<?> p) {…}
. . . und eingeschränkt:
public static
void paarVergleich(Paar<? extends Comparable> p) {…}
public static
void methode(Paar<? super Comparable> p) {…}
Anwendungsorientierte Programmierung
Folie 120
7.3 Generische Klassen
statische Methoden mit generischem Parameter:
public static <T> T links(Paar<T> p) { … }
public static <T, S extends T> T test(Paar<T> p, S x) { … }
generische Parameter werden beim Aufruf nicht
angegeben. Sie sind nur bei der Definition relevant
Anwendungsorientierte Programmierung
Folie 121
7.4 Überschreiben von bestimmten Methoden
Sollen die Instanzen einer Klasse verglichen werden, so muss das Interface
Comparable<T> implementiert werden.
Hierzu wird die Methode int compareTo(T to) implementiert.
Diese liefert ein Ergebnis
<0
== 0
>0
falls this < to
falls this == to
falls this > to
Anschließend können dann Felder oder Listen mit Instanzen dieser Klasse mit der
Methode sort() sortiert werden.
Eventuell müssen auch die Methode equals(T to) und hashCode()
überschrieben werden. Diese Methoden können in der IDE unter dem Menüpunkt
Source automatisch generiert und anschließend modifiziert werden
Anwendungsorientierte Programmierung
Folie 122
8 Java-Collections-Framework
In Java gibt es vorgefertigte generische Klassen (in java.util.*) , um Mengen von
Daten zu verwalten. Diese werden als Collections bezeichnet.
Diese Klassen bieten viele Vorteile
– meist wesentlich effizienter als eigene Implementierung
– der Code ist bereits getestet
– das Programm wird lesbarer
daher ist es ratsam, die Collections zu verwenden
generische Interfaces geben die verfügbaren Methoden an
abhängig von der Implementierung werden die Daten unterschiedlich organisiert
Anwendungsorientierte Programmierung
Folie 123
8 Java-Collections-Framework
Interfaces der Collections
List
geordnete Zusammenfassung von Elementen
Duplikate sind erlaubt
Zugriff über Index
Set
unsortierte Menge von Elementen
keine Duplikate erlaubt
Map
Zuordnungen: Elemente  Schlüssel
Schlüssel sind eindeutig
Deque
Einfügen/Entnehmen amAnfang/Ende
z.B. für FIFO/LIFO-Schlangen
Anwendungsorientierte Programmierung
Folie 124
8 Java-Collections-Framework
Das Interface Collection<T>
Alle Klassen des Frameworks implementieren diese Schnittstelle.
Daher sind immer folgenden Methoden vorhanden (Auszug)
boolean add(T e)
fügt ein Elemente hinzu; true, falls e sich einfügen lässt
boolean addAll(Collection <? extends T> c) fügt alle Elemente aus c
hinzu
void clear()
Löscht alle Elemente (optional)
boolean contains(Object o) true, falls o vorhanden
boolean isEmpty()
true, falls der Container leer ist
boolean remove(Object o) Löscht das Objekt o; true falls vorhanden
boolean removeAll(Collection c) Löscht alle in c enthaltenen Elemente
int size()
Liefert die Anzahl der Elemente
Object[] toArray() Speichert alle Elemente in einem Feld
Iterator<T> iterator()
(geerbt von Iterabel) Objekt zum iterieren im
Container
Anwendungsorientierte Programmierung
Folie 125
8 Java-Collections-Framework
Einige Methoden sind optional. Da aber jede Klasse die entsprechende Methode
implementieren muss, wird dieser Fall durch das Auslösen von
UnsupportedOperationException
gelöst. Diese wird auch bei unzulässigen Aktionen ausgelöst.
equals()
Klassen, die in Collections verwendet werden, sollten, durch überschreiben, eine
geeignete Methode equals() implementieren. Viele Methoden wie contains, remove
verwenden diese Methode zum Vergleich.
Anwendungsorientierte Programmierung
Folie 126
8 Java-Collections-Framework
Die Ableitungsstruktur weiterer Interfaces
Interface Iterable
liefert Iterator
Interface Collection
Interface: Queue
Schlangen/FIFO
Interface: List
Interface für
Listen/Sequenzen
Interface: Deque
zweiseitig
Interface: ArrayList
Interface: LinkedList
Anwendungsorientierte Programmierung
Interface: Set
Mengen
Map ist eine weitere Schnittstelle,
die zur Verwaltung von
Assoziationen (Schlüssel,Wert)
verwendet wird
Folie 127
8 Java-Collections-Framework
Implementierungen (Klassen)
List (Listen)
Set (Mengen)
Map
Queue
ArrayList
Liste als Feld
LinkedList
Doppelt verkettete Liste
HashSet
implementiert Menge durch schnelle Hash-Verfahren
TreeSet
Elemente sind sortiert, implementiert Menge als Baum
LinkedHashSet
sortiert, schnelles Hash-Verfahren
HashMap
Assoziationen durch Hash-Verfahren
TreeMap
Assoziationen durch Baum, sortiert
LinkedHashMap
Hash-Verfahren, sortiert
WeekHashMap
Elemente können entfernt werden
LinkedList
s.o.
ArrayBlockingQueue
Blockierenden Warteschlange
PriorityQueue
Prioritätswarteschlange
Anwendungsorientierte Programmierung
Folie 128
8 Java-Collections-Framework
List<T>
zusätzliche Methoden
T get( int index);
wahlfreier lesender Zugriff auf ein Element
T set(int index, T element);
wahlfreier schreibender Zugriff auf ein Element
void add(int index, T element);
fügt ein Element an der Stelle index ein. Die Nachfolger werden verschoben.
T remove(int index)
entfernt das Element an der Stelle index. Die Nachfolger werden nach vorn
verschoben.
List<T> sublist (int fromIndex, int toIndex)
erzeugt eine Teilliste mit den angegebenen Elementen
Anwendungsorientierte Programmierung
Folie 129
8 Java-Collections-Framework
Implementierung
LinkedList<T>
verkette Liste. Wahlfreier Zugriff langsam. Kein Speicher-Overhead.
Konstruktor für eine leere Liste:
public LinkedList<T>();
Wird wie folgt verwendet:
List<Typ> liste = new LinkedList<Typ>();
Konstruktor für mit Elementen vorbelegte Liste:
public LinkedList(Collection<? extends T> c);
ArrayList<T>
Realisierung durch ein Feld. Schneller wahlfreier Zugriff. Speicher-Overhead. Bei
Größenänderung muss evtl. das gesamte Feld umkopiert werden.
Konstruktor für eine leere Liste
List<Typ> liste = new ArrayList<Typ>();
Alle weiteren analog zu LinkedList
Anwendungsorientierte Programmierung
Folie 130
8 Java-Collections-Framework
Set<T>
Gleiche Methoden wie List, aber mit teilweise anderer Semantik, da keine doppelten
Einträge erlaubt sind (z. B. add(T e)).
TreeSet<T>
speichert die Elemente in einer Baumstruktur.
Die Elemente werden in sortierter Reihenfolge abgelegt
HashSet<T>
speichert die Elemente in einer sog. Hash-Tabelle. Dies erfolgt schneller als in
TreeSet, die Elemente sind aber nicht sortiert.
Beim Hash-Verfahren wird die in Object definierte Methode hashCode() benutzt,
um die Speicherstelle zu identifieren.
Anwendungsorientierte Programmierung
Folie 131
8 Java-Collections-Framework
Deque<T>
Datenstruktur für FIFOs, Stapel und Warteschlangen. Effizienter Zugriff auf das
erste und letzte Element in einer Liste. Methoden:
void addLast(T e)
fügt ein Element am Ende ein
T removeLast()
löscht letztes Element und gibt es zurück
T getLast()
gibt letztes Element zurück
void addFirst(T e)
fügt Element am Anfang ein
T removeFirst()
löscht erstes Element und gibt es zurück
T getFirst()
gibt erstes Element zurück
Anwendungsorientierte Programmierung
Folie 132
8 Java-Collections-Framework
Map<K, V>
Methoden des Interfaces Map<K,V>:
V put(K key, V value)
erzeugt eine neue Verknüpfung (und gibt den bisherigen Wert zum Schlüssel
zurück (null bei einer neuen Verknüpfung). Bei value kann es sich um einen
beliebigen (auch komplexen) Datentyp handeln.
V get(Object key)
liefert den Wert zum Schlüssel (null falls keineVerknüpfung vorhanden ist)
boolean containsKey(Object key)
prüft, ob der Schlüssel enthalten ist
Anwendungsorientierte Programmierung
Folie 133
8 Java-Collections-Framework
Methoden von Map (Fortsetzung)
boolean containsValue(Object value)
prüft, ob der Schlüssel enthalten ist
Set<K> keySet()
liefert die Menge der verwendeten Schlüssel
Collection<V> values()
liefert eine Liste mit den verwendeten Werten
Anwendungsorientierte Programmierung
Folie 134
8 Java-Collections-Framework
Implementierungen
HashMap<K, V>
speichert die Elemente in einer sog. Hash-Tabelle. Der Zugriff ist in (fast)
konstanter Zeit möglich. Die Elemente liegen unsortiert vor.
TreeSet<K, V>
speichert die Elemente in einer Baumstruktur. Die Elemente werden in sortierter
Reihenfolge abgelegt. Die Methoden von TreeSet sind meist langsamer als die
von HashMap.
Anwendungsorientierte Programmierung
Folie 135
8 Java-Collections-Framework
Iteratoren
jede Collection hat die Methode
Iterator<T> iterator()
diese liefert ein Objekt, mit dem man alle Elemente in der Collection aufzählen
kann.
Das Iterator-Interface:
boolean hasNext()
liefert true falls noch weitere Elemente vorhanden sind, false sonst.
T next()
Nächstes Element
void remove()
Löscht das zuletzt gelieferte Element
Anwendungsorientierte Programmierung
Folie 136
8 Java-Collections-Framework
Beispiel: Iteratoren
List<String> liste = new LinkedList<String>();
for (int i = 0; i < 5; i++)
liste.add("Elem" + i);
System.out.println(liste); // [Elem0, Elem1, Elem2, Elem3, Elem4]
Iterator<String> it = liste.iterator();
boolean loeschen = false;
while (it.hasNext()) {
if (loeschen)
it.remove();
loeschen = !loeschen;
}
System.out.println(liste);// [Elem0, Elem2, Elem4]
Anwendungsorientierte Programmierung
Folie 137
8 Java-Collections-Framework
Verallgemeinerte ForSchleife
alle Collections-Klassen können auch mit einem impliziten Iterator in der foreachSchleife benutzt werden
Bsp.:
List<String> liste = new LinkedList<String>()
. . .
for ( String s : liste)
System.out.println(s);
Anwendungsorientierte Programmierung
Folie 138
9 Graphische Benutzeroberflächen
Einige Vorbemerkungen
Regel für graphische Benutzeroberflächen (GUI)
Der Aufbau und die Gestaltung soll auf die Bedürfnisse des Benutzers
zugeschnitten sein und nicht den Programmierkenntnissen des Programmierers
entsprechen.
Trennung von GUI und Programmlogik
Hier sollen vor allem die Pakete java.awt und javax.swing benutzt werden
Kennzeichen: objektorientierter Ansatz
– Fenster und Dialogelemente sind Objekte
– Interaktion wird durch Objekte und deren Methoden realisiert
Anwendungsorientierte Programmierung
Folie 139
9 Graphische Benutzeroberflächen
Fenstertypen
• Fenster mit Titelleiste und eventuell Menüleiste (z. B. Das Hauptfenster)
javax.swing.JFrame
• Dialoge für Ausgaben oder Benutzerinteraktionen
javax.swing.JDialog
Diese Fenster können modal sein, d. h. alle weiteren Eingaben sind blockiert bis
des Dialog geschlossen wird
• Fenster ohne Titelleiste
javax.swing.JWindow
• Applets
javax.swing.JApplet
Allen Fenstern kann eine Größe und ein Ursprung (relativ zum übergeordneten
Fenster) zugeordnet werden.
Die Größe kann veränderbar oder fest vorgegeben werden
Fenster und ihre Inhalte werden erst durch setVisible(true) sichtbar.
Anwendungsorientierte Programmierung
Folie 140
9 Graphische Benutzeroberflächen
JFrame
Title (setTitle())
Decorated(setDecorated(true/false)
Größe (setSize(b, h))
Ort (setLocation(x, y)
ContentPane
Anwendungsorientierte Programmierung
Folie 141
9 Graphische Benutzeroberflächen
Benutzung von JFrame
Methoden (Auswahl)
• JFrame(): Erzeugen eines (unsichtbaren) Fensters
• JFrame(String titel) : Fenster mit Titel titel
• setTitle(String titel): Titel ändern
• setResizable(boolean status): Größe veränderbar?
• setVisible(boolean status):
sichtbar (Fenster sind bei der Generierung unsichtbar)
• setDefaultCloseOperation(int operation): Aktion beim Schließen
– WindowConstants.DO_NOTHING_ON_CLOSE: nichts
– JFrame.EXIT_ON_CLOSE: Schließen der Anwendung
• setSize(int b, int h): Größe des Fensters (Breite b, Höhe h)
• setLocation(int x, int y): Position des Fensters
• pack() Größe automatisch einstellen
Anwendungsorientierte Programmierung
Folie 142
9 Graphische Benutzeroberflächen
Anzeigen von Inhalten und Bedienelementen
Die Anzeige erfolgt über sogenannte Widgets. Das sind Klassen, die für eine
bestimmte Anwendung vorgesehen sind. (Auswahl)
– JLabel: reine (meist unveränderte) Textanzeige
– JTextField: Ein- / Ausgabe einer Textzeile
– JTextArea: Ein- / Ausgabe von beliebigem Text (z. B. Editor)
– JButton: Schaltflächen
– JSlider: Schieberegeler
– und viele mehr
Anwendungsorientierte Programmierung
Folie 143
9 Graphische Benutzeroberflächen
Widgets: JLabel
reine (meist unveränderte) Textanzeige
• JLabel( String text ): neues Label erzeugen und mit dem angegeben Text
belegen
• JLabel( String text , int orient ): neues Label mit Orientierung des
Textes
• getText(): liefert den Text
• setText( String text ): ändert den angezeigten Text
Anwendungsorientierte Programmierung
Folie 144
9 Graphische Benutzeroberflächen
Widgets: JTextField / JTextArea
Ein-/Ausgabe von Text
• JTextField (int zeichen): neues Textfeld mit der Breite von zeichen
• JTextField ( String anfangstext , int zeichen): dito mit Text
• getText(): liefert den Text
• setText( String text ): ändert den angezeigten Text
• boolean isEditable (): Ist der Text nutzeränderbar?
• setEditable (boolean status): ändert obige Einstellung
• setHorizontalAlignment (int ausrichtung): Textausrichtung
Anwendungsorientierte Programmierung
Folie 145
9 Graphische Benutzeroberflächen
Widgets: JButton Schaltflächen
• JButton(): erzeugt eine Schaltfläche
• JButton(String text ): dito mit Text
• setText(String s): ändert den Text
• addActionListener ( ActionListener a): zu benachrichtigendes Objekt
bei Nutzerinteraktion (dazu später)
Anwendungsorientierte Programmierung
Folie 146
9 Graphische Benutzeroberflächen
Weitere Widgets
• Checkboxen (JCheckBox)
• Radiobuttons (JRadioButton und ButtonGroup)
• Auswahlliste ( JList )
• Combobox (JComboBox)
• Schieberegler ( JSlider )
• Fortschrittsbalken (JProgressBar)
• Menüleisten (JMenuBar, JMenu, JMenuItem)
• Pop-Up-Men•us (JPopUpMenu)
• Tabellen (JTable und TableModel)
• Baumdarstellungen (JTree und TreeModel)
Anwendungsorientierte Programmierung
Folie 147
9 Graphische Benutzeroberflächen
Die so erstellten Widges können in das Fenster eingefügt werden
• Durch add(Component c) (ab Java 5.0)
• Jedes Fenster hat einen Darstellungsbereich die ContentPane
– getContentPane(): liefert den Darstellungsbereich. Bsp:
Container cp = wnd.getContentPane() // wnd ist von JFrame
//abgeleitet
cp.add(widget)
– setContentPane(Container c): setzt eine neuen Darstellungsbereich
– setBounds(int x, int x, int b, int h): kann das Widget an der
Position x, y mit Größe b, h platziert werden
Anwendungsorientierte Programmierung
Folie 148
9.1 Erstellen von GUIs (Graphical User Interface)
Manuelle Platzierung der Elemente
10, 10
20
80
Anwendungsorientierte Programmierung
public class Application extends JFrame {
JButton okBtn;
JTextField text;
public Application() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container cp = getContentPane();
setSize(100,150);
JPanel panel = new JPanel();
panel.setLayout(null);
text = new JTextField("TEXT");
panel.add(text);
text.setBounds(10, 10, 80, 20);
okBtn = new JButton("ok");
panel.add(okBtn);
okBtn.setBounds(10, 60,80,20);
cp.add(panel);
}
}
Folie 149
9.1 Graphische Benutzeroberflächen
Verwaltung der Widgets JPanel:
Für ein Layout der Komponenten müssen diese gruppiert werden.
• JPanel(): erzeugt einen Container mit Flow-Layout
• JPanel(LayoutManager layout): erzeugt Container mit anderem Layout
• setLayout(LayoutManager): setzt ein Layout
• add(Component): fügt ein Widget hinzu
Anwendungsorientierte Programmierung
Folie 150
9.2 Ereignisbehandlung
Behandlung von Events
• mit addActionListener Objekt zur Ereignisbehandlung anmelden
• Objekt muss Schnittstelle ActionListener implementieren
• genauer: Methode
public void actionPerformed(ActionEvent event)
• drei Ansätze:
– Fenster implementiert ActionListener selbst
– separate Klasse
– eingebettete Klasse
Anwendungsorientierte Programmierung
Folie 151
9.2 Ereignisbehandlung
in actionPerformed(ActionEvent event) kann auf das Ereignis zugegriffen
werden:
– getSource() liefert das Objekt, welches dasEreignis ausgelöst hat
– getActionCommand() liefert z.B. die Zeichenkette, die in der Schaltfläche
steht
– getWhen() liefert einen Zeitstempel
– getModifiers () liefert Information zu zusätzlich gedrückten Tasten (SHIFT
MASK, CTRL MASK,ALT MASK etc.)
Anwendungsorientierte Programmierung
Folie 152
9.2 Ereignisbehandlung
Beispiel: Fenster implementiert ActionListener selbst
import java.awt.event.*; // Basisklassen für Events
import javax.swing.*;
public class InKlasse extends JFrame
implements ActionListener {
public InKlasse() { …
JButton button = new JButton("Text"); //aktives Element
add(button);
button.addActionListener(this); //als Listener anmelden
}
public void actionPerformed(ActionEvent event) {
// Wird aufgerufen falls der Knopf gedrückt wird
}
}
Anwendungsorientierte Programmierung
Folie 153
9.2 Ereignisbehandlung
Der Listener wird durch eine eigene Klasse realisiert (Importe nicht angegeben)
public class MeinListener implements ActionListener {
private EigeneKlasse meinFenster;
MeinListener(EigeneKlasse wnd) { meinFenster = wnd; }
public void actionPerformed(ActionEvent event) {
Object button = event.getSource()
//Zugriff auf button
String text = ((JButton)button).getText()
//da die Quelle durch das Programm bekannt ist,
//ist ein ungeprüfter Typecast zulässig
if (text.equals("Aus") {
((JButton)button).setText("An");
meinFenster.incZaehler();
} else
((JButton)button).setText("Aus");
}
}
}
Anwendungsorientierte Programmierung
Folie 154
9.2 Ereignisbehandlung
Zusammenfügen
public class EigeneKlasse extends JFrame {
privat int zaehler = 0;
public void incZaehler() { zaehler++; }
public EigeneKlasse () {
JButton button = new JButton("Aus"); //aktives Element
add(button); //Hinzufügen zum Fenster
MeinListener action = new MeinListener(this);
//Erstellen einer Behandlung
button.addActionListener(action); //Anmelden an Button
}
}
Anwendungsorientierte Programmierung
Folie 155
9.2 Ereignisbehandlung
Innere Klasse
public class EigeneKlasse extends JFrame {
privat int zaehler = 0;
private JButton button;
public EigeneKlasse () {
button = new JButton("Aus"); //aktives Element
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent event) {
String text = button.getText()
if (text.equals("Aus") {
button.setText("An");
zaehler++;
} else
button.setText("Aus");
}
}
});
}
}
Anwendungsorientierte Programmierung
Folie 156
9.2 Ereignisbehandlung
Weitere Ereignisse
• Ereignisse auf niedriger Ebene (low level events)
– Maustasten und –bewegungen
– Fokus: das Element wird aktiv
– Tastendrücke
– etc.
• Semantische Ereignisse (high level events): Diese werden von GUI-Komponenten
wie Schaltflächen, Rollbalken usw. ausgelöst. Hierbei werden meist Low level
events in semantische Ereignisse umgewandelt. Die Komponente muss hierbei den
Fokus haben, d. h. die Low level events werden zu dieser Komponente geleitet.
Die Behandlung erfolgt ähnlich, daher wird hier keine Unterscheidung gemacht.
Anwendungsorientierte Programmierung
Folie 157
9.3 Verwendung von Layoutmanagern
Jedes Element in Swing besitzt drei Größen
MinimumSize, MaximumSize und PreferredSize
durch getXXX wird die Größe durch ein Objekt der Klasse Dimension
zurückgegeben. Ein Dimension-Objekt hat die öffentlichen Attribute width und
height vom Typ int. Durch setXXX kann die Größe gesetzt werden.
Beachte: die Methode setSize(int widtht, int height) hat, außer auf das Hauptfenster,
keine Auswirkung
FlowLayout
JPanel cp = (JPanel)wnd.getContentPane();
JPanel flaeche = new JPanel();
JTextField tf = new TextField();
tf.setPreferredSize(new Dimension(70,15);
flaeche.add(tf);
JButton btn = new JButton("ok");
tf.setPreferredSize(new Dimension(70,15);
flaeche.add(btn);
pack();
Anwendungsorientierte Programmierung
Folie 158
9.3 Verwendung von Layoutmanagern
Automatisches Layout der Komponenten
• FlowLayout : füllt zeilenweise die Widgets mit Umbruch falls notwendig
• BorderLayout Einteilung in Bereiche
Bereiche WEST, NORTH, EAST, SOUTH,CENTER
bei add muss der Zielbereich angeben werden
sinnvoll für grobe Einteilung auf höchster Fensterebene
• BoxLayout: Die Elemente werden neben- oder übereinander platzieren
Orientierung: X_AXIS, Y_AXIS, LINE AXIS bzw. PAGE AXIS
• GridLayout: regelmäßiges Gitter
• GridBagLayout: Für schwierige Fälle
Anwendungsorientierte Programmierung
Folie 159
9.3 Graphische Benutzeroberflächen
Ein Beispiel
Borderlayout
NORTH
CENTER
EAST
WEST
SOUTH
Jpanel
BoxLayout, Y_AXIS
Jpanel
FlowLayout
Anwendungsorientierte Programmierung
Folie 160
9.3 Ereignisbehandlung
Die Ereignisquellen und ihre Listener (awt)
Listener
Ereignisse
ActionListener
Drücken auf eine Schaltfläche oder <ret> in einem Textfeld
Typ: ActionEvent
WindowListener
Schließen oder Verändern eines Fensters
Typ: WindowEvent
MouseListener
Drücken auf eine Maustaste
Typ: MouseEvent
MouseMotionListener
Bewegung der Maus
Typ: MouseEvent
Anwendungsorientierte Programmierung
Folie 161
9.3 Ereignisbehandlung
Fensterereignisse Schnittstelle: WindowsListener
void windowOpened(WindowEvent event)
Wird aufgerufen, wenn das Fenster geöffnet wird.
void windowClosing(WindowEvent event)
Wird aufgerufen, wenn das Fenster geschlossen wird.
void windowClosed(WindowEvent event)
Wird aufgerufen, wenn das Fenster mit dispose() beendet wird.
void windowIconified(WindowEvent event)
Wird aufgerufen, wenn das Fenster zum Icon verkleinert wird.
void windowDeiconified(WindowEvent event)
Wird aufgerufen, wenn das Fenster wieder vergrößert wird.
void windowActivated(WindowEvent event)
Wird aufgerufen, wenn das Fenster aktiviert wird.
void windowDectivated(WindowEvent event)
Wird aufgerufen, wenn das Fenster deaktiviert wird.
Anwendungsorientierte Programmierung
Folie 162
9.3 Ereignisbehandlung
Da es sich bei WindowListener um eine Schnittstelle handelt, müssen alle
Methoden implementiert werden.
Häufig werden allerdings nur wenige Methoden benutzt, daher müssten alle anderen
mit leeren Rümpfen dennoch mitgeführt werden.
Verwendung von Adapterklassen java.awt.event.WindowAdapter
Diese Klasse implementiert alle Methoden mit leeren Rümpfen
Anwendungsorientierte Programmierung
Folie 163
9.3 Ereignisbehandlung
Verwendung
public class CloseWindow {
public static void main(String[] args) {
JFrame wnd = new JFrame();
wnf.setSize(400, 400);
wnd.setVisible();
wnd.addWindowListener(new CloseWindowAction());
}
}
public class CloseWindowAction extends WindowAdapter {
@Override
public void windowClosing(WindowEvent e) { System.exit(0); }
}
Anwendungsorientierte Programmierung
Folie 164
9.3 Ereignisbehandlung
Verwendung von inneren Klassen
public class CloseWindow extends JFrame{
public CloseWindow()
setSize(400, 400);
addWindowListener(
new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{ System.exit(0); }
}
)
}
public static void main(String[] args) {
new CloseWindow().setVisible(true);
}
}
Anwendungsorientierte Programmierung
Folie 165
9.3 Ereignisbehandlung
Die Ereignisse einer Komponente (JComponent)
Ereignis
Grund
ComponentEvent
Die Komponente wird bewegt, angezeigt, verdeckt oder verschoben
FocusEvent
bekommt oder veliert den Fokus
MouseEvent
Maus betritt oder verlässt den Bereich. Tastendruck, Bewegung
InputMethodEvent
Text- oder Cursor-Veränderung
HirarchieEvent
Änderung der Hierarchie
PropertyChangeEvent
Eine gebundene Eigenschaft ändert sich
ContainerEvent
Hinzufügen oder Löschen von Komponenten (Container)
AncestorEvent
Der Vorgänger wurde verändert
Anwendungsorientierte Programmierung
Folie 166
9.3 Ereignisbehandlung
Auf Tastendrücke reagieren, der KeyListener (Schnittstelle)
Methoden
void keyTyped(KeyEvent e)
Mit e.getKeyChar() kann das eingegebene Zeichen abgefragt werden.
Handelt es sich nicht um ein gültiges Unicode-Zeichen so wird CHAR_UNDEFINED
(65535) zurückgeliefert.
void keyPressed(KeyEvent e)
void keyReleased(KeyEvent e)
Hierdurch können auch Sonderzeichen wie <F1> oder <Entf> abgefragt werden.
Durch e.getKeyCode() wird eine Nummer für die gedrückte Taste zurückgeliefert.
Die Nummern werden als virtueller Code (virtual key code) bezeichnet. Hierfür sind
Konstanten die mit VK_ beginnen definiert. Beispiele:
<F1>
VK_F1
<Entf>
VK_DELETE
Anwendungsorientierte Programmierung
Folie 167
9.3 Ereignisbehandlung
Abschließende Bemerkungen
• Es wurde hier nur ein kleiner Ausschnitt aus den Möglichkeiten für den Aufbau einer
GUI (Graphical user interface) vorgestellt.
• Mit Hilfe der vorhanden Klassen und Schnittstellen lassen sich beliebig komplexe
Oberflächen schreiben.
• Die Oberfläche richtet sich immer nach dem Benutzer
• Der Entwurf und Implementierung einer guten GUI kann sehr zeitaufwendig sein
und ist teilweise gleich oder höher als Entwurf und Codierung der eigentlichen
Programmlogik
Anwendungsorientierte Programmierung
Folie 168
10 Serialisierung
Die Objektzustände können gespeichert werden (persistent)
Das Speichern von Objekten wird als Serialisierung bezeichnet.
Das Wiedderherstellen von Objekten wird als Deserialisierung bezeichnet.
Serialisierung
Die Methode writeObject() schreibt die Objekte in einen Ausgabestrom der
Klasse ObjectOuputStream. Dabei werden die die Zustände und
Objektreferenzen rekursiv in den Ausgabestrom geschrieben. Statische Zustände
werden nicht berücksichticht.
Deserialisierung
Mit der Methode readObject() wird ein Objekt aus einem ObjectInputStream
zur Laufzeit aufgebaut.
Anwendungsorientierte Programmierung
Folie 169
10 Serialisierung
Serialisierung (Schreiben von Objekten)
OutputStream fos = null;
try {
fos = new FileOutputStream(dateiname);
// Der Dateiname sollte die Endung .ser haben
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(object);
} catch (IOException e) { System.err.println(e); }
finally {
try { fos.close(); }
catch {Exception e} { e.printStackTrace(); }
}
Anwendungsorientierte Programmierung
Folie 170
10 Serialisierung
Fehlermeldungen (Exception)
Allgemeine IOException
NotSerializableException: Das Objekt ist nicht serialisierbar.
InvalidClassException: Fehler in der Klassenstruktur
Weiter Methoden von ObjectOutputStream
void flush() throws IOException
Schreibt noch gepufferte Daten
void close() throws IOException
Schließt den Datenstrom. Dieser Aufruf muss erfolgen bevor die Daten wieder
gelesen werden.
Anwendungsorientierte Programmierung
Folie 171
10 Serialisierung
Lesen von Objekten
InputStream ios = null;
try {
fos = new FileOutputStream(dateiname);
// Der Dateiname sollte die Endung .ser haben
ObjectInputStream ois = new ObjectInputStream(ios);
Class class = (Class) ios.readObject(object);
} catch (IOException e) { System.err.println(e); }
finally {
try { ios.close(); }
catch {Exception e} { e.printStackTrace(); }
}
Anwendungsorientierte Programmierung
Folie 172
10 Serialisierung
Eigene Klassen Serialisieren
Die meisten vordefinierten Klassen (z. B. Collection) sind serialisierbar
Damit eine eigen Klasse serialisierbar wird, muss sie die Schnittstelle
Serializiable implementieren
Hierdurch werden alle Attribute auch die der Oberklasse (außer statische) bei einer
Serialisierung geschrieben.
Bei Referenzen auf andere Objekte werden diese ebenfalls serialisiert. Zyklische
Referenzen werden hierbei aufgelöst
Anwendungsorientierte Programmierung
Folie 173
10 Serialisierung
Beispiel
public class TheOne implements Serializable {
private static final long serialVersionUID = 1L;
private int val = 17;
TheOther buddy;
public TheOther getBuddy() { return buddy; }
public void setBuddy(TheOther buddy) { this.buddy = buddy; }
}
public class TheOther implements Serializable{
private static final long serialVersionUID = 2L;
private int val = 127;
TheOne buddy;
public TheOne getBuddy() { return buddy; }
public void setBuddy(TheOne buddy) { this.buddy = buddy; }
}
Anwendungsorientierte Programmierung
Folie 174
Serialisierung
public class Main {
public static void main(String[] args) {
TheOne one = new TheOne();
TheOther other = new TheOther();
one.setBuddy(other);
other.setBuddy(one);
OutputStream fos = null;
ObjectOutputStream oos = null;
try { fos = new FileOutputStream("test.ser");
oos = new ObjectOutputStream(fos);
oos.writeObject(one);
} catch( IOException e ) {
System.out.println(e);
};
try { fos.close(); }catch( IOException e ) {}
}
Anwendungsorientierte Programmierung
Folie 175
10 Serialisierung
Ergibt
¬í sr serializepack.TheOne~tØEoÍÀ
I valL buddyt
Lserializepack/TheOther;xp sr serializepack.TheOther~tØEoÍÀ
buddyt Lserializepack/TheOne;xp •q ~
I valL
Die serialVersionUID (SUID)
Jede serialisierbare Klasse erhält eine Versionsnummer. Diese berechnet sich aus
den Attributen und Methoden der Klasse.
Bei Änderungen an der Klasse ändert sich somit die SUID und das Objekt kann nicht
mehr mit den Daten einer frühren Version geladen werden.
Daher ist es sinnvoll die SUID selbst zu definieren:
private static final long serialVersionUID = WertL;
Der Wert ist beliebig, muss aber ein long (L) sein.
Anwendungsorientierte Programmierung
Folie 176
10 Serialisierung
Gezielte Serialisierung
Ohne weitere Maßnahmen werden alle Attributwerte, auch private, in den
Datenstrom kopiert. Somit können interne Belegungen ausgelesen und manipuliert
werden.
Sollen bestimmte Attribute nicht serialisiert (in den Datenstrom kopiert) werden. So
sind diese mit dem durch das Schlüsselwort transient zu kennzeichnen.
Beispiel
public class Private implements Serializable {
private static final long serialVersionUID = 1L;
private int val = 17;
transient String passwort = "geheim";
}
Anwendungsorientierte Programmierung
Folie 177
10 Serialisierung
Eine weitere Möglichkeit ist die Vorgabe von serialPersistentFields. Diese ist
vom Typ ObjectStreamField[].
public class Private implements Serializable {
private static final long serialVersionUID = 1L;
private static ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[] {
new ObjectStreamField("val", Integer.class),
new ObjectStreamField("benutzername", String.class),
}
private int val = 17;
transient String benutzername = "nicht geheim";
transient String passwort = "geheim";
}
Anwendungsorientierte Programmierung
Folie 178
10 Serialisierung
Die Art der Serialisierung kann auch vorgegeben werden. Hierzu muss/kann eine
Klasse die Methoden:
private synchronized void writeObject(ObjectOutputStream oos)
Schreiben von Werten
private synchronized void readObject(ObjectInputStream oos)
throws IOException, ClassNotFoundException
Lesen von Werten
implementieren. Diese werden dann vom Serialisierer aufgerufen. Soll dennoch der
Standartserialisierer verwendet werden so können die Methoden
private final void defaultWriteObject()
throws IOException
private final void defaultReadObject()
throws IOException, ClassNotFoundException
aufgerufen werden
Anwendungsorientierte Programmierung
Folie 179
10 Serialisierung
Beispiel
public class Private implements Serializable {
private static final long serialVersionUID = 1L;
private int val = 17;
transient String passwort = "bleibt geheim";
private void writeObject(ObjectOutputStream oos)
throws IOException, ClassNotFoundException {
oos.defaultWriteObject(); // Schreibt val
}
private void readObject(ObjectInputStream ios)
throws IOException, ClassNotFoundException {
ios.defaultWriteObject(); // liest val
passwort = "bleibt geheim";
// muss eigentlich in einem tryBlock stehen
}
}
Anwendungsorientierte Programmierung
Folie 180
11 Grafikprogrammierung
Erste Versuche
Wir wollen hier auf ein JPanel (javax.swing.JPanel) zeichnen.
Hierfür wird auch die Klasse Graphics (java.awt.Graphics) aus awt benötigt.
Wird ein JPanel neu gezeichnet so wird die Methode paint aufgerufen. Es sollte
allerdings nicht die Methode sondern die umfassendere paintComponent
überschrieben werden.
protected void paintComponent(Graphics g) {
// Zeichenbefehle
}
Anwendungsorientierte Programmierung
Folie 181
11 Grafikprogrammierung
import java.awt.Graphics;
import javax.swing.*;
public class DrawPanel extends JPanel {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawLine(10, 10, 100, 50);
}
}
public class Main {
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(100, 100);
f.add(new DrawPanel());
f.setVisible(true);
}
}
Anwendungsorientierte Programmierung
Folie 182
11 Grafikprogrammierung
Ein Komponente kann durch Aufruf von repaint() zum Neuzeichnen aufgefordert
werden
void repaint()
void repaint(long tm)
Neuzeichnen nach tm Millisekunden
void repaint(int x, int y, int width, int height)
Neuzeichnen im angegeben Bereich
void repaint(long tm, int x, int y, int width, int height)
alles zusammen
Anwendungsorientierte Programmierung
Folie 183
11 Grafikprogrammierung
Erweiterung der Zeichenfähigkeiten
Die Klasse Graphics wurde in der JDK 1.2 eingeführt. Inzwischen wurde die
Graphik erweitert. Die Methoden befinden sich in der Unterklasse Graphics2D von
Graphics.
Daher sollte diese verwendet werden
protected void paintComponent(Graphics g) {
Graphics2D g2D = (Graphics2D)g; // Type-Cast
…
}
Anwendungsorientierte Programmierung
Folie 184
11 Grafikprogrammierung
Der Nullpunkt
Einfache Zeichenroutinen
abstract void drawLine(int xa, int ya, int xe, int ye)
zeichnet eine Linie zwischen den Punkten (xa, ya) und (xe, ye).
Anwendungsorientierte Programmierung
Folie 185
11 Grafikprogrammierung
Grundgerüst für eine Zeichenfläche
public class PaintPanel extends JPanel {
public PaintPanel() {
this.setBackground(Color.WHITE); // Setzen des Hintergrundes
}
// Die eigentliche Methode zum Zeichnen
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.BLACK); // Setzen der Zeichenfarbe
// Zeichenroutinen
}
}
Anwendungsorientierte Programmierung
Folie 186
11 Grafikprogrammierung
Einbinden der Zeichenfläche
public class CanvasGUI extends JFrame {
privatePaintPanel canvas = new PaintPanel();
public CanvasGUI() {
Container p = this.getContentPane();
p.add(canvas);
}
}
Anwendungsorientierte Programmierung
Folie 187
11 Grafikprogrammierung
Rechtecke
void drawRect(int x, int y, int width, int height)
Zeichnet ein Rechteck. Das Rechteck ist width+1 Pixel breit und height+1Pixel
hoch.
void fillRect(int x, int y, int width, int height)
Zeichnet ein gefülltes Rechteck. Das Rechteck ist width Pixel breit und height Pixel
hoch.
void drawRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight)
Zeichnet ein Rechteck mit gerundeten Ecken. Das Rechteck ist width+1 Pixel breit
und height+1Pixel hoch. Durch arcWidth und arcHeight wird der Durchmesser der
Kreisbögen angegeben
void fillRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight)
gefülltes Rechteck mit runden Ecken.
Anwendungsorientierte Programmierung
Folie 188
11 Grafikprogrammierung
Kreise, Ellipsen, Bögen
(x, y)
drawOval(int x, int y, int width, int height)
zeichnet eine Ellipse innerhalb eines gedachten
Rechtecks mit der Breite widthund der Höhe height
fillOval(int x, int y, int width, int height)
wie oben aber gefüllt
height
width
drawArc(int x, int y, int w, int h, int start, int winkel)
zeichnet eine Bogen
winkel
fillArc(…) gefüllt, sonst wie oben
0°
start (negativ)
Anwendungsorientierte Programmierung
Folie 189
11 Grafikprogrammierung
Text
Ein Fond erzeugen
Font(String fontname, int style, int size)
style: Font.PLAIN, Font.BOLD, Font.ITALIC
oder zusammengesetzt Font.BOLD | Font.ITALIC
size: Größe in Pixeln
Bsp:
Font f = new Font("Arial", Font.PLAIN, 14)
Font getFont(), setFont(Font f) liefert bzw. setzt den Font in der aktuellen
Graphikumgebung
Mit deriveFont(attribut) kann aus einem bestehenden Font ein Neuer mit anderen
Attributen (Größe, Stil ) erzeugt werden. Die Größe muss als float angegeben
werden. Bsp
Font f20 = f.deriveFont(20f)
Anwendungsorientierte Programmierung
Folie 190
11 Grafikprogrammierung
Das Zeichnen von Text erfolgt durch
void drawString(String s, int x, int y)
Bsp.
drawString("String", 50, 50);
50
In der Klasse FontMetrics sind verschiedene
Information über den aktuellen Font gespeichert
Bsp.: (g ist vom Typ Graphics)
FontMetrics fm = g.getFontMetrics()
FontMetrics fm = g.getFontMetrics(Font)
Die Breite des gezeichneten Strings kann durch
int drawWidth = fm.stringWidth("String");
ermittelt werden
Anwendungsorientierte Programmierung
50
String
Folie 191
11 Grafikprogrammierung
Festlegung der Linieart
Anwendungsorientierte Programmierung
Folie 192
Viel Spaß bei der weiteren Erkundung von Java
Anwendungsorientierte Programmierung
Herunterladen