Algorithmik 1 - Friedrich-Alexander-Universität Erlangen

Werbung
Organisatorisches
ƒ Regelung um die Weihnachtspause
y Freitag 24.12. sind keine Übungen
y Ab Montag, 10.1. wieder regulärer Übungs- und Vorlesungsbetrieb
Algorithmik 1
Prof. Dr. Michael Philippsen / Prof. Dr. Herbert Stoyan
Friedrich-Alexander-Universität
Erlangen-Nürnberg
Informatik 2/8
Programmiersysteme /
Künstliche Intelligenz
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-2
M. Philippsen / H. Stoyan
Kapitel 7 - Java-Details
7.1 Codier-Regeln für Java
7.1
7.2
7.3
7.4
7.5
ƒ Wenn Sie wirklich wollen, dann könnten Sie ihre Programme
schreiben, ohne jemals die Return-Taste zu drücken.
ƒ Die Anordnung in Zeilen ist nur für den menschlichen Leser.
ƒ Ebenso ist das Einrücken aus Sicht der Übersetzers völlig unnötig.
Es dient lediglich dem besseren Verständnis, weil man auf einen
Blick erkennt, wo z.B. eine Schleife beendet ist.
Codier-Regeln für Java
Vererbung am Beispiel
Graphische Oberfläche
Unter der Lupe
Was geht schief?
Æ Derartige Regeln heißen Codier-Regeln.
In diesem Abschnitt besprechen wir übliche Codier-Regeln für Java.
Bitte einhalten!
Handy aus!
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-3
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-4
7.1 Codier-Regeln für Java
7.1 Codier-Regeln für Java
Mehr Motivation
Codier-Regeln für Dateinamen
ƒ Im Durchschnitt fallen 80% der Kosten eines Programms während
der Wartung an.
ƒ Kaum ein Programm wird über seine ganze Lebensdauer vom
ursprünglichen Autor betreut.
ƒ Codier-Regeln verbessern die Lesbarkeit von Software; neuer Code
ist leichter zu begreifen; die Kosten der Wartung werden gesenkt.
ƒ Quellcode-Dateien haben den Suffix .java
ƒ ByteCode-Dateien haben den Suffix .class
Friedrich-Alexander-Universität Erlangen-Nürnberg
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-5
M. Philippsen
M. Philippsen
ƒ Maximal eine öffentliche Klasse pro Quelldatei. Ist eine öffentliche
Klasse namens X im Quellcode, dann muss die Quellcode-Datei
X.java heißen.
Algorithmik 1, WS 2004/05, Folie 7-6
M. Philippsen
7.1 Codier-Regeln für Java
7.1 Codier-Regeln für Java
Codier-Regeln für Programmdateien
Codier-Regeln für class und interface Deklarationen
ƒ
ƒ
ƒ
Mehr als 2.000 Zeilen sollte keine Programmdatei lang sein
Leerzeilen zur optischen Trennung
Generelle Struktur jeder Programmdatei
1. Anfangskommentar
ƒ
Generelle Struktur jeder class und interface Deklaration
1. externer Kommentar /** … */
2. class … { oder interface … {
3. interner Kommentar
4. statische Variablen
in der Reihenfolge public, protected, (package), private
/*
* Klassenname
*
* Versionsangabe
*
* Datum
*
* Copyright-Angabe, Autoren
*/
5. Instanzvariablen
in der Reihenfolge public, protected, (package), private
6. Konstruktoren
7. Methoden
nach Funktionalität gruppiert
unabhängig von der Sichtbarkeit
2. package und import-Anweisung
3. class und interface Deklarationen
Friedrich-Alexander-Universität Erlangen-Nürnberg
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-7
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-8
7.1 Codier-Regeln für Java
7.1 Codier-Regeln für Java
Programmzeilenformatierung (1)
Programmzeilenformatierung (2)
ƒ Einrückungen sollten in 4er-Schritten erfolgen
ƒ Keine Zeile sollten mehr als 80 Zeichen enthalten,
Kommentarzeilen nicht mehr als 70 Zeichen
ƒ Wenn die Zeile zu lang wird, möglichst an folgenden Stellen
umbrechen:
y nach einem Komma
int a,| b
y vor einem Operator
47 |+ 11
y möglichst gemäß der Bindungsstärke
ƒ Die Folgezeile wird so weit eingerückt, wie der Ausdruck „auf gleicher
Schachtelungsebene“ in der vorhergehenden Zeile.
ƒ Wenn zu tief eingerückt würde, dann einen 8er-Schritt gegenüber der
vorherigen Zeile einrücken.
M. Philippsen
someMethod1(longExpression1, longExpression2, longExpression3,
longExpression4);
var = someMethod(longExpression1,
someMethod2(longExpression2,
longExpression3));
longName1 = longName2 * (longName3 + longName4 - longName5)
+ 4 * longName6;
//obige Formatierung ist besser als:
longName1 = longName2 * (longName3 + longName4
- longName5) + 4 * longName6;
Leerzeichen zwischen Operator und Operanden
Friedrich-Alexander-Universität Erlangen-Nürnberg
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-9
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-10
7.1 Codier-Regeln für Java
7.1 Codier-Regeln für Java
Programmzeilenformatierung (3)
Programmzeilenformatierung (4)
//übliche Formatierung:
someMethod(int anArg, Object anotherArg, String yetAnotherArg,
Object andStillAnother) {
...
}
//wenn zu tief
private static
Object
Object
...
}
eingrückt werden würde
synchronized veryLongMethodName(int anArg,
anotherArg, String yetAnotherArg,
andStillAnotherArg) {
mit „normaler“ Einrückregel,
würde es in Folgezeile hier
weitergehen.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-11
M. Philippsen
ƒ Werden Bedingungen von if-Anweisungen zu lang, stets mindestens
8 Schritte einrücken
//schlechte Formatierung:
if ((condition1 && condition2)
|| (condition3 && condition4)
||!(condition5 && condition6)) {
doSomethingAboutIt();
}
//Verwenden Drucker o.
//Terminal falsche
//Zeilenlänge, dann ist
//Rumpf leicht zu
//übersehen!
//besser:
if ((condition1 && condition2)
|| (condition3 && condition4)
||!(condition5 && condition6)) {
doSomethingAboutIt();
}
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-12
M. Philippsen
7.1 Codier-Regeln für Java
Programmzeilenformatierung (5)
ƒ Formatierung des Fragezeichen-Operators:
7.1 Codier-Regeln für Java
Bedingung wahr? dann
erster Ausdruck : sonst
zweiter Ausdruck.
Kommentare
ƒ In Java unterscheidet man zwischen Kommentaren zur
Implementierung und Kommentaren zur Dokumentation.
y Implementierungskommentare werden mit // oder /*…*/ geschrieben.
Bedingung in Klammern
à Beschreiben Implementierungsgedanken
à Vor-/Nachbedingungen, Invarianten
à Auskommentieren von Code, der nicht mehr gebraucht wird
//je nach Geschmack:
alpha = (aLongBooleanExpression) ? (int) beta : gamma++;
alpha = (aLongBooleanExpression) ? (int) beta
: gamma++;
alpha = (aLongBooleanExpression)
? (int) beta
: gamma++;
Leerzeichen nach expliziter Typwandlung
Nie Leerzeichen bei unären Operatoren
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-13
y Dokumentationskommentare werden durch /**…*/ gekennzeichnet.
à Beschreibung für Entwickler, die die Klasse benutzen wollen.
à Funktionsweise, Bedeutung der Argumente von Methoden, …
y Das Werkzeug javadoc kann Dokumentationskommentare extrahieren
und html-Seiten generieren, wie Sie diese aus der Dokumentation der
Standard-Bibliotheken kennen.
ƒ Redundante Kommentare vermeiden
ƒ Daumenregel: Wenn ein Programmstück so trickreich ist, dass man
als Programmierer einen Implementierungskommentar als unbedingt
notwendig betrachtet, dann besser den Code klarer schreiben!
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-14
M. Philippsen
7.1 Codier-Regeln für Java
7.1 Codier-Regeln für Java
Dokumentationskommentar am Beispiel (1)
Dokumentationskommentar am Beispiel (2)
/**
* Returns an Image object that can then be painted
* on the screen.
* <p>
* The name argument is a specifier that …
*
* @param url an absolute URL giving the base location
*
name the location of the image, relative to url
* @return the image at the specified URL
* @see
Image
*/
public Image getImage(URL url, String name) {
try {
return getImage(new URL(url, name));
} catch (MalformedURLException e) {
return null;
}
}
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-15
getImage
public Image getImage(URL url,
String name)
Returns an Image object that can then be painted on the screen.
The argument is a specifier that …
Parameters:
url - an absolute URL giving the base location
name - the location of the image, relative to url
Returns:
the image at the specified URL
See Also:
Image
Mehr Informationen unter: http://java.sun.com/j2se/javadoc/
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-16
7.1 Codier-Regeln für Java
7.1 Codier-Regeln für Java
Deklarationen (1)
Deklarationen (2)
ƒ Eine Deklaration pro Zeile, vermeide Komma-Form (int a,b;)
ƒ Initialisierung möglichst unmittelbar an der Deklarationsstelle
ƒ Deklarationen am Anfang eines Blocks {…}, also nicht warten, bis die
Variable benötigt wird. Nur Laufvariablen von for-Schleifen werden
nicht an den Anfang des umgebenden Blocks gezogen.
ƒ In der Klassendeklaration Leerzeichen vor {
Beispiel: class Sample extends Object {
Leerzeichen
ohne Leerzeichen
class Sample extende Object {
int ivar;
int ivar2;
Sample(int i, int j) {
ivar = i;
ivar = j;
}
ƒ Leerzeichen bei Methodendeklaration gemäß
foo(int i, int j) {
ƒ } immer in einer eigenen Zeile, so weit eingerückt wie Eröffnung.
ƒ Leerzeile zwischen 2 Methodendeklarationen
M. Philippsen
int emptyMethod() {}
...
}
} in eigener Zeile,
eingerückt wie class
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-17
Leerzeichen
Leerzeile
} in eigener Zeile,
eingerückt wie Sample
Leerzeile
ausnahmesweise } in
gleicher Zeile
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-18
M. Philippsen
7.1 Codier-Regeln für Java
7.1 Codier-Regeln für Java
Anweisungen (1)
Anweisungen (2)
ƒ Nur eine Anweisung pro Zeile
ƒ { steht am Ende der Zeile derjenigen Anweisung, die Block öffnet
ƒ return: Rückgabewert
if (condition) {
statements;
nicht in Klammern ()
}
ƒ if-Anweisungen:
if (condition) {
Stets {} verwenden, auch
statements;
wenn nur eine Anweisung } else {
statements;
in einem Zweig ist.
ƒ Schleifen:
}
if (condition) {
statements;
} else if (condition) {
statements;
} else {
statements;
}
for (initialization; condition; update) {
statements;
}
Leerzeichen
//leere Schleife:
for (initialization; condition; update);
while (condition) {
statements;
}
do {
statements;
} while (condition);
Leerzeichen zwischen Schlüsselwort und (
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-19
Nicht mehr als 3 Variablen
gleichzeitig verändern.
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-20
7.1 Codier-Regeln für Java
7.1 Codier-Regeln für Java
Anweisungen (3)
Anweisungen (4)
ƒ switch-Anweisung:
switch (condition) {
case ABC:
statements;
/* fällt durch */
case DEF:
statements;
break;
case XYZ:
statements;
break;
default:
statements;
break;
}
Kommentar, wenn wirklich
„Durchrauschen“ in den
nächsten Fall beabsichtigt
ist. Dann keine Leerzeile.
Leerzeile zwischen
zwei Fällen.
ƒ try-Anweisung:
try {
statements;
} catch (ExceptionClass e) {
statements;
} finally {
statements;
}
ggf. ohne finally.
default-Fall
immer vorsehen.
Redundantes break
schützt, bei nachträglich
ergänzten neuen Fällen.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-21
M. Philippsen
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-22
M. Philippsen
7.1 Codier-Regeln für Java
7.1 Codier-Regeln für Java
Namensgebung (1)
Namensgebung (2)
ƒ Alle Namen sollten so gewählt werden, dass sie schon beim Lesen
erklären, was sie bedeuten und welche Funktion sie im Programm
haben. Solche Namen heißen mnemonische Namen.
ƒ Klassennamen und Schnittstellennamen sollten Substantive sein und
mit einem Großbuchstaben beginnen. Bei zusammengesetzten
Substantiven beginnt jedes neue Wort wieder mit einem
Großbuchstaben.
Beispiele: class Rational, class BibliotheksBenutzer
ƒ Methodennamen sind Verben und beginnen mit einem
Kleinbuchstaben. Bei zusammengesetzten Verben beginnt jedes
neue Wort mit einem Großbuchstaben.
Beispiele: run(), runFast()
ƒ Variablennamen fangen mit Kleinbuchstaben an (weder _ noch $).
Bei zusammengesetzten Substantiven beginnt jedes neue Wort
wieder mit einem Großbuchstaben.
ƒ Namen konstanter Werte nutzen ausschließlich Großbuchstaben.
Bei Zusammensetzung _ zur Worttrennung verwenden.
Beispiele: MIN_WIDTH, MAX_LENGTH
y Keine winzigen, erst recht keine einbuchstabigen Namen verwenden
y Ausnahmen:
à Laufvariablen von Schleifen (typisch: i, j, k)
à temporäre „Wegwerf“-Variablen, die nur an einer Stelle benutzt werden, z.B.
um die Werte zweier Variable zu vertauschen.
ƒ Paketnamen sollten nur aus Kleinbuchstaben bestehen. Dabei nimmt
man üblicherwiese „seine“ Domain rückwärts als Präfix:
Beispiel: de.uni-erlangen.informatik.i2.algo1
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-23
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-24
M. Philippsen
7.1 Codier-Regeln für Java
7.1 Codier-Regeln für Java
Code-Klarheit (1)
Code-Klarheit (2)
ƒ Instanzvariablen sollten nur mit wirklich gutem Grund öffentlich
zugänglich sein. Lieber set() und get() Methoden verwenden, die
den Wert der Instanzvariablen setzen bzw. zurückliefern.
ƒ Niemals ein Objekt verwenden, um (statische) Klassenvariablen oder
(statische) Klassenmethode aufzurufen. Lieber Klassenname.name
ƒ Konstante Werte sollten (fast) nie explizit als Literale im Code stehen.
Stattdessen Konstante mit Namen deklarieren und den Namen im
Code nutzen.
ƒ Keine Kettenzuweisungen machen:
a = b = c;
ƒ Im Zweifel zu viel Klammern
if (a == b && c == d)
Lieber:
if ((a == b) && (c == d))
Nicht jedem Leser des Programms sind die Präzedenzregeln klar.
ƒ Keine Zuweisung verwenden, wo sie mit einer Vergleichsoperation
verwechselt werden kann:
if (a = d) { …
Lieber: if ((a = d) == true) { …
ƒ Auf eingebettete Zuweisungen verzichten
d = (a = b + c) + r
Friedrich-Alexander-Universität Erlangen-Nürnberg
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-25
M. Philippsen
7.2 Vererbung am Beispiel
Algorithmik 1, WS 2004/05, Folie 7-26
M. Philippsen
7.2 Vererbung am Beispiel
Festkörper
Festkörperbeispiel (1)
Festkörperbeispiel (2)
Quader
Kugel
Quader
Zylinder
mit abstrakter Klasse:
public abstract class Festkoerper {
public final static float PI = 3.1415926;
public abstract double oberflaeche();
public abstract double volumen();
}
ƒ Quader:
oder mit Interface:
public interface Festkoerper {
public final static float PI = 3.1415926;
public double oberflaeche();
public double volumen();
}
Beides ist
sinnvoll, weil
die Klasse nur
abstrakte
Methoden und
Konstanten
deklariert.
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
7.2 Vererbung am Beispiel
Quader
Zylinder Radius,
Höhe
2·π·Radius·
π·Radius²·Höhe
(Radius + Höhe)
Kugel
4·π·Radius²
Radius
4/3·π·Radius3
public class Quader implements Festkoerper {
private double laenge, breite, hoehe;
public double oberflaeche() {
return 2 * (laenge * breite + laenge * hoehe
+ breite * hoehe);
}
public double volumen() {
return laenge * breite * hoehe;
}
...}
Algorithmik 1, WS 2004/05, Folie 7-28
M. Philippsen
Festkörperbeispiel (4)
Zustand Oberfläche
Volumen
Länge,
Breite,
Höhe
Länge·Breite·Höhe
Radius
2·(Länge·Breite
+ Länge·Höhe +
Breite·Höhe)
Quader
2·π·Radius·
π·Radius²·Höhe
(Radius + Höhe)
4·π·Radius²
4/3·π·Radius3
ƒ Zylinder:
Zustand Oberfläche
Volumen
Länge,
Breite,
Höhe
Länge·Breite·Höhe
2·(Länge·Breite
+ Länge·Höhe +
Breite·Höhe)
Zylinder Radius,
Höhe
2·π·Radius·
π·Radius²·Höhe
(Radius + Höhe)
Kugel
4·π·Radius²
Radius
4/3·π·Radius3
ƒ Kugel:
public class Zylinder implements Festkoerper {
private double radius, hoehe;
public double volumen() {
return PI * radius * radius * hoehe;
}
public double oberflaeche() {
return 2 * PI * radius * (radius + hoehe);
}
...}
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-29
Länge·Breite·Höhe
2·(Länge·Breite
+ Länge·Höhe +
Breite·Höhe)
7.2 Vererbung am Beispiel
Zylinder Radius,
Höhe
Kugel
Volumen
Länge,
Breite,
Höhe
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-27
Festkörperbeispiel (3)
Zustand Oberfläche
public class Kugel implements Festkoerper {
private double radius;
public double volumen() {
return 4.0/3.0 * PI * radius * radius * radius;
}
public double oberflaeche() {
return 4 * PI * radius * radius;
}
...}
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-30
M. Philippsen
7.2 Vererbung am Beispiel
Festkörperbeispiel (5)
Festkoerper f = new Kugel();
System.out.println(f.volumen());
f = new Zylinder();
System.out.println(f.volumen());
7.2 Vererbung am Beispiel
Variable vom Typ einer
Schnittstelle (oder einer
abstrakten Klasse). Jede
Instanz muss die
Methoden der Schnittstelle
implementieren.
Abhängig vom dynamischen
Typ des Objekts (von welchem
Typ ist f zur Laufzeit?) wird
die zugehörige konkrete
Implementierung aufgerufen.
interface BaseColors {
int RED
= 1;
int GREEN = 2;
int BLUE = 4;
}
interface RainbowColors
extends BaseColors {
int YELLOW = 3;
int ORANGE = 5;
int INDIGO = 6;
int VIOLET = 7;
}
bei statischen
Methoden und
Instanzvariablen
gelten andere
Regeln
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-31
Mehrfachvererbung
eingeschränkt auch
in Java
interface PrintColors
extends BaseColors {
int YELLOW = 8;
int CYAN
= 16;
int MAGENTA = 32;
}
interface LotsOfColors
extends RainbowColors,
PrintColors {
int FUCHSIA = 17; …
}
OK, solange nicht auf
YELLOW zugegriffen wird.
Fehler auch wenn jeder
Pfad YELLOW auf den
selben Wert setzen würde
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-32
M. Philippsen
7.2 Vererbung am Beispiel
7.3 Graphische Oberfläche
Festkörperbeispiel (6)
ƒ SWING erlaubt das Gestalten von graphischen Benutzeroberflächen
mit Knöpfen, Menüs, Schiebereglern usw. in einer
plattformunabhängigen Weise für MS Windows/NT, MacOS, Solaris,
Linux, u.a.
ƒ Das Erscheinungsbild wird an die jeweilige Plattform angepasst.
ƒ Wir benutzen die Komponenten aus der SWING-Bibliothek (z. B.
JButton), nicht die Komponenten aus der AWT-Bibliothek (also
nicht Button), müssen aber auch auf Klassen in der AWTBibliothek (z. B. GridBagLayout) zurückgreifen.
public class Kugel implements Festkoerper, LotsOfColors {
...
int color = RED; //alles ok
Kugel(int color) {
if ((color < MIN_COLOR) || (color > MAX_COLOR)) {
this.color = YELLOW; //Fehler zur Übersetzungszeit
} else {
this.color = color;
}
}
}
ƒ Plan für das Lernen der Grundkonzepte:
y Welche einfachen graphischen Interaktionskomponenten gibt es?
y Wie werden sie auf dem Bildschirm angezeigt und angeordnet?
y Wie reagieren sie auf Eingaben und Benutzung?
Friedrich-Alexander-Universität Erlangen-Nürnberg
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-34
7.3 Graphische Oberfläche
7.3 Graphische Oberfläche
Interaktionskomponenten (2)
M. Philippsen
Interaktionskomponenten (1)
Algorithmik 1, WS 2004/05, Folie 7-33
JButton
Knopf, Schaltfläche
JCheckBox Ankreuzfeld
JFrame
Rahmen mit Titelbalken etc.
JLabel
Beschriftung
JList
Auswahlliste
JPanel
M. Philippsen
JRadioButton Umschaltknopf
ButtonGroup
Mehrere
Knöpfe, von
denen nur
einer gedrückt
ist
JScrollbar
Verschiebebalken
JSlider
Schieberegler
JTextField
JTextArea
Editierbares
einzeiliges
bzw.
mehrzeiliges
Textfeld
Behälter zum Gruppieren und
Anordnen v. Komponenten
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-35
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-36
M. Philippsen
7.3 Graphische Oberfläche
7.3 Graphische Oberfläche
Gedanklicher Aufbau eines Fensters:
Aufbau eines Fensters in der Datenstruktur:
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-37
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
7.3 Graphische Oberfläche
Algorithmik 1, WS 2004/05, Folie 7-38
7.3 Graphische Benutzeroberfläche
Das erste Swing-Programm (2)
Das erste Swing-Programm (1)
ƒ Funktionalität wird in Objekten gekapselt
Hier: beim Schließen des Fensters soll sich das Programm beenden
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class MyCloser extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
public class RahmenMitKnopf {
public static void main (String args[]) {
JFrame r = new JFrame("RahmenMitKnopf");
Separate Klassendefinition für jedes mögliche Ereignis
ist lästig. "Anonyme innere Klassen" helfen, s.u.
Komponenten, die später in den Rahmen eingefügt werden, werden
i.A. zeilenweise von links nach rechts im Fenster angeordnet.
Rahmengröße richtet sich nach Größe der Komponenten
JButton k = new JButton("Knoepfle");
k.SetToolTipText("tut nichts"); //Hinweistext
r.getContentPane().add(k);
Friedrich-Alexander-Universität Erlangen-Nürnberg
...
JFrame r = new JFrame("RahmenMitKnopf");
r.addWindowListener(new MyCloser());
...
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Wenn der Rahmen
das Ereignis
windowClosing
sieht, dann wird die
entspr. Methode des
Objekts myCloser
aufgerufen.
Algorithmik 1, WS 2004/05, Folie 7-40
M. Philippsen
7.3 Graphische Oberfläche
7.3 Graphische Oberfläche
Das erste Swing-Programm (3)
Algorithmik 1, WS 2004/05, Folie 7-39
M. Philippsen
ƒ Die Lage der Komponenten im Fenster wird nur relativ spezifiziert.
Ändert sich die Größe des Fensters, wird diese Größenänderung an
alle Komponenten des Fensters weitergegeben.
ƒ Bisher: Fließplatzierer („FlowLayout“): Komponenten werden
nacheinander von links nach rechts im Fenster angezeigt.
add(e), add(e,i), remove(e), remove(i),
removeAll()…
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class RahmenMitKnopf {
public static void main (String args[]) {
JFrame r = new JFrame("RahmenMitKnopf");
r.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//Anonyme Innere Klasse!
JButton k = new JButton("Knoepfle");
k.setToolTipText("tut nichts"); //Hinweistext
r.getContentPane().add(k);
r.pack();
r.setVisible(true);
}
}
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-41
ƒ Weitere Platzierer:
y
y
y
y
Gitteranordnung (2D-Raster):
Einfassungsanordnung:
Schachtelanordnung:
Variable Rasteranordnung:
GridLayout
BorderLayout
BoxLayout
GridBagLayout
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-42
M. Philippsen
7.3 Graphische Oberfläche
7.3 Graphische Oberfläche
Gitteranordnung, GridLayout (1)
Gitteranordnung, GridLayout (2)
ƒ Einer der Konstruktoren: GridLayout(int zeilen, int spalten)
Dieser legt ein Gitter mit der angegebenen Zeilen-/Spaltenzahl an.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Gitteranordnung{
public static void main(String[] args) {
JFrame r = new JFrame("Gitter - Anordnung");
JPanel p = new JPanel(new GridLayout(2,3));
p.add(new JButton("Knopf1"));
p.add(new JButton("Knopf2"));
p.add(new JButton("3"));
p.add(new JButton("Knopf mit langem Text"));
p.add(new JButton("Knopf5"));
r.getContentPane().add(p);
r.pack();
r.setVisible(true);
}
}
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-43
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-44
7.3 Graphische Oberfläche
7.3 Graphische Oberfläche
Einfassungsanordnung, BorderLayout (1)
Einfassungsanordnung, BorderLayout (2)
ƒ maximal 5 Komponenten werden angeordnet: in der Mitte und in jeder der
vier Himmelsrichtungen.
class Einfassung {
public static void main( String[] args ) {
JFrame f = new JFrame("Gitter - Anordnung");
JPanel p = new JPanel(new BorderLayout());
f.getContentPane().add(p);
JButton b = new JButton("Norden");
p.add(b, BorderLayout.NORTH);
b = new JButton("Sueden");
p.add(b, BorderLayout.SOUTH);
b = new JButton("Westen");
p.add(b, BorderLayout.WEST);
b = new JButton("Osten");
p.add(b, BorderLayout.EAST);
b = new JButton("Mitte");
p.add(b, BorderLayout.CENTER);
f.pack();
f.setVisible( true );
}
}
Friedrich-Alexander-Universität
Erlangen-Nürnberg
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-45
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-46
7.3 Graphische Oberfläche
7.3 Graphische Oberfläche
Schachtelanordnung, BoxLayout
Variable Rasteranordnung, GridBagLayout
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-47
M. Philippsen
M. Philippsen
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-48
M. Philippsen
7.4 Unter der Lupe
7.4 Unter der Lupe
Anweisungen mit Label:
Statischer Initialisierer
ƒ Blockanfänge können mit Namen versehen werden. Namen heißen „Label“
ƒ Zusätzlich zur Initialisierung statischer Variablen kann man einen
statischen Initialisierer programmieren.
ƒ Der enthaltene Code wird ausgeführt, sobald die Klasse in die JVM
geladen wird.
ƒ Statische Initialisierer und Initialisierungs-Code für statische
Variablen werden in textueller Ordnung ausgeführt.
outer: for (int row = 0; row < numRows; row++) {
for (int col = 0; col < numCols; col++) {
...
break outer;//beendet äußere for-Schleife
}
}
for (int i=0; i < myArray.length; i++) {
if (myArray[i] == null) {
continue; //überspringt Rest der Schleife
//startet nächste Iteration
}
myArray[i].myMethod()
}
ƒ break verlässt die per Label genannte Schleife, continue startet eine
neue Iteration dieser Schleife. Ohne Label ist die jeweils direkt umgebende
Schleife betroffen.
Friedrich-Alexander-Universität Erlangen-Nürnberg
class Test {
static int MAGIC;
static {
MAGIC = 4711;
}
}
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-49
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-50
M. Philippsen
7.4 Unter der Lupe
7.4 Unter der Lupe
Initialisierungsreihenfolge (1)
Initialisierungsreihenfolge (2)
ƒ Auch wenn alle Instanzvariablen sichtbar sind (also nicht erst in späteren
Blöcken deklariert werden), kann ihre Verwendung dennoch unzulässig sein
ƒ Folge der Abarbeitung in textueller Reihenfolge
class Test {
int i = j;
int j = 1;
}
unzulässiger Vorwärtsverweis
ƒ Vorwärtsreferenzen sind innerhalb von Variableninitialisierern von Instanzoder Klassenvariablen und innerhalb von statischen Initialisierern
unzulässig.
class Test {
Test() { k = 2; }
int j = 1;
int i = j;
int k;
}
class Test {
static int peek() { return j; }
static int i = peek();
static int j = 1;
public static void main (String[] args) {
System.out.println(i+", "+j);
}
}
Ausgegeben wird 0,1, weil zum Zeitpunkt
der Initialisierung von i auf das dann noch
mit seinem default-Wert initialisierte j
zugegriffen wird. Erst später wird j durch
seinen Initialisierer auf 1 gesetzt.
OK, da Vorwärtsverweis nicht
innerhalb der Initialisierer
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-51
OK
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-52
M. Philippsen
7.4 Unter der Lupe
7.4 Unter der Lupe
Initialisierungsreihenfolge (3)
Initialisierungsreihenfolge (4)
ƒ Lokale Variablen müssen definitiv vor ihrer lesenden Benutzung mit einem
Wert beschrieben werden.
ƒ Der Übersetzer betrachtet den Code allerdings nur strukturell und
berücksichtigt außer Wahrheitswerten keine Wert.
int k;
if (v > 0 && (k = System.in.read()) >= 0) {
System.out.println(k);
}
OK, weil auf jedem Pfad durch den
Code k sicher initialisiert wird.
Die Bedingung kann nur zu true
ausgewertet werden, wenn auch
der zweite Teil ausgewertet wird.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-53
int k;
int n = 5;
if (n > 2) {
k = 3;
}
System.out.println(k);
Weil n zur Laufzeit den Wert 5 hat,
wird k bei jeder Programmausführung
initialisiert sein. Der Übersetzer
berücksichtigt aber den Wert von n
nicht und "sieht", dass k im else-Fall
nicht initialisiert werden könnte.
int k;
if (flag) {
k = 3;
} else {
k = 4
}
System.out.println(k);
OK
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-54
M. Philippsen
7.5 Was geht hier schief?
7.5 Was geht hier schief?
1. Beispiel
2. Beispiel
class Exp {
public static void main(String[] args) {
int i = 10;
int j = 12;
if ((i < j) || (i = 3)) {
System.out.println("Hello");
}
}
}
i=3 ist Zuweisung
mit Ergebnistyp
int. Kann nicht
mit || verknüpft
werden.
Übersetzer meldet
den Fehler.
class Exp {
public static void main(String[] args) {
int i = 10;
int j = 12;
if ((i < j) || (i = 3) > 5) { }
System.out.println(i);
}
}
Kein syntaktischer Fehler. Vermutlich ist der leere
Rumpf der if-Anweisung nicht beabsichtigt.
Hier wird in jedem Fall „10“ ausgegeben.
Einrücken von println reicht nicht.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-55
M. Philippsen
7.5 Was geht hier schief?
Algorithmik 1, WS 2004/05, Folie 7-56
M. Philippsen
7.5 Was geht hier schief?
3. Beispiel
class Test {
public static void main(String[] args) {
double a = 5.1;
double b = 20.32;
double c = 32.998;
System.out.println(findAvg(a,b,c));
}
main ist statische
Methode. Aus
statischem Kontext
kann Objekt-Methode
findAvg nicht
aufgerufen werden.
Übersetzer meldet
den Fehler.
double findAvg(double a, double b, double c) {
return (( a + c + b) /3.0);
}
}
return-Wert nicht
klammern (Codier-Regel)
class Hund {
public static void main(String[] args) {
Pudel p = new Pudel();
Terrier t = new Terrier();
Hund h = Hund();
h = p;
p = h;
p = (Pudel) h;
h = new Pudel();
p = (Pudel) h;
p = t;
p = (Pudel) t;
}
}
statischer
Typfehler
statisch ok
Laufzeitfehler
statischer
Typfehler
statischer
Typfehler
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-58
M. Philippsen
7.5 Was geht hier schief?
7.5 Was geht hier schief?
5. Beispiel
6. Beispiel
found könnte uninitialisierte lokale Variable
sein. Nur Instanzvariablen und Klassenvariablen
werden automatisch intitialisiert.
Der Übersetzer meldet den Fehler.
class Test {
public static void main(String[] args) {
int index;
boolean found;
for (index = 0; index < 10 && !found; index++) {
if (index > Math.PI) {
System.out.println(index + "ist größer als Pi");
found = true;
}
}
}
}
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-59
new fehlt.
class Pudel extends Hund { ... }
class Terrier extends Hund { ... }
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-57
4. Beispiel
main-Methode hat void als Ergebnistyp
Parametername fehlt.
public class Sum {
public static void int main(String[]) {
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
lokale Variablen mit gleichem Namen verboten
int sum = 0;
Reihungsgrenzen 0...length-1
int i;
for (int i = 1; i <= a.length; i+) {
++
sum += a[i];
System.out.println("The sum is: ", sum)
}
}
} fehlt
Konkatenation von
Zeichenketten mit +
; fehlt
Friedrich-Alexander-Universität Erlangen-Nürnberg
M. Philippsen
Algorithmik 1, WS 2004/05, Folie 7-60
M. Philippsen
7.5 Was geht hier schief?
7. Beispiel
Klassennamen beginnen
mit einem Großbuchstaben.
class ex {
...
void test(int i, long j) { ... }
void test(long i, int j) { ... }
...
e.test(1, 1);
e.test(1L, 1);
}
Beide test-Methoden haben
bei Typwandlung den
gleichen „Abstand“. Es
kann daher nicht statisch
entschieden werden,
welche am spezifischsten
ist. Daher Fehler.
Die zweite test-Methode
passt besser. Alles OK.
Friedrich-Alexander-Universität Erlangen-Nürnberg
Algorithmik 1, WS 2004/05, Folie 7-61
M. Philippsen
Herunterladen