Download Folie 1

Document related concepts
no text concepts found
Transcript
Java als objektorientierte
Programmiersprache





















Allgemeines zu Programmiersprachen
Was ist Java?
Allgemeines zu Java
Installation von Java
Algorithmen
Darstellungsmethoden
Schritte zur Programmentwicklung
Primitive Datentypen
Kontrollfluss und Schleifen
Strings
Arrays
Klassen und Objekte
Vererbung von Klassen
Exceptions
Interface
Applets
Events
Graphische Benutzeroberfläche
Streams
Threads
Ergänzungen
1
Einführung
Was ist eine Programmiersprache?
Sprache, die entwickelt wurde, um einen Computer zu
instruieren bestimmte Dinge zu tun.
Was ist ein Programm?
Ein Algorithmus, der mittels einer Computerprogrammiersprache
geschrieben wird.
Was ist ein Algorithmus?
Eine präzise Methode die ein Computer zur Lösung von
Aufgaben/Problemen benutzt.
Algorithmus ist aus endlicher Menge von Schritten aufgebaut.
Ein Schritt besteht aus einer oder mehreren Operationen.
2
Einführung
1. Übungsaufgabe:
Schreibe einen Algorithmus, der die Zahlen von 1 bis 2000 (allgemein
n) aufsummiert und das Ergebnis ausgibt!

Vorgehensweise:
initialisiere summe mit 0
initialisiere zahl mit 0
solange zahl <= 2000 wiederhole:
addiere zahl zu summe
erhöhe zahl um eins
gib summe aus

Pseudocode:
summe = 0
zahl = 1
while (zahl <= 2000) {
summe = summe + zahl
zahl = zahl + 1
}
print “Die Summe ist“, summe
3
Einführung
Welche Sprachen gibt es?

Maschinensprache:
interne Sprache des Rechners/Prozessors
Befehle sind binär codiert (Darstellung jedoch häufig
hexadezimal)
Bsp: op-code:
A1 10E4
04 2a
a3 10e4

(hole Inhalt der Speicherzelle
10e4h in a1- register)
(addiere zum Inhalt des a1- Register
eine 46)
Speicher Inhalt des a1- Registers in
Speicherzelle 10e4)
Assembler:
nur für Prozessor eines Typs gültig:
Befehlscodes werden durch Mnemotechnische Abkürzungen
dargestellt (MOV, ADD, MULT, INC,...)
Speicheradressen können symbolisch benannt werden

Problemorientierte, prozedurale (höhere
Programmiersprachen)
Vertreter:
Fortran, Cobol, Algol, C, C++, PASCAL, java, ...
höhere Rechnerunabhängigkeit (Portabilität)
Notation in Form von Anweisungen.

4GL, oder deklarative Sprachen:
z.b. Abfragesprachen für DB
4
Was ist Java?
Die Programmiersprache Java ist
 eine Plattform (bestehend aus Java- Compiler und Java
Interpreter)
 eine Systemprogrammiersprache (wie C/ C++, Pascal,
Fortran, ...) zum Schreiben von Programmen
 von der Syntax ähnlich der Sprache C
 einsetztbar zum Schreiben von Applets eingesetzt
Vergleich zwischen Java und anderen
Programmiersprachen (aus Oust[98]):
5
Was ist Java?
•
Das Bild zeigt die Einordnung von
Programmiersprachen in Abhängigkeit von
Maschineninstruktionen/ Anweisung und dem Grad der
Typisierung.
•
Während interpretierte Skriptsprachen wie perl, tcl
zumeist eine lose Typisierung besitzen (d.h. es
gibt z.B. keinen expliziten Datentyp für eine floatZahl oder eine Zeichenkette) sind Systemprogrammiersprachen streng typisiert, was eine
effektivere Fehlererkennung zum Compilierzeitpunkt
erlaubt.
•
Skriptsprachen führen pro Anweisung eine höhere
Anzahl von Maschineninstruktionen aus, was zu
kürzeren Programmen führt.
•
Systemprogrammiersprachen und Skriptsprachen
können sich auf ideale Weise ergänzen, indem
komplexe Komponenten in einer
Systemprogrammiersprache entwickelt werden und
diese Komponenten dann anschließend mittels
Skriptsprachen flexibel zu fertigen Anwendungen
kombiniert werden können.
6
Was ist Java?
Eigenschaften von Java:








einfach
objektorientiert
architekturneutral (portabel)
verteilt
sicher
multithreaded
dynamisch
performant
7
Was ist Java?
1. einfach:

Kleine Anzahl an Sprachelementen

Fehlen einer Reihe von komplizierten / fehleranfälligen
Sprachkonstrukten (keine Pointerarithmetik/Pointer,
keine Speicherallokation sondern Garbage Collection

Umfangreiche bestehende Klassenbibliotheken (zuerst
abschreckend, dann ..., einfach mal rumbrowsen)
8
Was ist Java?
2. objektorientiert:

Natürlichere Entwurfsphilosophie als bei
prozeduralen Sprachen

Einheitliche Behandlung von Daten und
Programmcode in Form von Klassen

Aufbau von Klassenhierarchien (Vererbung)

Objekte bestehen aus Daten (beschreiben Zustand
des Objektes) und Methoden (beschreiben Verhalten
des Objektes)

einfacher zu lesen, effizientere
Wiederverwendbarkeit, schnellere
Entwicklungszeiten, robuster/ weniger fehleranfällig
9
Was ist Java?
3. architekturneutral:
 Java Programme sind plattformunabhängig, d.h. sie
können auf jeder Rechnerplattform ablaufen für die eine
Java virtuelle Maschine existiert.
 Java Compiler erzeugt plattformunabhängigen
Bytecode, der dann zur Laufzeit von der Java virtual
machine (VM) interpretiert wird (siehe Folie).
 Java virtuelle Maschine kapselt alle betriebs/hardwarespezifischen Eigenschaften der
Rechnerplattform und stellt dem Java Programm eine
neutrale Laufzeitumgebung zur Verfügung.
 Aspekt der plattformunabhängigkeit in Bezug auf
Applets wichtig
10
Was ist Java?
4. architekturneutral:

Java Standardbibliothek unterstützt in hohem Maße
verteiltes Programmieren (eine Reihe von
existierenden Klassen die Kommunikation verteilter
Prozesse unterstützen -- java.netklassen, z.b. URL
Klasse); , RMI (Remote Method Invovcation) aber
auch Kommunikation über Sockets bzw. UDT/
datagramme; applets)
11
Was ist Java?
5. sicher:
 Fehlen von fehleranfälligen Konstrukten wie Pointer,
Speicheralllokation
 streng typisierte Sprache (d.h. jede Variable hat einen
fest vorgegebenen
Typ (boolean, int, long, float, char, string)
 Ausnahmebehandlung -> klarer strukturierter Code
 Interpreter überprüft Bytecode zur Laufzeit
 Applet Sandboxprinzip (eingeschränkte Funktionalität)
12
Was ist Java?
6. multithreaded:

Gleichzeitig mehrere Ausführungsstränge in einem
Programm (z.B. ausführen umfangreicher
Berechnungen und gleichzeitig
Interaktion mit Benutzer)
13
Was ist Java?
7. dynamisch:

Klassen können zur Laufzeit dynamisch nachgeladen
werden und Objekte daraus instanziiert werden.
14
Was ist Java?
8. performant:

prinzipiell sind interpretierte Programme langsamer
als z.B. compilierter (plattformabhängiger) C-Code
(Daumenregel: ca. faktor 10)

Geschwindigkeit ae4r für Grossteil der
Anwendungsfelder ausreichend, z.B. Datentransport,
Benutzerinteraktion.

JIT Compiler (Just In Time) übersetzt Java Bytecode
zur Laufzeit in plattformabhängigen Maschinencode

Weitere native-compilers in Entwicklung

Zeitkritische Anwendungen können weiterhin in
C/Fortran geschrieben werden und dann in das Java
Programm eingebunden werden.
15
Was ist Java?
9. architekturneutralität
16
Was ist Java?
Online Klassenbrowser
17
Was ist Java?
Einordnung

Applets sind Java Programme die in einer HTML-Seite integriert sind

Java fähige WWW-Browser (Netscape, MS-IE) haben eine VM
integriert

SDK von SUN ist eine Entwicklungsumgebung zur Entwicklung von
Java Programmen oder Applets.

weitere Entwicklungsumgebungen:
Java Workshop (SUN), Cafe (Symantec),
Visual J++
(Microsoft), Roaster (Natural Intelligence), Kawa (TekTools), JOE

Applets laufen innerhalb eines Browsers oder Appletviewer (SUN) ab

Java ist nicht Javascript
18
Was ist Java?
Die Java Umgebung

JDK von SUN

Compiler: javac

Debugger: jdb

Laufzeitumgebung: java, jre

Dokumentationstool: javadoc

Appletviewewér: appletviewer

Packer: jar

Integrated Development Environments (IDE)

bestehend aus: Projektmanager, Edit-CompileDebug Prozess, kontextsensitive Hilfe, GUI-Builder,
Versionsverwaltung, Templates, zusätzliche
Klassenbibliotheken
• Beispiele: Borland JBuilder, Sun Forte, Micro-soft
Visual J++, ...
19
Allgemeines zu Java
Einsatz des JDK von SUN
• Mit
beliebigem Editor (z.B. notepad) Programmcode
erstellen:
public class Summe {
public static void main (String args[ ]) {
int summe = 0;
int limit = 1000;
int zahl = 1;
while (zahl <=limit) {
summe = summe + zahl;
zahl = zahl + 1;
}
System.out.println("Die Summe von 1 bis " + limit + " betraegt:" + summe);
}
}
• Datei
unter dem Namen Summe.java abspeichern
• Datei Summe.java compilieren (Datei Summe.class wird erzeugt):
javac Summe.java
• Programm ausführen:
java Summe
• Ausgabe:
Die Summe von 1 bis 1000 betraegt: 500500
20
Installation von Java
Download des JDK:
Download von Java (Win95/NT)
21
Installation von Java
Installation von Java (Win95/NT)
22
Installation von Java
Installation von Java (Win95/NT)
Modifiziern des Zugriffspfad in der Autoexec.bat Datei (nur Win95/98):
23
Algorithmen
Ein Algorithmus ist ein Verfahren zur systematischen, schrittweisen
Lösung eines Problems. Er besteht aus einzelnen Anweisungen, die in
einer bestimmten Reihenfolge, evtl. mehrmals ausgeführt werden
müssen.
Beispiele:
• ärztliche Verordnung: nimm 3x täglich 15 Tropfen einer Medizin ein
• Spielregeln, z.B. Mensch-ärgere-dich-nicht
• Verfahren zur Addition und Multiplikation von 2 Dezimalzahlen
• Näherungsverfahren zur Bestimmung der Quadratwurzel
konkretes Beispiel: Algorithmen zum Test auf Primzahl
Eine Primzahl ist eine ganze Zahl >1, welche nur durch sich selbst und
durch den Wert 1 teilbar ist. Die Folge der Primzahlen lautet 2, 3, 5, 7, 11,
13, ...
ZAHL sei 7und ZAHL sei 9
7 : 2 teilbar? => nein 9 : 2 teilbar? => nein
7 : 3 teilbar? => nein 9 : 3 teilbar? => ja
7 : 4 teilbar? => nein 9 : 4 teilbar? => nein
7 : 5 teilbar? => nein 9 : 5 teilbar? => nein
7 : 6 teilbar? => nein usw. ...
=> 7 ist eine Primzahl => 9 ist keine Primzahl
24
Algorithmen
Algorithmus:
Gebe eine ZAHL ein
Setze DIVTEST = 2
SOLANGE ((DIVTEST kleiner ZAHL) und (ZAHL nicht durch
DIVTEST teilbar))
Erhoehe DIVTEST um 1
WENN (DIVTEST gleich ZAHL)
DANN Ausgabe ZAHL ist Primzahl
SONST Ausgabe ZAHL ist keine Primzahl
25
Grundstrukturen von Algorithmen
Allgemeine Anweisungen (oder Aktionen), werden ohne Einschränkung
ausgeführt.
Bei bedingte Anweisungen (oder Auswahl) werden Programmteile nur bei
bestimmten Daten ausgeführt , man spricht von bedingten Anweisungen.
Man unterscheidet:

Einfache bedingte Anweisung, bestehend aus Bedingung und
Anweisung, die ausgeführt wird, wenn die Bedingung erfüllt ist. Die
Bedingung ist ein Ausdruck, der als Ergebnis einen Wahrheitswert der
Form wahr oder falsch liefert. Die Anweisung ist eine beliebige
Anweisung (z.B. wieder eine bedingte Anweisung)

Vollständige bedingte Anweisung besteht aus beiden Elementen einer
bedingten Anweisung und zusätzlich einer Anweisung, die ausgeführt
wird, falls die Bedingung nicht erfüllt ist. Das hat zur Folge, daß immer
eine der beiden Anweisungen ausgeführt wird

Fallunterscheidung, falls es mehr als zwei Fälle gibt. Dann definiert man
statt einer Bedingung, die entweder wahr oder falsch sein kann, einen
so genannten Verteiler, der mehrere Werte annehmen kann. Analog
gibt es statt 2 möglichen Alternativen (Aktion 1 und 2) mehrere
mögliche Alternativen (Aktion 1 ... n).

Schleifen (oder Wiederholungen), bei denen die Daten bestimmen, wie
oft ein bestimmtes Programmstück durchlaufen werden soll. Schleifen
bestehen i. d. R. aus 3 Teilen:
•
•
•
Vorbehandlung, d.h. einer Initialisierung der Anfangswerte
Anweisungen, die innerhalb der Schleife wiederholt ausgeführt werden.
Diese müssen u.a. auch die Schleifenvariable verändern , die dann
getestet werden kann.
Test auf Bedingung für den Abbruch oder Fortsetzen der Schleifen
anhandder Schleifenvariable.
26
Grundstrukturen von Algorithmen
Es gibt 3 Arten von Schleifen:
•
Zählschleifen, bei denen ein Programmabschnitt n-mal
durchlaufen wird. Dabei muß die Anzahl der Schleifendurchläufe
bekannt sein. (Es gibt Programmiersprachen, insbesondere Java,
in deren Sprachumfang echte Zählschleifen nicht vorkommen.)
•
Bedingte Schleifen, bei denen ein Abschnitt eines Programms
solange durchlaufen wird, bis ein Testkriterium greift. Zu Beginn ist
die Anzahl der Durchläufe aber unbekannt (sonst i. d. R.
Zählschleife). Bedingte Schleifen unterteilt man, je nachdem, wann
der Test durchgeführt wird, in:
–
While-Schleifen, bei denen der Test vor jedem Schleifendurchlauf
erfolgt. Die Ausführung der Anweisungen erfolgt, solange die
Schleifenbedingung erfüllt ist.
–
Repeat-Schleife (do-while), bei denen der Test nach jedem
Schleifen-durchlauf erfolgt. Das bedeutet, daß die Schleife
mindestens einmal durchlaufen wird.
Die Interpretation ist abhängig von der Programmiersprache:
–
In PASCAL z.B. erfolgt die Ausführung der Anweisung, bis das
Abbruchkriterium erfüllt ist. Das Abbruchkriterium dieser Schleife
ist demnach die Negation der Schleifenbedingung bei der
äquivalenten While-Schleife.
–
In Java dagegen erfolgt die Ausführung der Anweisung, solange
die Schleifenbedingung erfüllt ist. Die Formulierung der
Schleifenbedingung ist demnach analog zur While-Schleife.
27
Darstellungsmethoden

Mit Hilfe von Flußdiagrammen kann man den Ablauf eines
Algorithmus recht übersichlich beschreiben. Dabei gibt es
unterschiedliche Symbole für verschiedene Typen von Anweisungen,
die genormt sind (DIN 66001):




Allgemeine Anweisung (Aktion)
Ein-/Ausgabeanweisung
Anfangs-/Endmarkierung
Bedingte Anweisung Bild
Diese Grundsymbole werden über Pfeile miteinander verbunden, um die
Ablaufreihenfolge darzustellen.
Der Nachteil besteht darin, daß es nicht für alle Anweisungsformen (z.B.
Schleifen) geeignete Symbole gibt. Man kann (wie in der Tabelle) auf
Nichts-Standard-Symbole ausweichen oder diese Anweisungsformen recht
kompliziert mit Hilfe der angebotenen Symbole realisieren. Nachteil der
Flußdiagramme:
sie ermöglichen eine übersichtliche Darstellung eines Ablaufens, sie
erzwingen diese aber nicht.
28
Darstellungsmethoden
Tabelle
29
Beispiel: GGT
Beispiel: Bestimme GGT von 24 und 15:
24:15 = 1
Rest 9
15 : 9 = 1
9:6=1
6 :3 = 2
Rest 6
Rest 3
Rest 0
GGT = 3
Ein Algorithmus dafür in natürlichsprachlicher Form hat die folgende
Gestalt:
Lies a und b
Falls b > a vertausche a und b
Falls b > 0
Setze zahl a = a und zahl b = b
wiederhole:
rest = zahl a modulo zahl b
zahl a = zahl b
zahl b = rest
solange rest ungleich 0
Drucke "zahl a ist der GGT von a und b"
sonst Drucke " ungültige Eingabe"
30
Flußdiagramm
Flussdiagramm
31
Struktogramm
32
Beispiel: Zins
Es soll ein Algorithmus zur Berechnung von Zinseszinsen erstellt werden.
Zur Erinnerung sei das Problem hier kurz skizziert:
Bei jährlicher Verzinsung für ein gegebenes Ausgangskapital K 0 einem
Zinssatz p erhält man Zinsen in Höhe von z = K 0 * p /100. Das
Gesamtkapital K 1 nach einem Jahr beträgt daher: K 1 =K 0 * (1 + p / 100).
Wenn man dieses neu erhaltene Kapital weiterverzinst, so erhält man durch
Wiederholung die Zinseszinsformel für das Endkapital K (n) nach n jähriger
Verzinsung: K (n) = K 0 * (1 + p /100) hoch n .
Die Berechnung benötigt also folgende Eingabedaten:
•
•
•
Ausgangskapital K_0
Zinssatz p
Verzinsungsdauer n in Jahren
Der Algorithmus soll diese drei Werte einlesen, und zunächst auf Gültigkeit
überprüfen, beispielsweise ist eine negative Verzinsungsdauer ungültig.
Falls einer der drei Werte unzulässig ist, soll der Algorithmus mit einer
qualifizierten Fehlermeldung abbrechen. Wenn alle drei Werte zulässig sind,
soll der Algorithmus zunächst diese Werte ausgeben, und dann eine
Tabelle folgender Form erstellen: (Beispiel p = 5%)
33
Natürlichsprachlicher Algorithmus
Start Zinseszins
Lies Startkapital
WENN Startkapital<0
DANN Ausgabe "Negatives Startkapital"
SONST
Lies Zinssatz
WENN Zinssatz<0
DANN Ausgabe "Zinssatz negativ"
SONST
Lies Dauer
WENN Dauer<0
DANN Ausgabe "Dauer negativ"
SONST
Kapital = Startkapital
Zins = 0
Jahr = 0
SOLANGE Jahr <=Dauer
Ausgabe Jahr, Zins, Kapital
Beginne neue Ausgabezeile
Zins = Kapital * Zinssatz/100
Kapital = Kapital + Zins
Jahr = Jahr + 1
Ende Zinseszins
34
Struktogramm
35
Flussdiagramm
36
Schritte zur Programmentwicklung
1.
Formulierung des Problems
2.
Entwurf eines Lösungsalgorithmus
Formulierung auf abstrakter Ebene
Beachten von Strukturregeln
Korrektheit des Lösungsalgorithmus prüfen
Effizienzuntersuchungen
3.
Implementierung, d.h. Übertragung des Lösungsalgorithmus in eine
Programmiersprache. Ergebnis: ein Programm als Quellcode
4.
Übersetzen (engl.: to compile) des Programms in eine
maschinennahe Sprache
Das geschieht durch den Compiler (javac). Das Ergebnis ist Bytecode
5.
Ausführen des Programms (java)
37
Beispiel
1.
Formulierung des Problems
Berechne den Quotienten zweier Zahlen a,b (d.h. a/b), falls b ¹ 0, sonst
melde, daß b ein unzulässiger Wert ist.
2.
Entwurf eines Lösungsalgorithmus
Start
Lies zwei Zahlen a und b ein
WENN b ungleich 0
DANN quotient sei a / b
schreibe quotient
SONST schreibe "b ist ein unzulaessiger Wert"
Ende
... Strukturregeln, Korrektheit, Effizienz
3.
Implementierung (Speichern als Quotient.java)
import Utils;
class Quotient {
public static void main (String args [ ]) {
float a,b, quotient;
a = Utils.inputFloat(„Gib a ein: „);
b = Utils.inputFloat(„Gib b ein: „);
if (b!=0) {
quotient = a/b;
System.out.println(„Quotient „+quotient);
}
else {
System.out.println(b+“ ist unzulaessiger Wert“);
}
}
}
38
Beispiel
4.
Übersetzen:
javac Quotient.java
5.
Ausführen:
misun3:65>java Quotient
Gib a ein: 3
Gib b ein: 6
Quotient 0.5
misun3:66>java Quotient
Gib a ein: 3
Gib b ein: 0
0.0 ist unzulaessiger Wert
39
Aufgaben
Aufgabe 1
Erstelle einen Algorithmus zum Aufbau einer Temperaturtabelle von
Fahrenheit (F) nach Celsius (C). Die Tabelle soll bei 0 F beginnen und bei
300 F enden. Die Abstände der Stützstellen sollen 20 F betragen.
Der funktionale Zusammenhang von F und C ist durch folgende Formel
gegeben: C = (5 / 9) * ( F - 32)
Beispiel: Temperaturtabelle
Fahrenheit I
0
I
..
300
Celsius
-17.8
I
148.9
Aufgabe 2
Der Wildbestand eines Forstes umfasst 200 Stück. Die jährliche
Vermehrung beträgt 10%; zum Abschuß sind im gleichen Zeitraum 15 Stück
freigegeben. Wie entwickelt sich der Bestand in den nächsten Jahren?
Erstelle eine Algorithmus, der den jährlichen Wildbestand ermittelt, bis
dieser die Zahl 300 erreicht hat.
Aufgabe 3
Entwickle einen Algorithmus, der das kleine Einmaleins in Tabellenform (10
mal 10 Tabelle) ausgibt.
Aufgabe 4
Schreibe einen Algorithmus, der beliebig, viele Zahlen einliest und diese
Zahlen aufsummiert. Als Abbruchkriterium verwende die Eingabe einer
negativen Zahl. (Realisierung einmal mit while-Schleife und einmal mit dowhile Schleife.)
40
Primitive Datentypen
2 Arten von Datentypen:


primitive Datentypen (heute)
Objekte (später)
Java ist streng typisiert, d.h. für jede Variable muß angegeben werden
was für eine Art von Wert sie aufnimmt
• Beispiele:
double radius;
float umfang;
int anzahl = 2;
char a = ‘c’;
41
Operatoren
mathematische Operatoren:
logische Operatoren
Konstanten
soll eine Variable nicht geändert werden dürfen, so wird es mit dem Attribut
final versehen:
final float PI = 3.141592f;
42
Ausgabe

In der Klasse java.lang.System realisiert

Drei Streams:


Standardausgabe: System.out

Standardfehlerausgabe: System.err

Standardeingabe: System.in
Ausgabe auf Konsole (stdout, stderr):
System.out.println ("Ich bin eine Zeile");
System.out.print ("Ich bin");
System.out.println (" eine Zeile");
System.err.println ("Aaaargghh ich steeer....");
43
Hello World
Ein erster Programmierversuch:

Datei HelloWorld.java in Editor (z.B. no-tepad) erstellen:
class HelloWorld {
public static void main (String args[ ]) {
System.out.println("Hello World!");
}
}


DOS Fenster öffnen
Programm übersetzen:
d:\user\smiff> javac HelloWorld.java

Wenn kein Fehler aufgetreten ist, wurde die Datei
HelloWorld.class angelegt
d:\user\smiff\> dir Hello*
HelloWorld.class
HelloWorld.java
d:\user\smiff>

Programm laufen lassen:
d:\user\smiff> java HelloWorld
Alternative:

Verwendung von Joe
44
Eingabe
•
Einlesen von Konsole: (mit Ausnahmebehandlung):
byte buffer[ ] = new byte[80];
int num_char;
String input = "";
System.out.print("Bitte gib mal was ein: ");
try {
num_char = System.in.read(buffer, 0, 80);
input = new String(buffer,0, num_char);
}
catch (IOException e) {
System.err.println("IO Fehler");
}
System.out.println(">>>>>>" + input);
}

Benutzung der Klasse Utils:
Zur Vereinfachung kann die Klasse Utils in das Programm im-portiert
werden, die das Einlesen erleichtert. Utils ist auf der Homepage
verfügbar.
45
Beispielprogramm zur Eingabe
import Utils;
class InputDemo
{
// kleines Demo Programm zur Demonstration
// der Eingabemethoden
// Utils.inputInteger(...)
// Utils.inputString(...)
// Utils.inputFloat(...)
public static void main(String argv[ ]) {
String str = Utils.inputString(" gib Text ein:");
int z = Utils.inputInteger("und jetzt ne Zahl:");
float f = Utils.inputFloat("und ne Gleitkommazahl:");
System.out.println(" String: " + str );
System.out.println("Integer: " + z );
System.out.println("Float: " + f);
}
}
46
Kontrollfluß und Schleifen
if – else
if (boolscher Ausdruck)
statement
else
statement
Beispiel:
if (a % 2 == 0) {
System.out.println(“a ist gerade“);
}
else {
System.out.println(“a ist ungerade“);
}
While Schleife
while (boolscher Ausdruck)
statement
Beispiel:
i = 1;
a = 0;
while (a < 10) {
a = a + i;
i = i + 1;
}
47
Beispiel
Ausgabe der Zahlen von 1 bis 100:
class Ausgabe1bis100 {
public static void main (String args []){
int i=1;
while ( i<101) {
System.out.println(i);
i++;
}
}
}
48
Schleifen
do – Schleife
do
statement
while (boolscher Ausdruck);
Beispiel (Test zu Beginn/Ende der Schleife):
do {
System.out.println(a);
a++;
} while (a < 50);
while (a < 50) {
System.out.println(a);
a++;
}
for – Schleife
for (init; boolscher Ausdruck; Schritt)
statement
Beispiel:
for (int i = 1; i < 100; i++) {
System.out.println(“i = “ + i);
}
49
Beispiel
Ausgabe der Zahlen von 1 bis 100 mit do-while:
class Ausgabe1bis100 {
public static void main (String args []) {
int i=1;
do {
System.out.println(i);
i++;
}
while ( i<101);
}
}
Ausgabe der Zahlen von 1 bis 100 mit for:
class Ausgabe1_100 {
public static void main (String args [ ]) {
for (int i=1; i<101; i++)
System.out.println(i);
}
}
50
Beispiel
Aufsummieren der Zahlen von 1 bis 50
public class Summe {
public static void main (String args[]) {
int summe=0;
for (int i= 1; i<=50; i++)
summe = summe + i;
System.out.println (“ summe = “+ summe);
}
}
51
Breakanweisung

break: Beendigung der Schleife und fortfahren mit der nächsten
Anweisung nach der Schleife
while (true) {
if (i++ > 100)
break;
System.out.println(“i=“ + i);
}

continue: Abbruch des aktuellen Schleifendurchlaufs und Sprung zum
nächsten Schleifendurchlauf
while (i <=100) {
if (i++ % 2)
continue;
System.out.println(i);
}
52
Switchanweisung

Switch Statement
switch (Selektor)
{
case wert1: statement; break;
case wert2: statement; break;
// ...
default: statement;
}
Beispiel:
public class Switch {
public static void main (String args[ ]) {
for (char c=65; c < 91; c++) {
switch (c) {
case ‘A’:
case ‘E’:
case ‘I’:
case ‘O’:
case ‘U’:
System.out.println(c + „ ist ein Vokal“);
break;
case ‘X’:
System.out.println(„Das „ + c +“ ist mein Lieb-lingsbuchstabe“);
break;
default:
System.out.println(c + „ ist ein Konsonant“);
}
}
}
}
53
Strings

Ein String ist ein Java Objekt

Erzeugung:
String s1 = "Hallo";
String s2 = new String("wie gehts");
String s3 = "Ein \"String\" mit Anführungszeichen";

Verkettung von Strings:
String s4 = s1 + " " + s2 + "?";

Umwandlung einfacher Datentypen in Strings:
float f = 1.234f;
String s = Float.toString(f);

Umwandlung von Strings in einfache Datentypen:
String intStr = "353";
int i = Integer.parseInt(intStr);
short s = Short.parseShort(intStr);

Methoden der Klasse String:

Vergleich: boolean equal = s1.equals(s2)
equal = s1.equalsIgnoreCase(s2);

Länge ermitteln: int len = s1.length()

Liste aller Methoden :
http://java.sun.com/products/jdk/1.2/docs/api/java/
lang/String.html
54
Beispiele
Programm das alle durch 3, 5 oder 7 teilbaren Zahlen kleiner 200
ausgibt:
class C357 {
public static void main (String args []) {
for (int i=1; i<201; i++)
if (i%3 == 0 || i%5 == 0 || i%6 == 0)
System.out.println(i+“ ist durch 3,5 oder
7 teilbar“);
}
}
55
Beispiele
Programm, das die folgende Ausgabe erzeugt:
*
***
*****
*******
*********
***********
class Baum {
public static void main (String args [ ]) {
int zeilen=10;
for (int i = zeilen; i >0; i--) {
for(int j=0;j<i;j++)
System.out.print(„ „);
for(int j=0;j<2*(zeilen-i)-1;j++)
System.out.print(„*“);
System.out.println();
}
}
}
56
Aufgaben
Erstellen Sie zu den in den Aufgaben 1 bis
4 aus der Vorlesung „Algorithmen“ erstellten
Algorithmen die zugehörigen JavaProgramme.
57
Arrays
Eindimensionale Arrays
Erzeugen (2 Möglichkeiten):
•
Erzeugung durch new-Operator:
float v[ ] = new float[4];
58
Arrays
•
Arrays sind Objekte
•
Sie werden dynamisch erzeugt
•
Sie werden automatisch vom Garbage Collector entfernt
•
Aber kein Konstruktor, sondern new-Operator
•
Anzahl der Komponenten des Arrays muß bei der Definition angegeben
werden
•
Die Länge des Arrays erhält man durch das length-Attribut desArrays
(v.length ist in unserem Beispiel gleich 4)
•
Die Indizes der Komponenten müssen ganzzahlig sein
•
Die Komponenten selbst werden mit 0 beginnend numeriert
•
Der größte zulässige Index ist immer um 1 kleiner ist als die Anzahl der
Komponenten (length-1)
•
Negative Indizes und Indizes größer oder gleich der Länge length sind
nicht zugelassen (z.B. [v.length] führt zum Fehler)
•
Die Elemente eines auf diese Weise erzeugten Arrays werden mit dem
für diesen Typ üblichen Standardwert initialisiert. (Bei unserem Array v
beispielweise mit 0.0f.)
•
Direkter Zugriff auf jede Komponente (z.B. v[1] = 1.2)
59
Arrays
•
Erzeugung durch einen Initialisierer:
int lt[ ] = {1,2,4,8,16,32,64,128};
•
Diese Syntax erzeugt auf dynamische Weise einen Array und
initialisiert seine Elemente mit den angebenen Werten
Beispiel: (Ausgabe des Arrays lt)
public class lt {
public static void main(String[ ] args) {
int lt[ ] = {1,2,4,8,16,32,64,128};
for(int i = 0; i < lt.length; i++)
System.out.println(lt[i]);
}
}
Beispiel: (Summe des Arrays lt)
public class lt {
public static void main(String[ ] args) {
int lt[ ] = {1,2,4,8,16,32,64,128};
int summe =0;
for(int i = 0; i < lt.length; i++)
summe = summe + lt[i];
System.out.println("Summe: " +summe);
}
}
60
Arrays
Beispiel: (Erzeugen eines Feldes mit Zufallszahlen als Inhalt)
public class MyArray {
public static void main(String[ ] args) {
double nums[] = new double[10];
for (int i = 0; i < nums.length; i++)
nums[i] = Math.random() * 100;
for (int i = 0; i < nums.length; i++)
System.out.println(nums[i]);
}
}
Beispiel: (Suchen des größten Wertes im Array)
public class ArrayGreat {
public static void main(String[ ] args) {
double [ ] nums = new double[10]; //Klammernb koennen auch hier stehen
for (int i = 0; i < nums.length; i++)
nums[i] = Math.random() * 100;
int max=0; //Index des groessten Elementes
for (int i = 1; i < nums.length; i++)
if (nums[max]<nums[i]) max = i;
System.out.println("Groesster Wert: " +nums[max]);
}
}
61
Arrays
Deklaration eines Arrays:
public class MyArray1 {
public static void main(String[ ] args) {
int a1 [ ]= {1,2,3,4,5}; // Definition von a1
int a2[ ]; // Deklaration von a2;
for (int i = 0; i < a1.length; i++)
System.out.println(a1[i]);
for (int i = 0; i < a2.length; i++)
System.out.println(a2[i]);
}
}
•
Ergibt einen Fehler, da a2 nicht initialisiert wurde
Zuweisung von Arrays:
public class MyArray1 {
public static void main(String[ ] args) {
int a1[ ]= {1,2,3,4,5}; // Definition von a1
int a2[ ]; // Deklaration von a2;
a2 = a1; // Zuweisung von a1 an a2
for(int i = 0; i < a1.length; i++)
System.out.println(a1[i]);
for (int i = 0; i < a2.length; i++)
System.out.println(a2[i]);
}
}
62
Arrays
Kopieren von Arrays (by reference):
public class ArrayCopy {
public static void main(String[ ] args) {
int[ ] a = {1,2,4,8,16};
System.out.print("a: ");
for (int i = 0; i < a.length; i++)
System.out.print (a[i]+" ");
System.out.println();
int[ ] b = {32,64,128,256,512,1024};
System.out.print("b: ");
for (int i = 0; i < b.length; i++)
System.out.print(b[i]+" ");
System.out.println();
a=b;
System.out.print("a: ");
for (int i = 0; i < a.length; i++)
System.out.print(a[i]+" ");
System.out.println();
a[0]=33;
System.out.print("a: ");
for (int i = 0; i < a.length; i++)
System.out.print (a[i]+" ");
System.out.println();
System.out.print("b: ");
for (int i = 0; i < b.length; i++)
System.out.print(b[i]+" ");
System.out.println();
}
}
Ausgabe:
a: 1 2 4 8 16
b: 32 64 128 256 512 1024
a: 32 64 128 256 512 1024
a: 33 64 128 256 512 1024
b: 33 64 128 256 512 1024
63
Arrays
Referenzdatentypen
•
Die komplexeren Datentypen von Java sind Objekte und Arrays. Sie
werden als „Referenztypen“ bezeichnet, weil sie „per Referenz“
(byreference) verarbeitet werden
•
Im Gegensatz dazu werden die einfachen Datentypen by value, also
„per Wert“ verarbeitet.
Kopieren von Variablen (by value):
public class VarCopy {
public static void main(String[] args) {
int a = 1;
System.out.println("a: "+a);
int b = 2;
System.out.println("b: "+b);
a=b;
System.out.println("a: "+a);
System.out.println("b: "+b);
a=3;
System.out.println("a: "+a);
System.out.println("b: "+b);
}
}
Ausgabe: a: 1
b: 2
a: 2
b: 2
a: 3
b: 2
64
Arrays
Kopieren von Arrays (by value):
public class ArrayCopy {
public static void main(String[ ] args) {
int[ ] a = {1,2,4,8,16};
System.out.print("a: ");
for (int i = 0; i < a.length; i++)
System.out.print (a[i]+" ");
System.out.println();
int[ ] b = {32,64,128,256,512,1024};
System.out.print("b: ");
for (int i = 0; i < b.length; i++)
System.out.print(b[i]+" ");
System.out.println();
System.arraycopy(a,0,b,0,a.length);
System.out.print("a: ");
for (int i = 0; i < a.length; i++)
System.out.print(a[i]+" ");
System.out.println();
System.out.print("b: ");
for (int i = 0; i < b.length; i++)
System.out.print(b[i]+" ");
System.out.println();
a[0]=33;
System.out.print("a: ");
for (int i = 0; i < a.length; i++)
System.out.print (a[i]+" ");
System.out.println();
System.out.print("b: ");
for (int i = 0; i < b.length; i++)
System.out.print(b[i]+" ");
System.out.println();
}
}
Ausgabe: a: 1 2 4 8 16
b: 32 64 128 256 512 1024
a: 1 2 4 8 16
b: 1 2 4 8 16 1024
a: 33 2 4 8 16
b: 1 2 4 8 16 1024
65
Arrays
Vorsicht vor Überschreitung der Arraygrenzen:
public class ArrayCopy {
public static void main(String[ ] args) {
int[ ] a = {1,2,4,8,16};
System.out.print("a: ");
for (int i = 0; i < a.length; i++)
System.out.print (a[i]+" ");
System.out.println();
int[ ] b = {32,64,128,256,512,1024};
System.out.print("b: ");
for (int i = 0; i < b.length; i++)
System.out.print(b[i]+" ");
System.out.println();
System.arraycopy(a,0,b,b.length,a.length);
System.out.print("a: ");
for (int i = 0; i < a.length; i++)
System.out.print(a[i]+" ");
System.out.println();
System.out.print("b: ");
for (int i = 0; i < b.length; i++)
System.out.print(b[i]+" ");
System.out.println();
a[0]=33;
System.out.print("a: ");
for (int i = 0; i < a.length; i++)
System.out.print (a[i]+" ");
System.out.println();
System.out.print("b: ");
for (int i = 0; i < b.length; i++)
System.out.print(b[i]+" ");
System.out.println();
}
}
Keine Erweiterung eines bestehenden Arrays möglich! Lösung:
int c[ ] = new int [a.length + b.length]
System.arraycopy(a,0,c,0,a.length);
System.arraycopy(b,0,c,a.length,b.length);
66
Arrays
Mehrdimensionale Arrays (Felder)
byte ZweiDimArray[ ][ ];
•
Deklaration der Variablen ZweiDimArray mit Typ byte[][] (Array-vonArray-aus-byte).
byte ZweiDimArray[ ][ ] = new Byte [256][ ];
•
Dynamische Bereitstellung eines Arrays mit 256 Elementen. Jedes
Element dieses neuen Arrays ist vom Typ byte[] - einem
eindimensionalen Array von bytes
byte ZweiDimArray[][] = new Byte [256][16];
•
Dynamische Bereitstellung eines 256Bytes-Arrays, von denen jeder 16
Bytes aufnehmen kann. Gleichzeitig wird eine Referenz dieser 16 byteArrays in den 256 Elementen des „äußeren“ Arrays gespeichert. Die 16
Bytes dieser 256 Arrays werden mit dem Standardwert 0 initialisiert.
Nicht Erlaubt:
byte ZweiDimArray[ ][ ] = new Byte [ ][16];
67
Arrays
Erlaubt:
Beliebige Dimension eines mehrdimensionalen Arrays:
int[ ][ ][ ][ ][ ] FuenfDim=new int[3][4][5][6][7];
•
Nicht rechteckige Form von Arrays:
int ZweiDim[ ][ ]= {{1,2},{3,4,5}, {5,6,7,8}};
Beispiel: (Generieren einer Matrix und Ausgabe der Matrix)
public class Matrix {
public static void main(String[] args) {
int matrix[][]=new int[4][5];
//Ausgabe der Matrix
for(int i = 0; i < matrix.length; i++) {
for (int j=0;j<matrix[i].length; j++)
System.out.print (matrix[i][j] +" ");
System.out.println();
}
}
}
Ausgabe: 0 0 0 0 0
00000
00000
00000
68
Arrays
Beispiel: Generieren der Einheitsmatrix und Ausgabe der Einheitsmatrix
public class EinheitsMatrix {
public static void main(String[ ] args) {
int matrix[][]=new int[10][10];
//Generieren der Einheitsmatrix
for (int i = 0; i < matrix.length; i++)
for (int j=0;j<matrix[i].length; j++)
if (i==j) matrix[i][j] =1;
//Ausgabe der Matrix
for(int i = 0; i < matrix.length; i++) {
for (int j=0;j<matrix[i].length; j++)
System.out.print (matrix[i][j] +" ");
System.out.println();
}
}
}
Ausgabe: 1 0 0 0 0 0 0 0 0 0
0100000000
0010000000
0001000000
0000100000
0000010000
0000001000
0000000100
0000000010
0000000001
69
Arrays
Beispiel: Nicht rechteckige Form eines mehrdimensionalen Arrays
public class Array2 {
public static void main(String[ ] args) {
short triangle[][]=new short[10][];
for (int i=0; i < triangle.length;i++) {
triangle[i] = new short[i+1];
for (int j=0;j<i+1; j++)
triangle[i][j] = (short) (i+j);
}
for(int i = 0; i < triangle.length; i++) {
for (int j=0;j<triangle[i].length; j++)
System.out.print (triangle[i][j] +" ");
System.out.println();
}
}
}
Ausgabe: 0
12
234
3456
45678
5 6 7 8 9 10
6 7 8 9 10 11 12
7 8 9 10 11 12 13 14
8 9 10 11 12 13 14 15 16
9 10 11 12 13 14 15 16 17 18
70
Arrays
•
Feste Anzahl von Komponenten
•
Beliebiger, aber für alle Komponenten gleicher Typ
•
Die Komponenten sind linear geordnet
•
Auf die einzelnen Komponenten kann direkt zugegriffen werden
•
Mehrdimensionale Arrays
•
Arrays sind Objekte. Dennoch gibt es Unterschiede zu »normalen«
Objekten
•
Gemeinsamkeiten von Objekten und Arrays:
•
–
Arrays werden wie Objekte grundsätzlich dynamisch angelegt und
am Ende ihrer Verwendung automatisch vom Garbage Collector
entfernt
–
Arrays sind wie Objekte Referenztypen
–
Arrays sind wie alle Klassen implizit Unterklassen der Klasse
Object Array-Elemente werden wie die Datenelemente von
Objekten auch stets automatisch initialisiert.
Unterschiede von Objekten und Arrays:
–
Arrays haben keine Konstruktoren. Statt dessen gibt es für Arrays
eine spezielle Syntax des new-Operators
–
Keine Unterklassen von Arrays möglich.
71
Arrays
Beispiel: Sortieren eines Feldes
public class ArraySortMain {
public static void main(String[ ] args) {
int [ ] nums = new int[10]; //Arrayerzeugung
//Zufallszahlen generieren
for(int i = 0; i < nums.length; i++)
nums[i] = (int) (Math.random() * 10);
//Ausdruck des erzeugten Arrays
for(int i = 0; i < nums.length; i++)
System.out.print(nums[i]+“ „);
System.out.println();
// Jetzt kommt das Sortieren
for (int i = 0; i < nums.length; i++) {
int min = i;
//Suchen des kleinsten Elementes zwischen i
//und dem Ende des Arrays.
for (int j = i; j < nums.length; j++)
if (nums[j] < nums[min]) min = j;
// Tauschen des kleinsten Elementes mit i
int tmp;
tmp = nums[i];
nums[i] = nums[min];
nums[min] = tmp;
//Ausdruck des Feldes, bei jedem Sortierdurchlauf
for (int j = 0; j < nums.length; j++)
System.out.print(nums[j]+“ „);
System.out.println();
}
}
}
72
Arrays
Beispiel: Sortieren eines Feldes
public class ArraySortMeth {
public static int[ ] einlesen() {
int [ ] nums = new int[10];
for(int i = 0; i < nums.length; i++)
nums[i] = (int) (Math.random() * 10);
for(int i = 0; i < nums.length; i++)
System.out.print(nums[i]+“ „);
System.out.println();
return nums;
}
public static void sort(int[ ] nums) {
for (int i = 0; i < nums.length; i++) {
int min = i;
for (int j = i; j < nums.length; j++)
if (nums[j] < nums[min]) min = j;
int tmp;
tmp = nums[i];
nums[i] = nums[min];
nums[min] = tmp;
}
}
public static void main(String[] args) {
int[ ] nummer=einlesen();
sort(nummer);
for(int i = 0; i < nummer.length; i++)
System.out.print(nummer[i]+“ „);
System.out.println();
}
}
73
Arrays
Beispiel: Sortieren eines Feldes
public class ArraySortMethViele {
public static int[ ] einlesen() {
int [ ] nums = new int[10];
for (int i = 0; i < nums.length; i++)
nums[i] = (int) (Math.random() * 10);
for (int i = 0; i < nums.length; i++)
System.out.print(nums[i]+“ „);
System.out.println();
return nums;
}
public static void ausgabe (int[ ] nums) {
for (int i = 0; i < nums.length; i++)
System.out.print(nums[i]+“ „);
System.out.println();
}
public static void sort(int[ ] nums) {
for (int i = 0; i < nums.length; i++) {
int min = i;
for (int j = i; j < nums.length; j++)
if (nums[j] < nums[min]) min = j;
int tmp;
tmp = nums[i];
nums[i] = nums[min];
nums[min] = tmp;
}
}
public static void main(String[] args) {
int[ ] nummer=einlesen();
sort(nummer);
ausgabe(nummer);
}
}
74
Arrays
Beispiel: Sortieren eines Feldes
public class ArraySortMethViele {
public static int[] einlesen() {
int [ ] nums = new int[10];
for (int i = 0; i < nums.length; i++)
nums[i] = (int) (Math.random() * 10);
for (int i = 0; i < nums.length; i++)
System.out.print(nums[i]+“ „);
System.out.println();
return nums;
}
public static void ausgabe(int[ ] nums) {
for (int i = 0; i < nums.length; i++)
System.out.print(nums[i]+“ „);
System.out.println();
}
public static void sort(int[ ] nums) {
for (int i = 0; i < nums.length; i++) {
int min = i;
for (int j = i; j < nums.length; j++)
if (nums[j] < nums[min]) min = j;
int tmp;
tmp = nums[i];
nums[i] = nums[min];
nums[min] = tmp;
}
}
public static void main(String[] args) {
int[ ] nummer=einlesen();
sort(nummer);
ausgabe(nummer);
}
}
75
Klassen und Objekte
Objektorientierte Softwareentwicklung
Was ist Objektorientierung ?
Oberflächlich betrachtet bedeutet der Begriff "objektorientiert", daß wir
Software als eine Ansammlung diskreter Objekte betrachten, die sowohl
Datenstruktur als auch Verhalten in sich vereinen. Dies steht im Gegensatz
zur konventionellen Programmierung, bei der Datenstruktur und Verhalten
nur lose miteinander verbunden sind. Es ist nicht ganz unstrittig, welche
Eigenschaften ein objektorientierter Ansatz genau erfordert. Im allg.
gehören jedoch vier Aspekte dazu: Identität, Klassifikation,
Polymorphismus und Vererbung
76
Klassen und Objekte
Eigenschaften von Objekten
Identität heißt, daß Daten mit diskreten, unterscheidbaren Entitäten Objekte
zugeordnet werden. Ein Absatz in einem Dokument, ein Fenster auf einer
Workstation und die weiße Dame in einem Schachspiel sind Beispiele für
Objekte. Jedes Objekt besitzt eine eigene inhärente ("ihm innenwohnende")
Identität. Mit anderen Worten, zwei Objekte sind klar voneinander
unterscheidbar, selbst wenn alle ihre Attributwerte (wie Name oder Größe)
identisch sind.
Klassifikation bedeutet, daß Objekte mit der gleichen Datenstruktur
(Attribute) und dem gleichen Verhalten (Operationen) zu einer Klasse
gruppiert werden. Eine Klasse ist eine Abstraktion, die die Eigenschaften
beschreibt, die für eine Anwendung wichtig sind, und den Rest ignoriert. Die
Wahl von Klassen ist immer beliebig und hängt von der Anwendung ab.
Jede Klasse beschreibt eine möglicherweise unendliche Menge individueller
Objekte. Jedes Objekt wird als eine Instanz seiner Klasse bezeichnet. Jede
Instanz der Klasse besitzt eigene Werte für alle ihre Attribute, während sie
die Attributnamen und Operationen mit anderen Instanzen der Klasse teilt.
Ein Objekt enthält eine implizite Referenz auf seine eigene Klasse, so daß
es "weiß", welcher Klasse es angehört. Polymorphismus bedeutet, daß sich
die gleiche Operation in unterschiedlichen Klassen unterschiedlich verhalten
kann. Das Verhalten der Operation verschieben zum Beispiele ist in der
Klasse Fenster ein anderes als in der Klasse Schachfigur. Eine Operation
ist eine Aktion oder Transformation, die ein Objekt ausführt bzw. die auf
dem Objekt ausgeführt wird. Rechtsbündig ausrichten, anzeigen und
verschieben sind Beispiele für Operationen. Eine spezifische
Implementierung einer Operation innerhalb einer bestimmten Klasse heißt
Methode. Weil ein objektorientierter Operator polymorph ist, kann es mehr
als eine Methode geben, die ihn implementiert. Vererbung bezeichnet die
gemeinsame Verwendung von Methoden und Operationen durch
verschiedene Klassen auf der Basis einer hierarchischen Relation. Eine
Klasse kann sehr allgemein definiert sein und dann in immer detaillierteren
Unterklassen verfeinert werden. Jede Unterklasse übernimmt oder erbt alle
Eigenschaften ihrer Oberklasse und fügt ihre eigenen individuellen
Eigenschaften hinzu. Die Eigenschaften der Oberklasse müssen nicht in
jeder Unterklasse wiederholt werden.
77
Klassen und Objekte
Begriffe und Paradigmen der objektorientierten Technologie
Abstraktion:
Eine geistige Fähigkeit des Menschen, Probleme der realen Welt mehr
oder weniger detailliert zu betrachten, je nach dem aktuellen Kontext
des Problems.
Kapselung: (Information Hiding)
Eine Modellierungs- und Implementierungstechnik, die die externen
Aspekte eines Objekts von den internen Implementierungsdetails des
Objekts trennt
Vererbung: (Inheritance)
Ein objektorientierter Mechanismus, der es ermöglicht, daß Klassen
Attribute und Operationen gemeinsam nutzen. Basiert auf einer
Relation, meistens auf Generalisierung.
Einfachvererbung:
Eine Art von Vererbung, bei der eine Klasse nur eine einzige
Oberklasse haben kann.
Mehrfachvererbung:
Eine Art von Vererbung, die es ermöglicht, daß eine Klasse mehr als
eine Oberklasse besitzt und Merkmale von allen Vorfahrenklassen erbt.
Polymorphismus:
Nimmt unterschiedliche Formen an; die Eigenschaft, daß eine
Operation sich auf unterschiedlichen Klassen unterschiedlich verhalten
kann.
Klassifikation:
Eine Gruppierung von Objekten mit der gleichen Datenstruktur und dem
gleichen Verhalten. Persistente Daten: Daten, die die Ausführung eines
bestimmten Programms überdauern.
Objektmodellierung:
Es existieren verschiedene Arten der Modellierung von Objekten: UML
(Unified Modeling Language), OMT (Object Modeling Technique),
Booch, Coad-Yourdon, etc.).
78
Klassen und Objekte
Prinzip der objektorientierten
Programmierung
•
Ein Gesamtprogramm besteht aus vielen unabhängigen Komponenten
(Objekten), die je eine bestimmte Rolle im Programm spielen und die
miteinander auf vorgegebene Weise (Methoden) sprechen.
Klassen, Objekte und Instanzen
•
Eine Klasse ist eine Sammlung aller Eigenschaften und Methoden der
Objekte dieser Klasse und legt fest, wie diese zu erzeugen sind
(Konstruktoren)
•
Eine Instanz einer Klasse ist ein anderes Wort für ein tatsächliches
Objekt. Während Klassen eine abstrakte Darstellung eines Objekts
sind, ist eine Instanz dessen konkrete Darstellung
•
Jede Klasse besteht im allgemeinen aus zwei Komponenten:
Eigenschaften und Methoden
•
Eigenschaften werden durch Variablen definiert (Instanzvariablen und
Klassenvariablen)
•
Methoden bestimmen, was Objekte alles machen können und was man
mit Objekten machen kann. Methoden sind Funktionen, die innerhalb
von Klassen definiert (Instanzmethoden und Klassenmethoden).
79
Klassen und Objekte
Klassen und Objekte in Java
Beispiel:
public class Circle {
private double x,y,r;//Instanzvariablen
´
// Die Konstruktormethode
public Circle(double x, double y, double r) {
this.x = x;
this.y = y;
this.r = r;
}
public double circumference()
{ return 2 * 3.14159 * r; }
public double area()
{ return 3.14159 * r*r; }
public static void main(String[ ] args) {
Circle c1 = new Circle(1,1,2);
Circle c2 = new Circle(2,2,4);
System.out.println(„Flaeche c1: „ + c1.area());
System.out.println(„Flaeche c2: „ + c2.area());
System.out.println(„Umfang c1: „ +
c1.circumference());
System.out.println(„Umfang c2: „ +
c2.circumference());
}
}
80
Klassen und Objekte
Objekte und Instanzen:
Circle c;
// Variable der
// Circle-Klasse
c = new Circle(1,1,2);
// Dynamisch erzeugte Instanz eines Circle-Objektes
Zugriff auf Objektdaten:
c.x = 2.0;
c.y = 2.0;
c.r = 1.0;
// Initialisiere den Kreis mit
// Mittelpunkt (2,2) und
// Radius 1.0
Verwendung von Objektmethoden:
Circle c = new Circle();
double a;
c.r = 2.5;
a = c.area();
Beachte: Es wird nicht
a = area(c);
verwendet, sondern
a = c.area();
Objekterzeugung:
Circle c = new Circle(); // Konstruktor
81
Klassen und Objekte
Konstruktoren:
Circle c = new Circle(1.414, -1.0, .25);

Der Name des Konstruktors ist immer mit dem Namen der Klasse
identisch

Der Rückgabewert ist implizit eine Instanz der Klasse.
Mehrere Konstruktoren:
public class Circle {
public double x,y,r; // Mittelpunkt + Radius
// Die Konstruktormethoden
public Circle(double x, double y, double r)
{ this.x = x; this.y = y; this.r = r;}
public Circle(double r)
{ x = 0; y = 0; this.r = r;}
public Circle(Circle c)
{ x = c.x; y = c.y; r = c.r;}
public Circle()
{ x = 0; y = 0; r = 1;}
// Methoden für Umfang und Fläche des Kreises
public double circumference()
{ return 2 * 3.14159 * r; }
public double area() {return 3.14159 * r*r; }
}
82
Klassen und Objekte
Kopieren von Objekten (by reference):
public class Circle {
public double x,y,r; // Instanzvariablen
// Die Konstruktormethoden
public Circle(double x, double y, double r)
{ this.x = x; this.y = y; this.r = r;}
public Circle(double r) {this(0.0,0.0,r);}
public Circle(Circle c) {this (c.x,c.y,c.r);}
public Circle(){this(0.0,0.0,1.0);}
public double circumference()
{ return 2 * 3.14159 * r; }
public double area() {return 3.14159 * r*r; }
public static void main(String[] args) {
Circle c1 = new Circle();
Circle c2 = new Circle(2,2,4);
System.out.println("Area c1: " + c1.area());
System.out.println("Area c2: " + c2.area());
c2=c1;
System.out.println("Area c1: " + c1.area());
System.out.println("Area c2: " + c2.area());
c1.r=2;
System.out.println("Area c1: " + c1.area());
System.out.println("Area c2: " + c2.area());
}
}
Ausgabe: Area c1: 3.14159
Area c2: 50.26544
Area c1: 3.14159
Area c2: 3.14159
Area c1: 12.56636
Area c2: 12.56636
83
Klassen und Objekte
Klassenvariablen:
public class Circle {
static int num_circles=0; //Klassenvariable:
//wie viele Kreise wurden erzeugt?
public double x,y,r; // Instanzvariablen
// Die Konstruktormethoden
public Circle(double x, double y, double r)
{ this.x = x; this.y = y; this.r = r;
num_circles++;}
public Circle(double r) {this(0.0,0.0,r);}
public Circle(Circle c) {this (c.x,c.y,c.r);}
public Circle(){this(0.0,0.0,1.0);}
public double circumference()
{ return 2 * 3.14159 * r; }
public double area() {return 3.14159 * r*r; }
}
Zugriff auf Klassenvariablen:
System.out.println(“Kreise: “ + Circle.num_circles);
Konstanten:
public class Circle {
public static final double PI=3.14159265;
public double x,y,r;
// ... etc.
}
84
Klassen und Objekte
Klassenmethoden:
public class Circle {
public double x,y,r;
// Liegt der Punkt (a,b) innerhalb des Kreises
public boolean isInside(double a, double b)
{
double dx = a - x;
double dy = b - y;
double distance = Math.sqrt(dx*dx+dy*dy);
if (distance<r) return true;
else return false;
}
// ... etc.
}
Math.sqrt() ist ein Aufruf einer Klassenmethode (oder statischen
Methode), die in Math definiert ist. Sie unterscheidet sich
wesentlich von den Instanzmethoden (wie z.B. area() in Circle).
85
Klassen und Objekte
Eine Klassenmethode für Kreise:
public class Circle {
public double x,y,r;
// Instanzmethode. Liefert den größeren Kreis
public Circle bigger (Circle c)
{ if (c.r > r) return c; else return this;}
// Klassenmethode. Liefert den größeren Kreis
public static Circle bigger (Circle a, Circle b)
{ if (a.r > b.r) return a; else return b; }
// ... etc.
}
Aufruf der Instanzmethode:
Circle a = new Circle (2.0);
Circle b = new Circle (3.0);
Circle c = a.bigger(b); // oder b.bigger(a);
Aufruf der Klassenmethode:
Circle a = new Circle (2.0);
Circle b = new Circle (3.0);
Circle c = Circle.bigger(a,b); // oder b.bigger(a);
86
Klassen und Objekte
Beispiele zu Klassen
Beispiel 1:
class Fahrzeug {
String marke;
String modell;
float preis;
float gewicht;
Fahrzeug (String mar, String mod, float pre, float gew) {
this.marke = mar;
this.modell = mod;
this.preis = pre;
this.gewicht = gew;
}
public String toString () {
return „Fahrzeug der Marke „ + marke + „, Modell „ + modell +
„, Gewicht „ + gewicht + „ kg“;
}
public static void main (String args[]) {
Fahrzeug ente = new Fahrzeug („Citroen“,“2CV“,8399.90f, 680.5f);
System.out.println(„Mein Auto: „+ ente);
}
}
87
Klassen und Objekte
Beispiele zu Klassen
Beispiel 2:
public class Bruch {
long z,n;
Bruch (long z, long n) {
this.z=z;
this.n = n;
this.kuerzen();
}
public Bruch add(Bruch b) {
long z1 = this.z * b.n;
long n = this.n * b.n;
long z2 = b.z * this.n;
return new Bruch(z1 + z2, n);
}
public Bruch add(long z) {
long z1 = this.z;
long n = this.n;
long z2 = z * this.n;
return new Bruch(z1 + z2, n);
}
public Bruch kuerzen() {
long limit = Math.min(z,n) / 2;
while (z % 2 == 0 && n % 2 == 0) {
this.z = this.z/2;
this.n = this.n/2;
}
88
Klassen und Objekte
Beispiele zu Klassen
for (long i = 3; i <= limit; i+=2) {
while (z % i == 0 && n % i == 0) {
this.z = this.z/i;
this.n = this.n/i;
}
}
return this;
}
public String toString() {
if (n == 1)
return Long.toString(z);
else
return z + „/“ + n;
}
}
public class MyBruch {
public static void main(String args[ ]) {
Bruch z1 = new Bruch(1,2);
System.out.println(„z1 = „ + z1);
Bruch z2 = new Bruch(10, 16);
System.out.println(„z2 = „ + z2);
Bruch z3 = new Bruch(3,8);
System.out.println(„z3 = „ + z3);
System.out.println(„z4 = „ + z3.add(z2));
System.out.println(„z6 = „ + z3.add(5L));
System.out.println(„z5 = „ +
new Bruch(128, 256));
}
}
89
Aufgaben
Aufgaben zu Klassen
Aufgabe 1
Schreibe eine Klasse, die die komplexen Zahlen repräsentiert.
1.
2.
Erstelle einen oder mehrere geeignete Konstruktoren zur Instanziierung
von komplexen Zahlen
Erstelle Instanzenmethoden für folgende Operationen:
–
Stringdarstellung einer komplexen Zahl.
–
Addition/Subtraktion zweier komplexer Zahlen. Das Ergebnis ist
eine neue komlexe Zahl
–
Multiplikation zweier komplexer Zahlen. Das Ergebnis ist eine
neue komlexe Zahl.
Aufgabe 2
Schreibe eine Klasse, die Polynome 2. Grades repräsentiert. Ein Polynom d
ieser Klasse hat allgemein das folgende Aussehen:
ax² + bx + c
1.
2.
Erstelle einen oder mehrere geeignete Konstruktoren zur Instanziierung
von Polynomen 2. Grades
Erstelle Instanzenmethoden für folgende Operationen:
–
–
–
–
–
Stringdarstellung eines Polynoms
Berechnen des Funktionswertes eines Polynoms
Addition/Subtraktion zweier Polynome. Das Ergebnis ist ein neues
Polynom
Multiplikation mit einem Skalar. Das Ergebnis ist ein neues
Polynom.
Berechnung der Nullstellen des Polynoms.
90
Vererbung von Klassen
Vererbung
Motivation
Beispiel:
Benutzerverwaltung (z.B. im Rechenzentrum) mit mehreren Kategorien von
Benutzern. Studenten, Mitarbeiter und externe Personen. Für Personen aus
den verschiedenen Gruppen werden unterschiedliche Informationen
erhoben.
Beispiel Benutzergruppen: externer Benutzer Person
class Person {
int userId;
String name;
String telNr;
Person(int id, String name, String tel) {
this.userId = id;
this.name = name;
this.telNr = tel;
}
}
Beispiel Benutzergruppen: Student
class Student {
int userId;
String name;
String telNr;
String matrNr;
Student(int id, String name,
String tel, String matrNr) {
this.userId = id;
this.name = name;
this.telNr = tel;
this.matrNr = matrNr;
}
}
91
Vererbung von Klassen
Beispiel Benutzergruppen: Mitarbeiter
class Mitarbeiter {
int userId;
String name;
String telNr;
String dienstgrad;
Mitarbeiter(int id, String name, String tel, String grad) {
this.userId = id;
this.name = name;
this.telNr = tel;
this.dienstgrad = grad;
}
}
Frage:
Können wir alle drei Benutzergruppen in einem einzigen Feld gemeinsam
verwalten?
Einfache Antwort:
Nein, denn es handelt sich um drei verschiedene Klassen; die Objekte
haben verschiedenenTyp.
Komplizierte Antwort:
Doch, wir können die Objekte in einem einzigen Feld speichern, wenn wir
die Gemeinsamkeitender drei Klassen extrahieren!
Beobachtung: Die gemeinsame Information von Studenten und Mitarbeitern
ist die Information, die für Personen gespeichert wird.
92
Vererbung von Klassen
Vererbung: Grundprinzip
Student und Mitarbeiter erben diese Attribute von Person; alles was man mit
einer Instanz der Klasse Person machen kann, kann man auch mit einer
Instanz der Klassen Mitarbeiter und Student machen!
93
Vererbung von Klassen
Vererbung: Grundprinzip
94
Vererbung von Klassen
Vererbung in Java
class Person {
int userId;
String name;
String telNr;
Person( ){
}
Person(int id, String name, String tel) {
this.userId = id;
this.name = name;
this.telNr = tel;
}
}
Die Klasse Person wird fast wie gehabt definiert. Aus einem Grund, den wir
später noch kennen lernen werden, benötigen wir im Augenblick noch den
Standardkonstruktor.
class Student extends Person {
String matrNr;
Student(int id, String name,
String tel, String matrNr) {
this.userId = id;
this.name = name;
this.telNr = tel;
this.matrNr = matrNr;
}
}
extends besagt, daß die Klasse Student von der Klasse Person erbt.
Weil die Klasse Student von der Klasse Person erbt, besitzt die Klasse
Student alle Attribute der Klasse Person (ohne daß die Attribute explizit
definiert sind).
95
Vererbung von Klassen
class Mitarbeiter extends Person {
String dienstgrad;
Mitarbeiter(int id, String name,
String tel, String grad) {
this.userId = id;
this.name = name;
this.telNr = tel;
this.dienstgrad = grad;
}
}
extends besagt, daß die Klasse Mitarbeiter von der Klasse Person erbt.
Weil die Klasse Mitarbeiter von der Klasse Person erbt, besitzt die Klasse
Mitarbeiter alle Attribute der Klasse Person (ohne daß die Attribute explizit
definiert sind).
Bemerkung:
Die neuen Definitionen sind im wesentlichen identisch mit den alten
separaten der Definitionen der Klassen.
Der einzige Unterschied:
Jetzt können Objekte der Klasse Student und Mitarbeiter an eine Variable
des Typs Person zugewiesen werden, da sie diese Klasse spezialisieren!
Person[ ] pers = new Person[3];
pers[0] = new Mitarbeiter(1,"Huber","(030) ...","WiMi");
pers[1] = new Student(2,"Meier", "(08421) 4711","0815");
pers[2] = new Person(5,"Mueller","(08421) 461");
96
Vererbung von Klassen
Beispiel:
Person[ ] pers = new Person[3];
pers[0] = new Mitarbeiter(1,"Huber", "(030) ...", "WiMi");
pers[1] = new Student(2,"Meier", "(08421) 4711", "0815");
pers[2] = new Person(5,"Mueller", "(08421) 461");
// Ausgabe aller Adressen des Arrays pers:
for (int i = 0; i < pers.length; i++) {
System.out.println(pers[i].name + ":" + pers[i].telNr);
}
Das Prinzip:
•
•
Ein Objekt einer Klasse B, die von Klasse A abgeleitet ist (von A erbt),
besitzt zusätzlich zu den in der Klasse B definierten Attributen und
Methoden alle Attribute und Methoden der Klasse A.
Ein Objekt einer Klasse B kann an eine Variable der Klasse A
zugewiesen werden, wenn Klasse B von Klasse A abgeleitet ist.
Beispiel:
Person pers;
pers = new Mitarbeiter(1,"Huber", "(030) ...", "WiMi");
•
Die umgekehrte Richtung ist nicht zulässig!
Gegenbesipiel:
Mitarbeiter marb;
marb = new Person(1,"Huber", "(030) ...");
•
•
Ein Objekt, das in einer Variablen der Klasse A gespeichert ist, kann ein
Objekt jeder Klasse B sein, die von A erbt.
Für ein in einer Variablen der Klasse A gespeichertes Objekt können
alle Attribute und Methoden der Klasse A benutzt werden —und nur
diese! Selbst dann, wenn es sich um ein Objekt der Klasse B handelt,
das mehr Attribute besitzt.
97
Vererbung von Klassen
Beispiel:
Person pers;
pers = Mitarbeiter(1,"Huber", "(030) ...", "WiMi");
System.out.println(pers.name + ":" + pers.telNr);
System.out.println(pers.dienstgrad);
Das Objekt, das in pers gespeichert ist, hat zwar ein Attribut dienstgrad,
aber die Variable pers hat nur den Typ Person! Da die Klasse Person selbst
kein Attribut dienstgrad besitzt, dürfen wir es nicht benutzen.
Bei starker Typisierung wird die Korrektheit eines Zugriffs anhand des
Variablentyps geprüft!
98
Vererbung von Klassen
Vererbungshierarchie
Beamter erbt indirekt über
Mitarbeiter alle Eigenschaften von
Person!
Ein Objekt der Klasse Beamter
kann also sowohl einer Variablen
vom Typ Mitarbeiter als auch einer
Variablen vom Typ Person
zugewiesen werden.
class Beamter extends Mitarbeiter
{
String besGr;
...
}
99
Vererbung von Klassen
Vererbung von Methoden
Methoden werden ebenso vererbt wie Attribute!
class Person {
int userId;
String name;
String telNr;
Person() {
}
Person(int id, String name, String tel)
{ \* wie gehabt *\}
public String toString() {
return name + ": " + telNr}
}
Person pers = new Person(5,"Mueller", "(08421) 461");
Person pers = new Person(6,"Maier", "(08421) 462");
System.out.println(pers.toString());
System.out.println(pers);
Ausgabe am Bildschirm:
Mueller: (08421) 461
Maier: (08421) 462
Mitarbeiter marb;
marb = Mitarbeiter(1,"Huber", "(030) ...", "WiMi");
System.out.println(marb);
Ausgabe am Bildschirm: Huber: (030) ...
Da Mitarbeiter von Person erbt, besitzt jedes Objekt der Klasse Mitarbeiter
auch die Methode toString.
100
Vererbung von Klassen
Überschreiben von Methoden
Bisher:
In den abgeleiteten Klassen wurden neue Attribute oder neue Methoden
hinzugefügt.
Jetzt:
In der abgeleiteten Klasse werden Methoden der ursprünglichen Klasse
überschrieben.
Beispiel:
class Mitarbeiter extends Person {
String dienstgrad;
Mitarbeiter(int id, String name,
String tel, String grad)
{ \* wie gehabt *\ }
public String toString()
{ return name + ":" + tel +","+dienstgrad;}
}
class Student extends Person {
String matrNr;
Student(int id, String name,
String tel, String matrNr)
{ /* wie gehabt */ }
public String toString()
{ return name + ":" + tel + ", " + matrNr; }
}
101
Vererbung von Klassen
Person[ ] pers = new Person[3];
pers[0] = new Mitarbeiter(1,"Huber", "(030) ...", "WiMi");
pers[1] = new Student(2,"Meier", "(08421) 4711", "0815");
pers[2] = new Person(5,"Mueller", "(08421) 461");
for (int i = 0; i < pers.length; i++)
{ System.out.println(pers[i]); }
/* Ausgabe am Bildschirm:
* Huber: (030) ..., WiMi
* Meier: (08421) 4711, 0815
* Mueller: (08421) 461
*/
Hier wurden offensichtlich die neuen toString-Methoden der
Klassen Mitarbeiter und Student aufgerufen.
102
Vererbung von Klassen

Eine Unterklassenbeziehung läßt sich explizit in der folgenden Form
angeben:
class Unterklasse extends Oberklasse {
....
}

Die Unterklasse enthält alle Komponenten der Oberklasse.

Erweiterbar um neue Komponenten

Unterklasse ist Spezialfall der Oberklasse

Komponenten der Oberklasse sind von der Unterklasse aus mit dem
Schlüsselwort super erreichbar. Dies gilt auch für den Aufruf des
Konstruktors derOberklasse.

Klassen, für die keine Beziehung zu anderen Klassenfest gelegt wurde,
sind automatisch Unterklassen der Klasse Object.
103
Vererbung von Klassen
Beispiel: „Chefs sind auch Personen“
class Person {
String Name;
String Vorname;
int PersonalNummer;
Person (String Name, String Vorname, int PersonalNummer) {
this.Name = Name;
this.Vorname = Vorname;
this.PersonalNummer = PersonalNummer;
}
void print() {
System.out.println("Name: "+ this.Name);
System.out.println("Vorname: "+ this.Vorname);
System.out.println("Personalnummer: "+
this.PersonalNummer);
}
}
class Chef extends Person {
String Abteilung; //Zusaetzliches Attribut
Chef (String Name, String Vorname, int PersonalNummer, String Abteilung) {
super(Name,Vorname,PersonalNummer);
this.Abteilung=Abteilung;
}
// Ueberschreibt die Methode print() in Person
void print() {
super.print();
System.out.println("Leiter der Abteilung: "+
this.Abteilung);
}
}
104
Vererbung von Klassen
Beispiel: Verwendung der Klassen Person und Chef
public class Firma {
public static void main (String args[ ]) {
Person personal[] = new Person [4];
personal [0] = new Person („Meier“, „Karl“, 100);
personal [1] = new Person („Huber“, „Egon“, 101);
personal [2] = new Person („Bauer“, „Hans“, 102);
personal [3] = new Chef („Wichtig“, „Willi“, 103,“Einkauf“);
for (int i =0; i< personal.length; i++)
personal[i].print(); // Polymorphie
}
}
105
Vererbung von Klassen
Beispiel: Klasse Fahrzeug
class Fahrzeug {
String marke;
String modell;
float preis;
float gewicht;
Fahrzeug (String mar, String mod, float pre, float gew) {
this.marke = mar;
this.modell = mod;
this.preis = pre;
this.gewicht = gew;
}
public String toString () {
return "Fahrzeug der Marke " + marke + ", Modell " + modell + ",
Gewicht " + gewicht + " kg";
}
public static void main (String args[ ]) {
Fahrzeug ente = new Fahrzeug("Citroen","2CV", 8399.90f, 680.5f);
System.out.println("Mein Auto: "+ ente);
}
}
106
Vererbung von Klassen
Beispiel: Erweiterung der Klasse Fahrzeug
class Auto extends Fahrzeug {
String kraftstoff;
int ps;
Auto (String mar, String mod, float pre, float gew, String kra, int ps) {
super(mar,mod,pre,gew);
this.kraftstoff = kra;
this.ps = ps;
}
public String toString () {
return super.toString() + ", " + kraftstoff +
"-Kraftstoff, " + ps + " ps";
´ }
public static void main (String args[ ]) {
Auto ente = new Auto("Citroen","2CV", 8399.90f,
680.5f,"Normal",28);
System.out.println("Mein Auto: "+ ente);
}
}
107
Vererbung von Klassen
Objektklasse Object
108
Vererbung von Klassen
Vergleich von Objekten
•
Vergleich von primitiven Datentypen:
int i1 = 12;
int i2 = 21;
int i3 = 12;
System.out.println(i1+"=="+i2+ " ? " + (i1==i2));
System.out.println(i1+"=="+i3+ " ? " + (i1==i3));
System.out.println(i2+"=="+i3+ " ? " + (i2==i3));
System.out.println();
•
Ausgabe:
K:\java-vorlesung\code>java -classpath . Bruch
12==21 ? false
12==12 ? true
21==12 ? false
•
Vergleich von Objekten:
public static void main(String argv[]) {
Bruch b1 = new Bruch(13,3);
Bruch b2 = new Bruch(3,13);
Bruch b3 = new Bruch(13,3);
Bruch b4 = b2;
System.out.println(b1+"=="+b2+ " ? " + (b1==b2));
System.out.println(b1+"=="+b3+ " ? " + (b1==b3));
System.out.println(b1+"=="+b4+ " ? " + (b1==b4));
System.out.println(b2+"=="+b4+ " ? " + (b2==b4));
System.out.println();
System.out.println(b1+".equals("+b2+")?"+ (b1.equals(b2)));
System.out.println(b1+".equals("+b3+")?"+ (b1.equals(b3)));
System.out.println(b1+".equals("+b4+")?"+ (b1.equals(b4)));
System.out.println(b2+".equals("+b4+")?"+ (b2.equals(b4)));
109
Vererbung von Klassen
•
Ausgabe:
K:\java-vorlesung\code>java -classpath . Bruch
12==21 ? false
12==12 ? true
21==12 ? false
13/3==3/13 ? false
13/3==13/3 ? false
13/3==3/13 ? false
3/13==3/13 ? true
13/3.equals(3/13) ? false
13/3.equals(13/3) ? false
13/3.equals(3/13) ? false
3/13.equals(3/13) ? true
•
Eigene Methode: public boolean equals(Object o)
public boolean equals(Object o) {
if (o instanceof Bruch) {
Bruch b = (Bruch) o;
return this.zaehler == b.zaehler && this.nenner == b.nenner;
} else
return false;
}
•
Ausgabe:
...
13/3.equals(3/13) ? false
13/3.equals(13/3) ? true
13/3.equals(3/13) ? false
3/13.equals(3/13) ? true
110
Vererbung von Klassen
Daten verstecken und kapseln
Sichtbarkeitsmodifikatoren:
 public
Klasse, Variable oder Methode überall sichtbar
und damit auch überall benutzbar

private
private-Variable sind nur in den Methoden sichtbar, die in
dieser Klasse definiert sind.
private-Methoden können nur von Methoden innerhalb der
Klasse aufgerufen werden.
private-Elemente (members) sind nicht in Subklassen
sichtbar und werden auch nicht an Subklassen vererbt.

protected
protected-Elemente sind in allen Subklassen dieser
Klasse sichtbar, und auch in allen Klassen, die mit dieser
Klasse in einem Paket enthalten sind.

„friendly“ oder „package“
Standardmäßige Paketsichtbarkeit, die verwendet wird, wenn ein
Element einer Klasse mit keinem der Schlüsselworte public, private
oder protected dekalriert ist.
111
Vererbung von Klassen
Erreichbarkeit von Klassenelementen
Sichtbarkeit
Erreichbar für
public
protected
friendly
private
Gleiche Klasse
Ja
Ja
Ja
Ja
Klasse im gleichen Paket
Ja
Ja
Ja
Nein
Subklasse im anderen Paket
Ja
Ja
Nein
Nein
Keine Subklasse, anderes Paket
Ja
Nein
Nein
nein
112
Aufgaben
Aufgaben zu Klassen
Aufgabe 1
Schreibe eine Klasse welche Terme der Form
ax y
repräsentiert. (Beispiel: 2x 4 , 3x 9 , -2x 2 ..). Hierbei können folgende
Vereinfachungen vorgenommen werden: a ganzzahlig, y ganzzahlig
und >= 0.
1.
Erstelle einen oder mehrere geeignete Konstruktoren
2.
Erstelle Instanzenmethoden für folgende Operationen:
–
–
–
–
Stringdarstellung eines Terms
Berechnen des Funktionswertes eines Terms
Multiplikation zweier Terme. Das Ergebnis ist ein neuer Term
Berechnung der Ableitung eines Terms
Aufgabe 2
Schreibe eine Klasse welche ein Haushaltsbuch repräsentiert.
1.
Erstelle einen oder mehrere geeignete Konstruktoren
2.
Erstelle Instanzenmethoden für folgende Operationen:
–
–
–
–
–
Einzahlung mit Kommentar (Bsp: 100 DM von Oma)
Auszahlung mit Kommentar. (Bsp: 10 DM für Kino)
Abfrage aller Einzahlungen
Abfrage aller Ausgaben
Abfrage des aktuellen Kontostandes
113
Aufgaben
Aufgaben zu Klassen
Aufgabe 1
Schreibe eine Klasse zur Repräsentation von
Polynomen beliebiger Ordnung. Nutze hierzu die in
Aufgabe 2 des vorhergehenden Übungsblattes
entwickelte Klasse Term.
Bsp: 2x 4 + 3x 3 -2x 2 + 5x -10
1.
Erstelle einen oder mehrere geeignete Konstruktoren
2.
Erstelle Instanzenmethoden für folgende Operationen:
–
–
–
–
Stringdarstellung eines Polynoms
Berechnen des Funktionswertes an beliebiger Stelle eines
Polynoms
Addition/Subtraktion zweier Polynome. Das Ergebnis ist ein neues
Polynom
Berechnung der Ableitung eines Polynoms. Das Ergebnis ist ein
neues Polynom.
114
Aufgaben
Aufgaben zu Klassen
Aufgabe 1
Schreibe ein einfaches Programm zum Speichern von
Adressen. Zur Vereinfachung genügt es, wenn nur eine
feste Anzahl von Adressen gespeichert werden kann.
Aufgabe 2
Der folgende Algorithmus („Siebes von Eratostenes“) ermittelt alle
Primzahlen zwischen 2 und einer vorgegebenen Grenze N:
1.
SIEB = alle natürlichen Zahlen von 2 bis N
2.
Primzahlen = leere Menge
3.
wiederhole die Schritte (4) bis (6) solange, bis SIEB leer wird
4.
bestimme die kleinste Zahl MIN in SIEB
5.
füge MIN zu Primzahlen hinzu
6.
entferne MIN und alle seine ganzahligen Vielfachen aus SIEB
Schreibe ein Programm, das diesen Algorithmus implementiert.
115
Exceptions
Exceptions und ihre Behandlung

Exception - Ausnahmebedingung (wie z.B. Fehler)

Exception erzeugen (engl. throw) - bedeutet Ausnahmebedingung zu
signalisieren

Exception abfangen (engl. catch) – bedeutet ein Ausnahmebedingung
zu behandeln, d.h. alle Aktionen durchzuführen, die notwendig sind um
den normalen Zustand wiederherzustellen
Exception-Objekte
Eine Exception ist in Java ein Objekt, nämlich eine Instanz irgendeiner
Unterklasse von java.lang.Thro-wable.
Throwable besitzt 2 Standardunterklassen:
•
java.lang.Error
für Probleme beim dynamischen Laden oder bei Probleme der JVM. Sie
werden i.d.R. nicht abgefangen
•
java,lang,Exception
Exceptions dieser Unterklasse weisen auf Bedingungen hin, die
abgefangen und behoben werden können, z.B.
java.io.EOFException oder
java.lang.ArrayAccessOutofBounds.
116
Exceptions
Exception-Handling
try/catch/finally-Anweisung zum Exception-Handling:
•
try - stellt eine Codeblock zur Verfügung mit dem Exceptions
und abnormale Abbrüche behandelt werden
•
catch - dem try-Block folgen null oder mehr catch-Klauseln, die
bestimmte Exception-Typen abfangen und behandeln
•
finally - den catch-Klauseln folgt optional ein finally Block, der hinterher
„aufräumt“. Die Anweisungen eines finally-Blocks werden garantiert
ausgeführt, gleichgültig mit welchem Status der try-Block beendet wird.
Beispiel:
try {
/* Programmcode der Exceptions erzeugt */
}
catch ( Typ1 e1) {
/* Behandle Exception e1 vom Typ Typ1 */
}
catch ( Typ e2 ) {
/* Behandle Exception e2 vom Typ Typ2 */
}
finally {
/* Dieser Code wird immer ausgeführt */
}
117
Exceptions
Beispiel:
public class ExceptionMethods {
public static void main(String[ ] args) {
try {
throw new Exception („Meine Exception“);
}
catch ( Exception e) {
System.out.println(„Exception gefangen“);
System.out.println(„e.getMessage(): „+
e.getMessage());
}
}
}
Ausgabe:
Exception gefangen
e.getMessage(): Meine Exception
Einige Methoden von Throwable:
String getMessage()
Gibt die Beschreibung der Exception zurück.
String to String()
Gibt eine kurze Beschreibung von Throwable einschließlich der
detailierten Beschreibung.
System.out.println(e.toString());
Ausgabe: java.lang.Exception: Meine Exception
void printStackTrace()
Gibt Throwable unbd den Call Stack Trace zurück.
e.printStackTrace();
Ausgabe: java.lang.Exception: Meine Exception
at ExceptionMethods.main
118
Exceptions
Exceptions deklarieren
Java erfordert, daß jede Methode, die eine Exception
verursachen kann, diese entweder abfangen oder in der
Methodendeklaration den Typ der Exception mit einer throwsKlausel abgeben muß.
Beispiel:
public void open_file() throws IOException {
/* Hier stehen Anweisungen, die eine nicht abgefangene
java.io.IOException veruraschen können. */
}
public void myfunc () throws tooBig, tooSmall, divZero{
/* Hierbei entstehen die Exceptions tooBig, tooSmall, divZero
die nicht abgefangen werden. */
}
Eigene Exceptions definieren und erzeugen
Neben den Standard Java Exception (Klasse Throwable mit
Unterklassen Error und Exception, siehe java.sun.com)
können auch eigene Exceptions definiert werden.
119
Exceptions
Beispiel:
class MyException extends Exception{
public MyException () {}
public MyException (String msg) {
super (msg);
}
}
public class Inheriting {
public static void f() throws MyException {
System.out.println(„Throwing MyException from f()“);
throw new MyException();
}
public static void g() throws MyException {
System.out.println(„Throwing MyException from g()“);
throw new MyException(„originated in g()“);
}
public static void main(String[] args) {
try {
f();
}
catch ( MyException e) {
e.printStackTrace()
}
try {
g();
}
catch ( MyException e) {
e.printStackTrace()
}
}
}
120
Exceptions
Ausgabe:
Throwing MyException from f()
My Exception
at Inheriting.f (Inheriting.java:16)
at Inheriting.main (Inheriting.java:24)
Throwing MyException from g()
My Exception: originated in g()
at Inheriting.f (Inheriting.java:20)
at Inheriting.main (Inheriting.java:29)
121
Exceptions
Exception Matching
Der Exception-Handler sucht in den catch-Klauseln, die erste
die „paßt“. Matching einer Exception erfordert kein genaues
„passen“ . Ein Objekt einer erweiterten Klasse wird auch von
einer catch-Klausel der Basis-Klasse gefangen:
Beispiel:
class Annoyance extends Exception{}
class Sneeze extends Annoyance{}
public class Human () {
public static void main(String[] args) {
try {
throw new Sneeze();
}
catch (Sneeze s) {
System.out.println(„Caught Sneeze“);
}
catch (Annoyance a) {
System.out.println(„Caught Annoyance“);
}
}
}
122
Exceptions
Die Sneeze Exception wird natürlich von der ersten CatchKlausel gefangen.
Wenn die erste Catch-Klausel gelöscht wird, so ist der code
immer noch lauffähig, da catch (Annoyance) alle AnnoyanceExceptions oder von ihr abgeleiteten Exceptions fängt.
Umdrehen der catch-Klauseln zu
try {
throw new Sneeze();
}
catch (Annoyance a) {
System.out.println(„Caught Annoyance“);
}
catch (Sneeze s) {
System.out.println(„Caught Sneeze“);
}
führt zu einem Fehler beim compilieren, da der Compiler,
erkennt, daß die Sneeze-Catch-Klausel nie erreicht wird.
123
Interface
Schnittstellenvererbung: interface,
implements

Java kennt keine Mehrfachvererbung im Sinne der
Implementierungsvererbung (extends)

Durch Vererbung via implements können Schnittstellen vererbt werden

Definition von Schnittstellen:
interface statt class

Implementierung von Schnittstellen:
implements statt extends

Unterschiede zwischen Vererbung und Interfaces:

Eine Klasse kann mehrere Interfaces, aber immer nur eine direkte
Oberklasse besitzen

Ein Interface hat keine Implementierung, sondern legt nur eine
Schnittstelle fest

Oberklasse implementiert i.a. das gemeinsame Verhalten von
mehreren Unterklassen

Interface legt eine gemeinsame Schnittstelle fest, ohne eine
Hierarchie aufzubauen
124
Interface
Beispiel:
// Definition der Schnittstelle
interface CDPlayer {
public void playNextTitle ();
}
interface Tuner {
public void getNextRadioStation ();
}
// Ein Server implementiert die Schnittstellen
class StereoAnlage extends Elektrogeraet implements CDPlayer, Tuner, etc. {
// Die Implementierung wurde versprochen.
// Nun wird sie vom Java-Compiler eingefordert!
public void playNextTitle () {
// Hier kommt die Implementierung hin!
}
public void getNextRadioStation (){
// Hier kommt die Implementierung hin!
}
}
// Ein Client benutzt die Geraete
class Wohnzimmer {
... Irgendeine Methode ...
// Neues Geraet kaufen
Stereoanlage hifikiste= new StereoAnlage (...);
// Das Geraet verspricht einiges....
.....
hifikiste.playNextTitle();
hifikiste.getNextRadioStation();
....
}
125
Interface
Beispiel:
public interface LautesTier {
public void gibtLaut() ;
}
public class Katze implements LautesTier {
public void gibtLaut() {
System.out.println("Miau!");
}
}
public class Hund implements LautesTier {
public void gibtLaut() {
System.out.println("Wau wau!");
}
}
public class Katzenmusik {
public static void main (String[] args) {
LautesTier tier1 = new Katze();
LautesTier tier2 = new Hund();
for (int i=1; i<=10; i++) {
tier1.gibtLaut();
tier2.gibtLaut();
}
}
}
126
Interface

Schnittstelle: Vertrag zwischen Auftraggeber (Client) und
Auftragnehmer (Server)

Implementierung der Funktionalität durch den
Auftragnehmer (Server)

Anwender (Clients) benötigen kein Wissen über Implementierungen von
irgendwelchen Objekten, sondern lediglich die Beschreibung der
Schnittstelle

Der Anbieter eines Dienstes (Server) implementiert den Dienst, indem
die Klasse von der Schnittstelle abgeleitet wird. Danach werden alle
Methoden des Dienstes überschrieben
Eine Klasse kann im Sinne dieser Theorie mehrere Schnittstellen
implementieren

127
Applets
•
„Minianwendung“ für die Ausführung in einem Web-Browser oder in
einem Applet-Viewe
•
Keine main ( )-Methode
•
Neues Applet ist Subklasse von Applet
•
Funktionalität des eigenen Applets durch Überschreiben von
Standardmethoden, die bei Bedarf aufgerufen werden:
init(), destroy(), start(), stop(), paint() etc.
•
Sicherheitsbeschränkungen (Kein Zugriff auf das lokale Dateisystem
„Sandkastenprinzip“)
128
Applets
Erstellen eines Applets:
import java.applet.*;
import java.awt.*;
public class FirstApplet extends Applet {
public void paint(Graphics g) {
g.drawString("Hello World", 25, 50);
}
}
Ausgabe des Applets:
HTML-Datei:
HTML>
<HEAD>
<TITLE>Das Zeichen-Applet</TITLE>
</HEAD>
<BODY>
<P>
<APPLET code="FirstApplet.class" width=500 height=300>
</APPLET>
</BODY>
</HTML>
129
Applets
Aufruf des Appletviewers:
appletviewer FirstApplet.html
Darstellung im Appletviewer
130
Applets
Darstellung im WWW-Browser
Öffnen mit Menüpunkt Open Page des File Menüs im Netscape Browser
131
Applets
Erstellen eines weiteren Applets
import java.applet.*;
import java.awt.*;
public class SecondApplet extends Applet {
static final String message = "Hello World";
private Font font;
public void init() {
font = new Font("Helvetica", Font.BOLD, 48);
}
public void paint(Graphics g) {
// The pink oval
g.setColor(Color.pink);
g.fillOval(10, 10, 330, 100);
g.setColor(Color.red);
g.drawOval(10,10, 330, 100);
g.drawOval(9, 9, 332, 102);
g.drawOval(8, 8, 334, 104);
g.drawOval(7, 7, 336, 106);
// The text
g.setColor(Color.black);
g.setFont(font);
g.drawString(message, 40, 75);
}
}
132
Applets
Die HTML-Datei
<HTML>
<APPLET code="SecondApplet.class" width=500 height=300>
</APPLET>
</HTML>
Aufruf des Appletviewers:
appletviewer SecondApplet.html
Darstellung im Appletviewer
133
Applets
Darstellung im WWW-Browser
Öffnen mit Menüpunkt Open Page des File Menüs im Netscape Browser
134
Applets
Weitere Beispiele
import java.awt.*;
import java.applet.Applet;
public class FirstShapes extends Applet {
public void paint (Graphics g) {
g.drawRect (30, 30, 80, 40);
g.drawOval (120, 30, 50, 50);
g.setColor (Color.black);
g.fillRect (30, 100, 80, 40);
g.fillOval (120, 100, 50, 50);
g.drawLine (30, 160, 130, 170);
g.drawArc (30, 180, 50, 50, 60, 40);
g.fillArc (120, 180, 50, 50, 60, 40);
}
}
HTML-Datei
<html>
<body>
<applet code=FirstShapes.class width=300 height=300>
</applet>
</body>
</html>
135
Applets
136
Applets
import java.applet.*;
import java.awt.*;
public class Scribble1 extends Applet {
private int lastx, lasty; //Letze Mauskoordinaten
Button clear_button; // Clear button
Graphics g; // Graphics Objekt zum Zeichnen
public void init() {
clear_button = new Button("Clear");
this.add(clear_button);
g = this.getGraphics();
}
public boolean mouseDown(Event e, int x, int y) {
lastx = x; lasty = y;
return true;
}
public boolean mouseDrag(Event e, int x, int y) {
g.setColor(Color.black);
g.drawLine(lastx, lasty, x, y);
lastx = x; lasty = y;
return true;
}
public boolean keyDown(Event e, int key) {
if ((e.id == Event.KEY_PRESS) && (key == ’c’)) {
clear();
return true;
}
else return false;
}
public boolean action(Event e, Object arg) {
if (e.target == clear_button) {
clear();
return true;
}
else return false;
}
public void clear() {
137
g.setColor(this.getBackground());
Applets
Applet zu Beginn
Applet nach dem Zeichnen
138
Events
Events
•
Grafische Anwendungen werden über Events gesteuert. D.h. sie
machen nichts, solange der Benutzer nicht die Maus bewegt, einen
Button anklickt oder eine Taste drückt.
•
Unterschiedliche Eventmodelle bei Java 1.0 und Java 1.1.
•
Viele Web-Browser benutzen noch das alte Eventmodell von Java 1.0
Das Event-Modell von Java 1.0
•
Alle Events werden durch die Event-Klasse repräsentiert.
(java.awt.Event) Diese Klasse besitzt eine Reihe von Instanzvariablen,
die das Event beschrieben.
•
Eine dieser Variablen (id) gibt zum Beispiel den Typ des Events an. In
der Klasse Event ist eine Reihe von Konstanten definiert, die mögliche
Werte des id-Feldes darstellen.
•
Events werden zuerst an die handleEvent()-Methode des ComponentObjektes übergeben, in dem sie aufgetreten sind. (Component ist die
Superklasse aller GUI-Komponenten).
139
Events
Das Event-Modell von Java 1.0
(Fortsetzung)
•
Die Standardimplementierung dieser Methode untersucht das id-Feld des
Event-Objektes und gibt die am häufigsten vorkommenden Typen an
verscheidene typspezifische Methoden weiter:
•
Die oben aufgeführten Methoden sind in der Component Klasse definiert.
Um die entsprechenden Events nach eigener Wahl behandeln zu
können, müssen diese Methoden durch eigene Methoden überschieben
werden. (Unter Umständen muß auch handleEvent() überschrieben
werden.)
•
Die Methode handleEvent() und alle typspezifischen Methoden liefern
boolean-Werte zurück. Gib eine Behandlungsmethode false zurück, dann
bedeutet das, daß das Event nicht verarbeitet wurde. Diese
unverarbeitete Event wird in der Hierarchie nach oben weitergegeben
und kann dort behandelt werden.
Liefert die Methode true zurück, ist dies ein SIgnal, daß das Event
verarbeitet wurde.
•
Die Verwendung des alten Java 1.0 Event-Modells erzeugt bei neueren
Java-Versionen eine „deprecation warning“.
140
Events
import java.applet.*;
import java.awt.*;
public class Scribble1 extends Applet {
private int lastx, lasty; //Letze Mauskoordinaten
Button clear_button; // Clear button
Graphics g; // Graphics Objekt zum Zeichnen
public void init() {
clear_button = new Button("Clear");
this.add(clear_button);
g = this.getGraphics();
}
public boolean mouseDown(Event e, int x, int y) {
lastx = x; lasty = y;
return true;
}
public boolean mouseDrag(Event e, int x, int y) {
g.setColor(Color.black);
g.drawLine(lastx, lasty, x, y);
lastx = x; lasty = y;
return true;
}
public boolean keyDown(Event e, int key) {
if ((e.id == Event.KEY_PRESS) && (key == ’c’)) {
clear();
return true;
}
else return false;
}
public boolean action(Event e, Object arg) {
if (e.target == clear_button) {
clear();
return true;
}
else return false;
}
public void clear() {
g.setColor(this.getBackground());
g.fillRect(0, 0, bounds().width, bounds().height);
}
}
141
Events
Das Event-Modell von Java 1.1
•
Bei diesem Event-Modell werden verschiedene Event-Klassen durch verschiedene
Java-Klassen repräsentiert.
•
Jedes Event ist eine Subklasse von java.util.EventObject.
•
Das Event-Modell basiert auf dem Konzept des „Event-Listeners“. Ein EventListener ist ein Objekt, das Events abfangen möchte. Ein Objekt, das Events
generiert (eine Event-Quelle, „event source“), pflegt eine Liste von Listenern, die
über auftretende Events informiert werden wollen, und stellt Methoden bereit, die es
den Listenern ermöglichen, sich selbst in diese Liste interessierter Objekte
einzutragen bzw. sich wieder aus ihr zu entfernen.
•
Wird ein Event ausgelöst, benachrichtigt die Event-Quelle alle Listener-Objekte,
daß ein Event aufgetreten ist.
Eine Event-Quelle benachrichtigt ein Event-Listener- Objekt durch den Aufruf einer
Methode und die Übergabe eines Event-Objektes. Damit eine Quelle eine Methode
des Listeners aufrufen kann, müssen alle Listener die verlangte Methode
implementieren. Das wird dadurch sichergestellt, daß alle Event-Listener eines
bestimmten Event-Typs ein entsprechendes Interface implementieren.
142
Events
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Scribble2 extends Applet implements MouseListener, MouseMotionListener {
private int last_x, last_y;
public void init() {
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
// Methode des MouseListener interface.
public void mousePressed(MouseEvent e) {
last_x = e.getX();
last_y = e.getY();
}
// Methode des MouseMotionListener interface.
public void mouseDragged(MouseEvent e) {
Graphics g = this.getGraphics();
int x = e.getX(), y = e.getY();
g.drawLine(last_x, last_y, x, y);
last_x = x; last_y = y;
}
// Die anderen Methoden des MouseListener interface.
public void mouseReleased(MouseEvent e) {;}
public void mouseClicked(MouseEvent e) {;}
public void mouseEntered(MouseEvent e) {;}
public void mouseExited(MouseEvent e) {;}
// Die anderen Methoden des MouseMotionListener interface.
public void mouseMoved(MouseEvent e) {;}
}
143
Events
Erstellen eines weiteren Applets:
import java.applet.*;
import java.awt.*;
import Polynom;
public class MyApplet extends Applet {
float skalierung;
float x_start = - 3;
float x_ende = -x_start;
int x_koord_start;
int x_koord_end;
int y_koord_start;
int y_koord_end;
int x_koord_offset;
int y_koord_offset;
Polynom p;
Graphics g;
public void init() {
g = this.getGraphics();
}
public void zeichne_graph(Polynom fkt, Color c) {
// Erster Funktionswert berechnen und Werte zwischenspeichern
int x_koord_old = x_koord_start;
int y_koord_old;
int x_koord, y_koord;
float x;
float y;
// Transformation von x-Bildkoordinatenpunkt zu realem x Wert
x = (x_koord_start-x_koord_offset) / skalierung;
y = fkt.berechne(x);
//Transformation von realem y Wert in Bildkoordinaten y Wert
y_koord_old = (int) (y * skalierung);
g.setColor(c);
for(x_koord=x_koord_start+1;x_koord<x_koord_end;x_koord++) {
x = (x_koord-x_koord_offset) / skalierung;
y = fkt.berechne(x);
y_koord = - (int) (y * skalierung) + y_koord_offset;
g.drawLine(x_koord_old, y_koord_old, x_koord, y_koord);
x_koord_old = x_koord;
y_koord_old = y_koord;
}
}
144
Events
public void koordinatenkreuz() {
g.setColor(Color.pink);
g.drawLine(x_koord_start,y_koord_offset,x_koord_end,y_koord_offset);
g.drawLine(x_koord_offset, y_koord_start, x_koord_offset, y_koord_end);
}
public void zeichne_graph(Polynom fkt) {
zeichne_graph(fkt, Color.black);
}
public void paint(Graphics g) {
// Ermittlung der Zeichenfläche und Abbildung der Koordinaten
int width = this.getWidth();
int height = this.getHeight();
x_koord_offset = width/2;
y_koord_offset = height/2;
x_koord_start = 0;
x_koord_end = width - x_koord_start;
y_koord_start = 0;
y_koord_end = height - y_koord_start;
skalierung = width/(x_ende - x_start);
// Zeichne Koordinatenkreuz
koordinatenkreuz();
// Erzeugung eines Polynoms 3. Grades
p = new Polynom(1,-2).mult(new Polynom(2,-1).mult(new
Polynom(1,1)));
zeichne_graph(p, Color.green);
zeichne_graph(p.ableitung(), Color.blue);
zeichne_graph(p.ableitung().ableitung(), Color.red);
}
}
145
Events
146
Events
Beispiel:
import java.awt.Graphics;
import java.awt.Font;
import java.util.Date;
public class DigitalClock extends java.applet.Applet {
Font theFont = new Font(„TimesRoman“,Font.BOLD,24);
Date theDate;
public void paint(Graphics g) {
g.setFont(theFont);
theDate = new Date();
g.drawString(theDate.toString(),10,50);
}
}
147
Graphische Benutzeroberfläche
Graphische Oberfläche
•
Oberflächen
– Applets
– fensterbasierte Applikationen
•
Elemente
– Button
– Textfeld
– Texteditor
– Label
– Checkbox
– Radio Buttons
– DropDown List
– List Box
– Dialog Box
– Menus (Java 1.0 nur bei Applikationen
•
Anordnung
– FlowLayout
– Border Layout
– Grid Layout
– Card Layout
148
Graphische Benutzeroberfläche
AWT Oberfläche
149
Graphische Benutzeroberfläche
Applets
•
keine main() Methode
•
Unterliegen Reihe von Restriktionen (kein lokaler Plattenzugriff,
Kommunikation nur mit Host von dem es geladen wurde, „untrusted
applet“ Dialogbox
•
Überschreiben der Methoden
–
–
–
–
–
•
init()
start()
stop()
paint(Graphics g)
destroy()
Ereignisgesteuert (event based)
150
Graphische Benutzeroberfläche
Applikationen
•
Fensterbasierte Anwendungen benutzen zur Darstellung Objekte der
Klasse Frame bzw. leiten Unterklassen davon ab.
•
Ein Frame Objekt besitzt Titelzeile und Rand
•
Frames können ein Menü besitzen (siehe Seite 13)
•
Konstruktor:
–
–
•
Frame()
Frame (String title)
Methoden (Auswahl):• String getTitle()
–
–
–
–
–
–
–
–
–
–
void show()
void toFront()
void toBack()
void setMenuBar(MenuBar mb)
void remove(MenuComponent)
Frame[] getFrames()
void setIconImage(Image img)
void setResizable(boolean resizable)
void setLayout(LayoutManager mgr)
LayoutManager getLayout()
151
Graphische Benutzeroberfläche
Button
•
Konstruktoren:
–
–
•
Methoden (Auswahl):
–
–
•
Button()
Button(text)
getLabel()
setLabel(String str)
Beispiel (Java 1.0):
public void init() {
txt = new TextField(10);
add(txt);
click = new Button("Anzeigen");
add(click);
}
public boolean action(Event e, Object arg) {
if (e.target==click) {
showStatus(txt.getText());
} else
return super.action(e, arg);
return true;
}
152
Graphische Benutzeroberfläche
Textfeld
•
Konstruktoren:
–
–
–
–
•
Methoden (Auswahl):
–
–
–
–
–
–
•
TextField()
TextField(String text)
TextField(int columns)
TextField(String text, int columns
void setEchoChar( char c )l
void setText(String str)
String getString()
void selectAll()
void setEditable(boolean b)
boolean isEditable()
Beispiel (Java 1.0):
TextField tf1, tf2, tf3, tf4;
// a blank text field
tf1 = new TextField(int columns);
// blank field of 20 columns
tf2 = new TextField("", 20);
// predefined text displayed
tf3 = new TextField("Hello!");
// predefined text in 30 columns
tf4 = new TextField("Hello", 30);
153
Graphische Benutzeroberfläche
TextEditor
•
Konstruktoren:
–
–
–
–
•
Konstanten:
–
–
–
–
•
TextArea(int rows, int columns)
TextArea(String text)
TextArea(String text, int rows, int columns)
TextArea(String text, int rows, int columns, int scrollbars)
SCROLLBARS_BOTH,
SCROLLBARS_HORIZONTAL_ONLY
SCROLLBARS_NONE
SCROLLBARS_VERTICAL_ONLY
Methoden (Auswahl):
–
–
–
–
–
–
–
appendText(String str)
insertText(String str, int pos)
replaceText(String str, int start, int end)
String getText()
void setText() void selectAll()
setEditable(boolean b)
boolean isEditable()
154
Graphische Benutzeroberfläche
Label
•
Konstruktoren:
–
–
–
•
Konstanten:
–
–
–
•
Label()
Label(String text)
Label(String text, int alignment)
CENTER
LEFT
RIGHT
Methoden (Auswahl):
–
–
String getText()
void setText(String str)
155
Graphische Benutzeroberfläche
Chechbox
•
Konstruktoren (Auswahl):
–
–
–
–
•
Checkbox()
Checkbox(String label)
Checkbox(String label, boolean state)
Checkbox(String label, boolean state, CheckboxGroup)
// siehe RadioButton
Methoden (Auswahl):
–
–
–
boolean getState()
boolean setState(boolean b)
setLabel(String str)
Radiobuttons
•
Konstruktor:
–
•
CheckboxGroup()
Methoden (Auswahl):
–
–
Checkbox getCurrent()
boolean setCurrent()
156
Graphische Benutzeroberfläche
Auswahlbox
•
Konstruktor:
–
•
Methoden (Auswahl):
–
–
–
–
–
–
–
–
–
•
Choice()
void add(String item)
int countItems()
int getSelectedIndex()
String getSelectedItem()
void insert(String item)
void remove(int position)
void removeAll()
void select(int pos)
void select(String str)
Beispiel:
Choice choice = new Choice();
choice.add("red");
choice.add("green");
choice.add("blue");
157
Graphische Benutzeroberfläche
List
•
Konstruktor:
–
–
–
•
Methoden (Auswahl):
–
–
–
–
–
–
–
–
–
–
•
List()
List(int rows)
List(int rows, boolean multipleSelect)
void add(String item)
int countItems()
void delItem(int index)
void delItems(int start, int stop)
void deselect(int index)
String getItem(int index)
int getItemCount()
String[] getItems()
String getSelectedItem()
String[] getSelectedItems()
Beispiel:
List list = new List(4, true);
list.addItem("Java");
list.addItem("C");
list.addItem("C++");
list.addItem("Smalltalk");
list.addItem("Lisp");
list.addItem("Modula-3");
list.addItem("Forth");
158
Graphische Benutzeroberfläche
Dialogbox
•
Konstruktor (Auswahl):
–
–
–
•
Dialog(Frame owner)
Dialog(Frame owner, boolean modal)
Dialog(Frame owner, String title)
Methoden (Auswahl):
–
–
–
–
setTitle(String title)
void show()
void hide()
void setModal(boolean b)
159
Graphische Benutzeroberfläche
Menuleisten
•
Aussehen:
•
Komponenten:
–
–
–
–
Frame
MenuItem
Menu
MenuItem
160
Graphische Benutzeroberfläche
Menüleisten (Java 1.0)
import java.awt.*;
public class MenuDemo extends Frame {
MenuItem copy, paste, insert, neu, quit, info;
MenuDemo (String title){
super(title);
MenuBar menubar = new MenuBar();
this.setMenuBar(menubar);
Menu file = new Menu("Datei");
Menu edit = new Menu("Bearbeiten");
Menu help = new Menu("Hilfe");
menubar.add(file);
menubar.add(edit);
menubar.add(help);
menubar.setHelpMenu(help);
neu = new MenuItem("neu");
file.add(neu);
quit = new MenuItem("beenden");
file.add(quit);
copy = new MenuItem("Kopieren");
edit.add(copy);
paste = new MenuItem("Ausschneiden");
edit.add(paste);
insert = new MenuItem("Einfügen");
edit.add(insert);
info = new MenuItem("Info");
help.add(info);
this.setSize(400, 400);
this.show();
}
161
Graphische Benutzeroberfläche
Menüleisten (Java 1.0)
public boolean action(Event e, Object arg) {
if (e.target instanceof MenuItem) {
if (e.target==copy) {
System.out.println("Kopieren ...");
} else if (e.target==paste) {
System.out.println("Ausschneiden ...");
} else if (e.target==insert) {
System.out.println("Einfügen ...");
} else if (e.target==quit) {
System.out.println("Beenden ...");
System.exit(0);
} else
System.out.println("sonstwas ...");
return true;
}
return super.action(e, arg);
}
public static void main(String[] args) {
new MenuDemo("Beispielmenu");
}
}
162
Graphische Benutzeroberfläche
Menüleisten (Java 1.1)
import java.awt.*;
import java.awt.event.*;
public class MenuDemo extends Frame
implements ActionListener {
MenuItem copy, paste, insert, neu, quit, info;
MenuDemo (String title){
super(title);
MenuBar menubar = new MenuBar();
this.setMenuBar(menubar);
// Create three pulldown menus for the menubar
Menu file = new Menu(„Datei“);
Menu edit = new Menu(„Bearbeiten“);
Menu help = new Menu(„Hilfe“);
menubar.add(file);
menubar.add(edit);
menubar.add(help);
menubar.setHelpMenu(help);
neu = new MenuItem(„neu“);
file.add(neu);
quit = new MenuItem(„beenden“);
file.add(quit);
copy = new MenuItem(„Kopieren“);
edit.add(copy);
paste = new MenuItem(„Ausschneiden“);
edit.add(paste);
163
Graphische Benutzeroberfläche
Menüleisten (Java 1.1)
insert = new MenuItem(„Einfügen“);
edit.add(insert);
info = new MenuItem(„Info“);
help.add(info);
copy.addActionListener(this);
paste.addActionListener(this);
insert.addActionListener(this);
info.addActionListener(this);
neu.addActionListener(this);
quit.addActionListener(this);
this.setSize(400, 400);
this.show();
}
public void actionPerformed(ActionEvent e) {
String str = e.getActionCommand();
System.out.println (str);
if (str==“beenden“) {
System.exit(0);
}
}
public static void main(String[] args) {
new MenuDemo(„Beispielmenu“);
}
}
164
Graphische Benutzeroberfläche
Layoutmanager
•
•
•
Verantwortlich für die Plazierung der Komponenten (Buttons, Textfelder,
etc.) innerhalb eines Fensters
Standard ist FlowLayout
weiterer verbreiteter Layoutmanager ist BorderLayout:
import java.awt.*;
import java.applet.Applet;
public class BorderLayoutDemo extends Applet {
public void init() {
setLayout(new BorderLayout());
add(new Button("North"), BorderLayout.NORTH);
add(new Button("South"), BorderLayout.SOUTH);
add(new Button("East"), BorderLayout.EAST);
add(new Button("West"), BorderLayout.WEST);
add(new Button("Center"), BorderLayout.CENTER);
}
}
//<applet code=BorderLayoutDemo.class width=320
// height=200>
//</applet>
165
Graphische Benutzeroberfläche
Layoutmanager
•
Ausgabe:
•
weitere Layoutmanager:
– Grid Layout
– Card Layout
166
Graphische Benutzeroberfläche
import java.awt.*;
import java.awt.event.*;
public class MenuDemo extends Frame
implements ActionListener {
MenuItem copy, paste, insert, neu, quit, info;
MenuDemo (String title){
super(title);
MenuBar menubar = new MenuBar();
this.setMenuBar(menubar);
// Create three pulldown menus for the menubar
Menu file = new Menu("Datei");
Menu edit = new Menu("Bearbeiten");
Menu help = new Menu("Hilfe");
// Add the menus to the bar, and treat Help menu specially.
menubar.add(file);
menubar.add(edit);
menubar.add(help);
menubar.setHelpMenu(help);
neu = new MenuItem("neu");
file.add(neu);
quit = new MenuItem("beenden");
file.add(quit);
copy = new MenuItem("Kopieren");
edit.add(copy);
paste = new MenuItem("Ausschneiden");
edit.add(paste);
insert = new MenuItem("Einfügen");
edit.add(insert);
info = new MenuItem("Info");
help.add(info);
copy.addActionListener(this);
paste.addActionListener(this);
insert.addActionListener(this);
info.addActionListener(this);
neu.addActionListener(this);
quit.addActionListener(this);
this.setSize(400, 400);
this.show();
}
167
Graphische Benutzeroberfläche
public void actionPerformed(ActionEvent e) {
String str = e.getActionCommand();
System.out.println (str);
if (str=="beenden") {
System.exit(0);
}
}
public static void main(String[] args) {
new MenuDemo("Beispielmenu");
}
}
168
Graphische Benutzeroberfläche
Beispiel1:
import java.awt.*;
import java.awt.event.*;
public class MenuDemo extends Frame
implements ActionListener {
MenuItem copy, paste, insert, neu, quit, info;
MenuDemo (String title){
super(title);
MenuBar menubar = new MenuBar();
this.setMenuBar(menubar);
// Create three pulldown menus for the menubar
Menu file = new Menu("Datei");
Menu edit = new Menu("Bearbeiten");
Menu help = new Menu("Hilfe");
// Add the menus to the bar, and treat Help menu specially.
menubar.add(file);
menubar.add(edit);
menubar.add(help);
menubar.setHelpMenu(help);
neu = new MenuItem("neu");
file.add(neu);
quit = new MenuItem("beenden");
file.add(quit);
copy = new MenuItem("Kopieren");
edit.add(copy);
paste = new MenuItem("Ausschneiden");
edit.add(paste);
insert = new MenuItem("Einfügen");
edit.add(insert);
public static void main(String[] args) {
new MenuDemo("Beispielmenu");
}
}
169
Graphische Benutzeroberfläche
info = new MenuItem("Info");
help.add(info);
copy.addActionListener(this);
paste.addActionListener(this);
insert.addActionListener(this);
info.addActionListener(this);
neu.addActionListener(this);
quit.addActionListener(this);
this.setSize(400, 400);
this.show();
}
public void actionPerformed(ActionEvent e) {
String str = e.getActionCommand();
System.out.println (str);
if (str=="beenden") {
System.exit(0);
}
}
170
Graphische Benutzeroberfläche
Beispiel 2:
import java.awt.*;
import java.awt.event.*;
public class DrawFkt1 extends Frame
implements ActionListener {
MenuItem parabel, sinus, gerade, neu, quit;
float skalierung;
float x_start = - 4;
float x_ende = -x_start;
int x_koord_start;
int x_koord_end;
int y_koord_start;
int y_koord_end;
int x_koord_offset; //Verschiebung des Ursprungs in x-Richtung
int y_koord_offset; //Verschiebung des Ursprungs in y-Richtung
Graphics g;
int auswahl;
final int SINUS=0;
final int PARABEL=1;
final int GERADE=2;
DrawFkt1 (String title){
super(title);
genMenu();
this.setSize(400, 400);
this.show();
}
171
Graphische Benutzeroberfläche
private void genMenu() {
MenuBar menubar = new MenuBar();
this.setMenuBar(menubar);
// Create three pulldown menus for the menubar
Menu file = new Menu("Datei");
Menu edit = new Menu("Auswählen");
// Add the menus to the bar, and treat Help menu specially.
menubar.add(file);
menubar.add(edit);
neu = new MenuItem("neu");
file.add(neu);
quit = new MenuItem("beenden");
file.add(quit);
parabel = new MenuItem("Parabel");
edit.add(parabel);
sinus = new MenuItem("Sinus");
edit.add(sinus);
gerade = new MenuItem("Gerade");
edit.add(gerade);
parabel.addActionListener(this);
sinus.addActionListener(this);
gerade.addActionListener(this);
neu.addActionListener(this);
quit.addActionListener(this);
}
172
Graphische Benutzeroberfläche
public void actionPerformed(ActionEvent e) {
String str = e.getActionCommand();
g = this.getGraphics();
if (str=="beenden") {
System.exit(0);
}
else if (str=="Sinus") {
auswahl = SINUS;
zeichne_graph(Color.green,g);
}
else if (str=="Parabel") {
auswahl = PARABEL;
zeichne_graph(Color.blue,g);
}
else if (str=="Gerade") {
auswahl = GERADE;
zeichne_graph(Color.red,g);
}
else {
koordinatenkreuz(g);
}
}
public void koordinatenkreuz(Graphics g) {
g.setColor(this.getBackground());
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(Color.pink);
g.drawLine(x_koord_start, y_koord_offset,
x_koord_end, y_koord_offset);
g.drawLine(x_koord_offset, y_koord_start,
x_koord_offset, y_koord_end);
}
173
Graphische Benutzeroberfläche
public void zeichne_graph(Color c, Graphics g) {
// Allererster Funktionswert berechnen und Wertepaar zwischenspeichern
//
int x_koord_old = x_koord_start;
int y_koord_old;
int y_koord;
float x;
float y;
// Transformation von x-Bildkoordinatenpunkt zu realem x Wert
x = (x_koord_start-x_koord_offset) / skalierung;
y = (float) berechne(x); //berechnen des Fkt-Wertes
// Transformation von realem y Wert in Bildkoordianten y Wert
y_koord_old = (int) (y * skalierung);
g.setColor(c);
for (int x_koord = x_koord_start + 1; x_koord < x_koord_end; x_koord++) {
x = (x_koord-x_koord_offset) / skalierung;
y = (float) berechne(x); //berechnen des Fkt-Wertes
y_koord = - (int) (y * skalierung) + y_koord_offset;
g.drawLine(x_koord_old, y_koord_old,x_koord, y_koord);
x_koord_old = x_koord;
y_koord_old = y_koord;
}
}
174
Graphische Benutzeroberfläche
public void paint(Graphics g) {
// Ermittlung der Zeichenfläche und Abbildung der Koordinaten
//
g = this.getGraphics();
int width = this.getWidth();
int height = this.getHeight();
System.out.println(0 +"/"+0+" "+width+","+height);
x_koord_offset = width/2;
x_koord_start = 0;
x_koord_end = width;
y_koord_start = 50;
y_koord_offset = (height+y_koord_start)/2;
y_koord_end = height;
skalierung = width/(x_ende - x_start);
System.out.println("Skalierung:
" + skalierung);
System.out.println("Zeicheninterval: [" + x_start+","+x_ende+"]");
System.out.println("Koordinatenbereich: [" + x_koord_start+","+x_koord_end+"]");
System.out.println("Koordinatenbereich: [" + y_koord_start+","+y_koord_end+"]");
// Zeichne Koordinatenkreuz
koordinatenkreuz(g);
}
double berechne (double x) {
if (auswahl == SINUS)
return Math.sin(x);
else if (auswahl == PARABEL)
return x*x;
else return x;
}
public static void main(String[] args) {
DrawFkt1 drawFkt1 = new DrawFkt1("Beispielmenu");
}
}
175
Graphische Benutzeroberfläche
Beispiel 4:
import java.awt.*;
import java.awt.event.*;
public class TextBox extends Frame implements ActionListener{
TextField lowerBound;
Label lowerBoundLabel;
Button oklB;
int low;
final int defaultlow = -4;
TextBox (String title){
super(title);
setLayout(new FlowLayout(FlowLayout.LEFT, 10,10));
lowerBound = new TextField(String.valueOf(defaultlow),6);
lowerBoundLabel = new Label ("Untere Intervallgrenze: ");
oklB = new Button("übernehmen");
add(lowerBoundLabel);
add(lowerBound);
add(oklB);
oklB.addActionListener(this);
this.setSize(400, 400);
this.show();
}
public void actionPerformed(ActionEvent e) {
String str = e.getActionCommand();
System.out.println (str);
if (str=="übernehmen") {
String tmp = lowerBound.getText();
try {
low = Integer.parseInt(tmp);
System.out.println("neue Grenze: "+low);
}
catch (NumberFormatException ne) {
lowerBound.setText(String.valueOf(defaultlow));
}
}
}
public static void main(String[] args) {
new TextBox("Beispielmenu");
}
176
Graphische Benutzeroberfläche
import java.awt.*;
import java.awt.event.*;
public class TextBox1 extends Frame
implements TextListener{
TextField lowerBound;
Label lowerBoundLabel;
int low;
final int defaultlow = -4;
TextBox1 (String title){
super(title);
setLayout(new FlowLayout(FlowLayout.LEFT, 10,10));
lowerBound = new TextField(String.valueOf(defaultlow),6);
lowerBoundLabel = new Label ("Untere Intervallgrenze: ");
add(lowerBoundLabel);
add(lowerBound);
lowerBound.addTextListener(this);
this.setSize(400, 400);
this.show();
}
public void textValueChanged(TextEvent e) {
String tmp = lowerBound.getText();
try {
low = Integer.parseInt(tmp);
System.out.println("neue Grenze: "+low);
}
catch (NumberFormatException ne) {
lowerBound.setText(String.valueOf(defaultlow));
}
}
public static void main(String[] args) {
new TextBox1("Beispielmenu");
}
}
177
Graphische Benutzeroberfläche
Beispiel 3:
import java.awt.*;
import java.awt.event.*;
public class TextBox2 extends Frame
implements ActionListener{
TextField lowerBound;
Label lowerBoundLabel;
Button oklB;
int low;
final int defaultlow = -4;
TextField upperBound;
Label upperBoundLabel;
Button okuB;
int upper;
final int default_upper = 4;
TextBox2 (String title){
super(title);
setLayout(new FlowLayout(FlowLayout.LEFT, 10,10));
lowerBound = new TextField(String.valueOf(defaultlow),6);
lowerBoundLabel = new Label ("Untere Intervallgrenze: ");
oklB = new Button("übernehmen");
oklB.setActionCommand("lowOK");
add(lowerBoundLabel);
add(lowerBound);
add(oklB);
oklB.addActionListener(this);
upperBound = new TextField(String.valueOf(default_upper),6);
upperBoundLabel = new Label ("Obere Intervallgrenze: ");
okuB = new Button("übernehmen");
okuB.setActionCommand("upperOK");
add(upperBoundLabel);
add(upperBound);
add(okuB);
okuB.addActionListener(this);
this.setSize(400, 400);
this.show();
178
}
Graphische Benutzeroberfläche
public void actionPerformed(ActionEvent e) {
String str = e.getActionCommand();
System.out.println (str);
if (str=="lowOK") {
String tmp = lowerBound.getText();
try {
low = Integer.parseInt(tmp);
System.out.println("neue Grenze: "+low);
}
catch (NumberFormatException ne) {
lowerBound.setText(String.valueOf(defaultlow));
}
} else if (str=="upperOK") {
String tmp = upperBound.getText();
try {
upper = Integer.parseInt(tmp);
System.out.println("neue Grenze: "+upper);
}
catch (NumberFormatException ne) {
lowerBound.setText(String.valueOf(default_upper));
}
}
if (upper < low) {
upper = low;
lowerBound.setText(String.valueOf(upper));
upperBound.setText(String.valueOf(upper));
}
}
public static void main(String[] args) {
new TextBox2("Beispielmenu");
}
}
179
Graphische Benutzeroberfläche
Ergebnis von DrawFkt1
180
Graphische Benutzeroberfläche
Ergebnis von Textbox
Ergebnis von TextBox1
Ergebnis von TextBox2
181
Streams
Das Input-Output-System von Java
•
Java hat zwei Basisklassen für Input und Output:
InputStream und OutputStream
•
Diese Klassen unterstützen das Lesen und Schreiben von Bytes.
•
Durch
import java.io.*
werden diese Klassen eingebunden.
•
InputStream hat eine Basismethode
read()
für das Lesen eines einzelnen oder eines Arrays von Bytes.
•
OutputStream hat eine Basismethode
write()
für das Schreiben eines einzelnen oder eines Arrays von Bytes.
182
Streams
Typen von InputStream
Input kann aus verschiedenen Quellen kommen. Solche
Quellen können sein:
•
Array von Bytes
•
Zeichenkette
•
Datei
•
Pipe
•
Sequenz von anderen Streams, die zu einem einzelnen Stream
zusammengefaßt werden
•
Andere Quelle, wie z.B. Internet-Verbindungen
Für diese verschiedenen Quellen gibt es Unterklassen von InputStream, die
für diese Quellen erstellt wurden.
183
Streams
Typen von OutputStream
Output kann in verschiedene Senken fließen. Solche
Senken können sein:
•
Array von Bytes
•
Datei
•
Pipe
•
Andere Senken, wie z.B. Internet-Verbindungen
Für diese verschiedenen Senken gibt es Unterklassen von OutputStream,
die für diese Senken erstellt wurden.
184
Streams
Reader und Writer
Die Klassen InputStream und OutputStream sind die Basisklassen für das
Lesen und Schreiben von Byte-Streams.
Die Klassen Reader und Writer sind zu InputStream und OutputStream
identisch, allerdings Lesen und Schreiben diese beiden Klassen Zeichen.
Ebenso sind alle Unterklassen jeweils identisch.
Beispiel: Anlegen eines ByteArrayInputStreams
import java.io.*;
class IOdemo {
public static void main (String args[]) throws IOException{
byte buffer[] = new byte[80];
int test;
for (int i=0;i<buffer.length;i++)
buffer[i] = (byte) (i+1); // Fuellen von buffer
InputStream s = new ByteArrayInputStream(buffer);
//Testweise Lesen der ersten 10 Bytes
for (int i = 0; i < 10 ; i++) {
test = s.read();
System.out.println("Gelesen: " + test);
}
}
}
185
Streams
Andere Art des Exception-Handlings
import java.io.*;
class IOdemo {
public static void main (String args[]) {
byte buffer[] = new byte[80];
int test;
for (int i=0;i<buffer.length;i++)
buffer[i] = (byte) (i+1); // Fuellen von buffer
InputStream s = new ByteArrayInputStream(buffer);
//Testweise Lesen der ersten 10 Bytes
for (int i = 0; i < 10 ; i++) {
try {
test = s.read();
System.out.println("Gelesen: " + test);
}
catch (IOException e) {
System.out.println("IO Fehler");
}
}
}
}
186
Streams
Die Methoden von InputStream
int available()
Returns the number of bytes that can be read (or skipped over) from this
input stream without blokking by the next caller of a method for this input
stream.
void close()
Closes this input stream and releases any system resources associated
with the stream.
void mark(int readlimit)
Marks the current position in this input stream.
boolean markSupported()
Tests if this input stream supports the mark and reset methods.
int read()
Reads the next byte of data from the input stream.
int read(byte[] b)
Reads some number of bytes from the input stream
and stores them into the buffer array b.
int read(byte[] b, int off, int len)
Reads up to len bytes of data from the input stream into an array of bytes.
void reset()
Repositions this stream to the position at the time the mark method was last
called on this input stream.
long skip(long n)
Skips over and discards n bytes of data from this input stream.
187
Streams
Beispiel: Lesen eines Buffers und Schreiben in einen Anderen
import java.io.*;
class IOdemo1 {
public static void main (String args[]) {
byte ibuffer[] = new byte[10];
byte obuffer[] = new byte[10];
for (int i=0;i<ibuffer.length;i++)
ibuffer[i] = (byte) (i+1); // Fuellen von buffer
InputStream s = new ByteArrayInputStream(ibuffer);
//Lesen von ibuffer und Schreiben in obuffer
try {
s.read(obuffer);
}
catch (IOException e) {
System.out.println("IO Fehler");
}
//Test durch Ausgabe von obuffer
for (int i=0;i<obuffer.length;i++)
System.out.println("obuffer["+i+"] = "+ obuffer[i]);
}
}
188
Streams
Die Methoden von OutputStream
void close()
Closes this output stream and releases any system resources associated
with this stream.
void flush()
Flushes this output stream and forces any buffered output bytes to be
written out.
void write(byte[] b)
Writes b.length bytes from the specified byte array to this output stream.
void write(byte[] b, int off, int len)
Writes len bytes from the specified byte array starting at offset off to this
output stream.
void write(int b)
Writes the specified byte to this output stream.
189
Streams
Beispiel: Lesen aus einem File
import java.io.*;
class FileDemo {
public static void main (String args[]) throws IOException{
int in=0;
FileInputStream s = new FileInputStream("tmp1");
in = s.read();
System.out.println("Test = "+ in);
}
}
Beispiel: Schreiben und Lesen eines Files
import java.io.*;
class FileDemoIO {
public static void main (String args[]) throws IOException{
int i=0;
FileOutputStream out = new FileOutputStream("tmp2");
out.write(3);
FileInputStream in = new FileInputStream("tmp2");
i = in.read();
System.out.println("Test = "+ i);
}
}
190
Streams
Die Klasse File
Zum Bearbeiten von Files gibt es die Klasse File. Einige Konstruktoren
der Klasse sind:
File(File parent, String child)
Creates a new File instance from a parent abstract pathname and a
child pathname string.
File(String pathname)
Creates a new File instance by converting the given pathname string
into an abstract pathname.
File(String parent, String child)
Creates a new File instance from a parent pathname string and a child
pathname string.
Einige Methoden dieser Klasse sind z.B.:
boolean canRead()
Tests whether the application can read the file denoted by this abstract
pathname.
boolean canWrite()
Tests whether the application can modify to the file denoted by this abstract
pathname.
int compareTo(File pathname)
Compares two abstract pathnames lexicographically.
int compareTo(Object o)
Compares this abstract pathname to another object.
boolean createNewFile()
Atomically creates a new, empty file named by this abstract pathname
if and only if a file with this name does not yet exist.
boolean delete()
Deletes the file or directory denoted by this abstract pathname.
191
Streams
boolean equals(Object obj)
Tests this abstract pathname for equality with the given object.
boolean exists()
Tests whether the file denoted by this abstract pathname exists.
File getAbsoluteFile()
Returns the absolute form of this abstract pathname.
String getAbsolutePath()
Returns the absolute pathname string of this abstract pathname.
String getName()
Returns the name of the file or directory denoted by this abstract
pathname.
String getParent()
Returns the pathname string of this abstract pathname’s parent, or null
if this pathname does not name a parent directory.
File getParentFile()
Returns the abstract pathname of this abstract pathname’s parent, or
null if this pathname does not name a parent directory.
String getPath()
Converts this abstract pathname into a pathname string.
boolean isAbsolute()
Tests whether this abstract pathname is absolute.
boolean isDirectory()
Tests whether the file denoted by this abstract pathname is a directory.
boolean isFile()
Tests whether the file denoted by this abstract pathname is a normal
file.
192
Streams
boolean isHidden()
Tests whether the file named by this abstract pathname is a hidden
file.
long lastModified()
Returns the time that the file denoted by this abstract pathname was
last modified.
long length()
Returns the length of the file denoted by this abstract pathname.
String[] list()
Returns an array of strings naming the files and directories in the
directory denoted by this abstract pathname.
String[] list(FilenameFilter filter)
Returns an array of strings naming the files and directoriesin the directory
denoted by this abstract pathname that satisfy the specified filter.
boolean mkdir()
Creates the directory named by this abstract pathname.
boolean mkdirs()
Creates the directory named by this abstract pathname, including any
necessary but nonexistent parent directories.
boolean renameTo(File dest)
Renames the file denoted by this abstract pathname.
boolean setLastModified(long time)
Sets the last-modified time of the file or directory named by this abstract
pathname.
boolean setReadOnly()
Marks the file or directory named by this abstract pathname so that only
read operations are allowed.
String toString()
Returns the pathname string of this abstract pathname.
URL toURL()
Converts this abstract pathname into a file: URL.
193
Streams
Beispiel: Lesen aus einem File
import java.io.*;
class FileDemo2 {
public static void main (String args[]) throws IOException{
File test = new File("tmp1");
byte ibuffer[] = new byte[5];
test.createNewFile();
FileInputStream s = new FileInputStream(test);
try {
s.read(ibuffer);
}
catch (IOException e) {
System.out.println("IO Fehler");
}
//Test durch Ausgabe
for (int i=0;i<ibuffer.length;i++)
System.out.println("ibuffer["+i+"] = "+ ibuffer[i]);
}
}
194
Streams
Beispiel: Lesen und Schreiben eines Files
import java.io.*;
class FileDemo3 {
public static void main (String args[]) throws IOException{
File test = new File("tmp1");
int i;
test.createNewFile();
FileOutputStream out = new FileOutputStream (test);
for (i = 1; i <20; i++)
out.write(i);
FileInputStream in = new FileInputStream(test);
do {
i = in.read();
System.out.println("Ergebnis"+ i);
}
while (i!= -1);
}
}
195
Threads
Einfache Animationen und Threads
Eine Animation umfaßt in Java zwei Schritte:
•
•
Erstens Aufbau und Ausgabe eines Animationsrahmens und
zweitens entsprechend häufige Wiederholung der Zeichnung, um den
Eindruck von Bewegung zu vermitteln.
Zeichnen und Nachzeichnen:
Die paint()-Methode wird von Java immer aufgerufen, wenn ein Applet
gezeichnetwerden muß - beim erstmaligen Zeichnen des Applets, wenn das
Applet-Fenster verschoben oder es durch ein anderes Fenster überlagert
wird. Mab kann Java aber auch auffordern, ein Applet zu einem bestimmten
Zeitpunkt nachzuzeichnen.
Um die Darstellung am Bildschirm zu ändern, wird ein Bild erstellt – ein
sogenannter »Rahmen« - der gezeichnet werden soll, dann wird Java
aufgefordert, diesen Rahmen zu zeichnen.
Wird dies wiederholt und schnell genug getan, so erhält man im Java-Applet
eine Animation. Mehr ist dazu nicht nötig.
Wo findet all dies statt? Nicht in der paint()-Methode. paint() gibt nur Punkte
am Bildschirm aus. Mit anderen Worten, paint() ist nur für den aktiven
Rahmen der Animation zuständig. Die wirkliche Arbeit dessen, was paint()
wirklich bewirkt, die Änderung des Rahmens für eine Animation, findet
irgendwo anders in der Definition des Applets statt.
In diesem »irgendwo anders« wird der Rahmen erstellt (setzen von
Variablen für paint(), definieren von Farben, Fonts oder andere Objekte, die
paint() benötigt), dann wird die repaint()-Methode aufgerufen. repaint() ist
der Auslöser, der Java veranlaßt, paint() aufzurufen und den Rahmen zu
zeichnen.
196
Threads
Threads:
Was sie sind und wozu man sie braucht
Wenn ein Programm abläuft, beginnt es mit der Ausführung seines
Initialisierungscodes, ruft Methoden oder Prozeduren auf und fährt mit der
Ausführung und Verarbeitung fort, bis es fertig ist oder das Programm
beendet wird. Das Programm nutzt einen einzelnen Thread, wobei der
Thread für das Programm ein einzelner Kontrollpunkt ist.
Multithreading, wie in Java, ermöglicht die Ausführung mehrerer
verschiedener Threads gleichzeitig im gleichen Programm, ohne sich
gegenseitig zu beeinträchtigen.
Schreiben von Applets mit Threads:
Um ein Applet zu schreiben, das Threads nutzt, müssen vier Änderungen
durchgeführt werden:
•
Erweitern der Unterschrift des Applets um die Wörter implements
Runnable
•
Einfügen einer Instanzvariablen, die den Thread des Applets enthält
•
Ändern der start()-Methode, so daß sie außer dem Starten des
Threads nichts macht
•
Erstellen einer run()-Methode, die den eigentlichen Code enthält, der
das Applet startet
197
Threads
Beispiel: Ein einfacher Thread
class ErsterThread extends Thread {
public void run () {
for (int i = 0; i < 10; i++) {
System.out.println (i + „ „);
try {
sleep (100);
}
catch (InterruptedException e) {
System.out.println (e);
}
}
System.out.println („Ende Thread „ + toString ());
}
}
public class ErsterThreadDemo {
static public void main (String args[]) {
ErsterThread thread = new ErsterThread ();
thread.start ();
System.out.println („Ende main“);
}
}
Ausgabe:
misun3:105>java ErsterThreadDemo
Ende main
ErsterThread: 0
ErsterThread: 1
ErsterThread: 2
ErsterThread: 3
ErsterThread: 4
ErsterThread: 5
ErsterThread: 6
ErsterThread: 7
ErsterThread: 8
ErsterThread: 9
198
Threads
Beispiel: Digitale Uhr
import java.awt.Graphics;
import java.awt.Font;
import java.util.Date;
public class DigitalThreads extends java.applet.Applet
implements Runnable {
Font theFont = new Font(„TimesRoman“,Font.BOLD,24);
Date theDate;
Thread runner;
public void start() {
if (runner == null); {
runner = new Thread(this);
runner.start();
}
}
public void stop() {
if (runner != null) {
runner.stop();
runner = null;
}
}
public void run() {
while (true) {
theDate = new Date();
repaint();
try { Thread.sleep(1000); }
catch (InterruptedException e) { }
}
}
public void paint(Graphics g) {
g.setFont(theFont);
g.drawString(theDate.toString(),10,50);
}
}
199
Threads
Beispiel: Mehrere Threads
class ErsterThread extends Thread {
public void run () {
for (int i = 0; i < 10; i++)
try {
sleep (Math.round (1000.0*Math.random ()));
System.out.println („ErsterThread: „ + i);
}
catch (InterruptedException e) {
System.out.println (e);
}
}
}
class ZweiterThread implements Runnable {
Thread thread;
ZweiterThread () {
thread = new Thread (this);
}
public void start () {
thread.start ();
}
public void join () throws InterruptedException {
thread.join ();
}
public void run () {
for (int i = 0; i < 10; i++)
try {
thread.sleep (Math.round (1000.0*Math.random ()));
System.out.println („ZweiterThread: „ + i);
}
catch (InterruptedException e) {
System.out.println (e);
}
}
}
200
Threads
public class ThreadDemo {
static public void main (String args[]) {
ErsterThread thread1 = new ErsterThread ();
thread1.start ();
ZweiterThread thread2 = new ZweiterThread ();
thread2.start ();
try {
thread1.join ();
thread2.join ();
}
catch (InterruptedException e) {
System.out.println (e);
}
}
}
Ausgabe:
misun3:106>java ThreadDemo
ErsterThread: 0
ZweiterThread: 0
ZweiterThread: 1
ZweiterThread: 2
ErsterThread: 1
ZweiterThread: 3
ErsterThread: 2
ZweiterThread: 4
ZweiterThread: 5
ErsterThread: 3
ErsterThread: 4
ErsterThread: 5
ZweiterThread: 6
ZweiterThread: 7
ZweiterThread: 8
ZweiterThread: 9
ErsterThread: 6
ErsterThread: 7
ErsterThread: 8
ErsterThread: 9
201
Threads
Beispiel:
class ErsterThread extends Thread {
public void run () {
for (int i = 0; i < 10; i++) {
System.out.println (i + " ");
try {
sleep (100);
}
catch (InterruptedException e) {
System.out.println (e);
}
}
System.out.println ("Ende Thread " + toString ());
}
}
public class ErsterThreadDemo {
static public void main (String args[]) {
ErsterThread thread = new ErsterThread ();
thread.start ();
System.out.println ("Ende main");
}
}
202
Threads
Beispiel:
import java.awt.Graphics;
import java.awt.Font;
import java.util.Date;
public class DigitalThreads extends java.applet.Applet
implements Runnable {
Font theFont = new Font("TimesRoman",Font.BOLD,24);
Date theDate;
Thread runner;
public void start() {
if (runner == null); {
runner = new Thread(this);
runner.start();
}
}
public void stop() {
if (runner != null) {
runner.stop();
runner = null;
}
}
public void run() {
while (true) {
theDate = new Date();
repaint();
try { Thread.sleep(1000); }
catch (InterruptedException e) { }
}
}
public void paint(Graphics g) {
g.setFont(theFont);
g.drawString(theDate.toString(),10,50);
}
}
203
Threads
class ErsterThread extends Thread {
public void run () {
for (int i = 0; i < 10; i++)
try {
sleep (Math.round (1000.0*Math.random ()));
System.out.println ("ErsterThread: " + i);
}
catch (InterruptedException e) {
System.out.println (e);
}
}
}
class ZweiterThread implements Runnable {
Thread thread;
ZweiterThread () {
thread = new Thread (this);
}
public void start () {
thread.start ();
}
public void join () throws InterruptedException {
thread.join ();
}
public void run () {
for (int i = 0; i < 10; i++)
try {
thread.sleep (Math.round (1000.0*Math.random ()));
System.out.println ("ZweiterThread: " + i);
}
catch (InterruptedException e) {
System.out.println (e);
}
}
}
204
Threads
public class ThreadDemo {
static public void main (String args[]) {
ErsterThread thread1 = new ErsterThread ();
thread1.start ();
ZweiterThread thread2 = new ZweiterThread ();
thread2.start ();
try {
thread1.join ();
thread2.join ();
}
catch (InterruptedException e) {
System.out.println (e);
}
}
}
205
Ergänzungen
Abstract Windowing Toolkit (AWT)
Das Abstract Windowing Toolkit (AWT) ist ein Package, das Klassen für die
Zusammenstellung und Verwendung von graphischen
Benutzungsoberflächen (GUI) enthält. Solche GUIs bestehen aus Fenstern,
Menüs, Eingabefeldern, Buttons und dergleichen, und die Steuerung durch
den Benutzer erfolgt meistens mit Tastatur (Keyboard) und Maus oder mit
ähnlichen Hardware-Komponenten wie z.B. Trackballs, Touchscreen oder
Spracheingabe.
Das Wort abstrakt (abstract) im Namen AWT deutet darauf hin, dass in
diesen Klassen nur die plattformunabhängigen wesentlichen Eigenschaften
der Komponenten definiert sind und für die konkrete Darstellung dann die
am jeweiligen Rechner vorhandenen Systemkomponenten ("Peers") mit den
auf diesem Rechner üblichen Layouts, Aussehen und Funktionalitäten
("look and feel") verwendet werden. Ein im Java-Programm mit AWT
definierter Button wird also auf einem PC wie normale Windows- Buttons,
auf einem Macintosh wie normale Apple-Buttons und unter Unix wie
normale Motif- oder CDE-Buttons aussehen, und das gleiche gilt für
Fenster, Scrollbars, Menüs etc.
Dies hat für den Benutzer den Vorteil, dass er auf seinem Computersystem
immer dieselben, gewohnten GUI-Komponenten vorfindet, unabhängig von
der Applikation. Es hat aber den Nachteil, dass die gleiche Applikation auf
verschiedenen Computersystemen dadurch in den Details verschieden
aussieht und dass im Fall von Applets keine genaue Anpassung der
Größen, Farben, Schriftarten und Graphik-Elemente an die umgebende
Web-Page möglich ist.
206
Ergänzungen
Deshalb unterstützen neuere Java-Versionen (Swing, JDK 1.2) zusätzlich
zu den Peer-Komponenten auch sogenannte "leichte„ (light weight)
Komponenten, die komplett in Java geschrieben sind und bei denen die
Layout-Details genauer definiert werden können. Damit kann man Applets
und Applikationen so gestalten, dass jede Anwendung
plattformübergreifend ihr eigenes Look-and-Feel hat.
Die Swing-Komponenten sind Teil der sogenannten Java Foundation
Classes (JFC). Sie können beim JDK 1.1 zusätzlich installiert werden und
sind ab JDK 1.2 Teil des JDK. Sie werden von den meisten Web-Browsern
noch nicht unterstützt.
Für AWT Version 1.1 müssen die Packages java.awt und java.awt.event
importiert werden, für Swing zusätzlich das Package javax.swing.
207
Ergänzungen
Swing-Komponenten (JComponent)
In Swing (Java Foundation Classes JFC) stehen als Alternative zu den
AWT-Komponenten die folgenden Komponenten zur Verfügung. Sie
verwenden keine Peers vom Betriebssystem, sondern sind komplett in Java
definiert. Man kann das Aussehen und die Funktionalität (look and feel) für
diese Komponenten im Java-Programm genau festlegen: entweder, indem
man eines der vorgefertigten Designs auswählt (z.B. wie bei Motif oder wie
bei Windows) oder, indem man alle Details selbst festlegt und damit
ein produktspezifisches Look-and-Feel erzeugt.
Swing-Komponenten sollten niemals mit Peer-Komponenten gemischt
verwendet werden.
Die wichtigsten Swing-Kompontenten sind:
•
JFrame mit ContentPane, für ein Fenster mit Rahmen (wie Frame)
•
JPanel, JInternalFrame, JDesktopPane, JLayeredPane, JTabbedPane,
JApplet für einen Bereich (wie Panel bzw. Applet)
•
JComponent als Oberklasse für alle Swing-Komponenten und
Container, und für eine Zeichenfläche (wie Canvas und Panel)
•
JLabel für einen Text oder ein Icon (wie Label)
•
JButton für einen Knopf mit Text oder Icon (wie Button)
•
JCheckbox, JRadioButton, JToggleButton für einen Schalter
(wie Checkbox)
•
JList, JComboBox in Verbindung mit einem Vector oder einem
ListModel bzw. ComboBoxModel und ListCellRenderer für
Auswahllisten (wie Choice bzw. List)
•
JTextField, JPasswordField, JTextArea in Verbindung mit String oder
Document, für Text-Eingaben (wie TextField bzw. TextArea)
208
Ergänzungen
•
JDialog, JOptionPane für Dialogfenster (wie Dialog)
•
JFileDialog, JFileChooser für die Auswahl einer Datei (wie FileDialog)
•
JMenuBar, JMenu, JMenuItem, JCheckboxMenuItem, JPopupMenu,
JSeparator für Menüs (wie MenuBar, Menu etc.)
•
JScrollBar, JScrollPane für Scrollbars (wie ScrollBar bzw. ScrollPane)
•
ImageIcon für ein kleines Bild
•
JProgressBar für die graphische Darstellung eines Zahlenwertes
•
JSlider für die graphische Eingabe eines Zahlenwertes
•
JColorChooser für die Auswahl einer Farbe
•
JToolBar für eine Button-Leiste
•
JToolTip bzw. setToolTipText() für eine Zusatzinformation zu jeder Komponente
•
JTable in Verbindung mit TableModel und TableCellRenderer für die Anordnung von
Komponenten in Tabellenform
•
JTree in Verbindung mit TreeModel, TreePath, TreeNode und TreeCellRenderer
oder TreeCellEditor sowie TreeSelectionModel und TreeSelectionListener für die
Darstellung eines hierarchischen Baums von Elementen wie z.B. ein Directory
mit Subdirectories und Files
•
JEditorPane, JTextPane in Verbindung mit einem String oder einem InputStream
oder Reader oder einem Document wie PlainDocument, DefaultStyledDocument
oder HTMLDocument mit HyperlinkListener, und mit einem EditorKit wie
DefaultEditorKit, HTMLEditorKit oder RTFEditorKit, für die formatierte Darstellung
von Text. Die HTML-Unterstützung ist dabei nur relativ einfach, für "besseres"
HTML gibt es, alleridngs nicht kostenlos, eine HotJava-Bean von der
Firma Sun.
209
Ergänzungen
Abstrakte Klassen
Abstrakte Klassen (abstract class) stellen eine Mischung aus Superklassen
und Interfaces dar: ein Teil der Methoden ist in der abstrakten Klasse
konkret definiert wie bei Superklassen, und von einem anderen Teil ist nur
die Signature der Methoden skizziert, wie bei Interfaces. Die Definition
beginnt mit
public abstract class SuperClassName
und die Vererbung in der Subklasse wie gewohnt mit
public class SubClassName extends SuperClassName
Die Subklasse muss dann konkrete Implementierungen von allen in
der Superklasse nur skizzierten Methoden enthalten und kann die
dort konkret definierten Methoden entweder übernehmen (Vererbung) oder
überschreiben (override).
Innere Klassen (inner class)
Ab JDK 1.1. kann man Klassen auch innerhalb von anderen Klassen
definieren, sie können dann nur innerhalb dieser Klasse verwendet werden,
haben aber (im Gegensatz zu separat definierten Klassen) Zugriff auf alle in
der äußeren Klasse definierten Datenfelder und Methoden.
210
Ergänzungen
Packages und import
Unter einem Package versteht man eine Menge von zusammengehörenden
Klassen, ähnlich wie bei einer Programmbibliothek. Package ist im
wesentlichen identisch mit Directory: Alle Klassen, die im selben Directory
liegen, gehören zu diesem Package.
In Java werden Packages einheitlich und plattformunabhängig mit Punkten
zwischen den Directory-Namen geschrieben, egal, ob auf der jeweiligen
Plattform Schrägstriche / oder Backslashes \ oder sonst etwas als FileSeparator verwendet wird.
Wenn man in einer Java-Klasse andere Klassen oder Interfaces
ansprechen will, muss man diese im allgemeinen "importieren". Dazu gibt
man am Beginn des Source-Files mit import den Namen der Klasse (meist
mit ihrem Package-Namen) an, oder man importiert gleich alle Klassen
eines Package, indem man einen Stern * angibt:
import aaa.bbb.Xxxx ;
import aaa.bbb.* ;
Im ersten Fall wird die Klasse Xxxx aus dem Package aaa.bbb verfügbar
gemacht, im zweiten Fall alle Klassen aus dem Package aaa.bbb.
Die Angabe der Packages (Directories) erfolgt immer relativ zu den
Directories, die in der Environment-Variablen CLASSPATH angeführt sind.
211
Ergänzungen
Wenn der Punkt . für das jeweilige Directory in CLASSPATH enthalten ist,
dann braucht man für Klassen, die im selben Directory liegen, kein importStatement anzugeben, sondern alle Klassen, die im selben Directory liegen,
stehen automatisch zur Verfügung.
Das zur Grundausstattung von Java gehörende Package java.lang und das
"eigene" Package (eigenes Directory oder package-Angabe) werden vom
Compiler automatisch gefunden und müssen nicht explizit importiert
werden, wohl aber alle anderen wie z.B. java.util, java.text, java.awt,
java.awt.event etc.
212
Ergänzungen
Java-Archive (jar)
Ein Java-Archiv enthält Dateien und eventuell auch ganze DirectoryStrukturen (siehe Packages) in demselben komprimierten Format, das auch
von PKZIP und Win-Zip verwendet wird. Sie werden mit dem Programm jar
(java archiver)verwaltet, der Aufruf erfolgt ähnlich wie beim Unix-Programm
tar (tape archiver):
Archiv-File erstellen (create):
jar cvf xxx.jar *.class
Inhalt eines Archiv-Files anzeigen (table of contents):
jar tvf xxx.jar
einzelen Dateien aus einem Archiv-File herausholen (extract):
jar xvf xxx.jar Yyyy.class
Der Herausholen bzw. "Auspacken" von Archiv-Files ist meistens gar nicht
nötig: Der Java-Compiler und die Java Virtual Machine können die ClassFiles direkt aus dem Archiv-File lesen und laden. Zu diesem Zweck muss
der Filename des Archiv-Files im Classpath angegeben sein bzw. bei
Applets im ARCHIVE-Paremeter des Applet-Tag im HTML-File.
213
Ergänzungen
Java im Web-Server (CGI, Servlets)
Web-Server können nicht nur fertige Files liefern sondern auch Programme
ausführen. Dazu dient die Schnittstelle Common Gateway Interface (CGI).
Die CGI-Programme können, eventuell in Abhängigkeit von BenutzerEingaben, irgendwelche Aktionen ausführen und die Ergebnisse über das
Hypertext Transfer Protocol HTTP an den Web-Browser senden.
CGI-Programme können im HTML-File oder Applet entweder über ein
Hypertext-Link aufgerufen werden (nur Ausgabe an den Client) oder über
ein Formular oder GUI (Eingabe vom Client an das CGI-Programm,
Ausgabe an den Client).
CGI-Programme können in jeder beliebigen Programmier- oder ScriptSprache geschrieben werden, auch in Java. In diesem Fall besteht das
CGI-Programm aus einem Shell-Script, in dem die Java Virtual Machine
aufgerufen wird, die den Bytecode der Java- Applikation interpretiert, etwa
in einer der folgenden Formen:
java Classname
java Classname Parameter
java -Dvariable=wert Classname
Dies bedeutet, dass bei jedem Aufruf des CGI-Programms die Java Virtual
Machine neu gestartet werden muss, was eventuell zu längeren
Wartezeiten führen kann.
Diesen Nachteil kann man vermeiden, wenn man einen Web-Server
verwendet, der die Java Virtual Machine integriert enthält und JavaProgramme sofort direkt aufrufen kann (z.B. die neueren Versionen von
Apache, Netscape Enterprise Server und vielen anderen).
214
Ergänzungen
Diese Java-Programme werden als Servlets bezeichnet. Der Name
"Servlet" ist analog zu "Applet" gebildet: So wie Applets von einer Java
Virtual Machine innerhalb des Web-Browsers ausgeführt werden, so werden
Servlets von einer Java Virtual Machine innerhalb des Web-Servers
ausgeführt.
Dafür gibt es die Packages javax.servlet und javax.servlet.http sowie ein
Java Servlet Development Kit JSDK mit einem ServletRunner zum Testen
von Servlets, bevor sie im echten Web- Server eingebaut werden.
Die wichtigsten Methoden von Servlets sind:
Wenn der Web-Server startet und die Servlets initialisiert, wird die
init-Methode ausgeführt.
Bei jedem Client-Request ("User-Click") wird die service-Methode oder die
von dort je nach der Request-Methode aufgerufene Methode doGet, doPost
etc. ausgeführt. Diese Methoden haben 2
Parameter:
Mit dem Parameter ServletRequest können die vom Client mitgesendeten
Informationen abgefragt werden. Mit dem Parameter ServletResponse muss
die Antwort an den Client gesendet werden.
Mit der Methode getServletInfo kann man das Servlet
dokumentieren.
Servlets können wie Java-Applikationen auch auf lokale Files, Programme
und Systemfunktionen am Web-Server zugreifen.
215
Ergänzungen
Internet-Protokoll, Server und Clients
Java unterstützt die Kommunikation über das weltweite Internet und über
interne Intranets und Extranets mit den Internet- Protokollen TCP und UDP.
Dazu muss das Package java.net importiert werden.
Grundbegriffe:
Die programmtechnischen Mechanismen für Netzverbindungen werden
Sockets (vom englischen Wort für Steckdose) genannt. Für die
Adressierung werden Hostname und Portnummer verwendet.
Der Hostname ist eine weltweit bzw. netzweit eindeutige Bezeichnung des
Rechners (Name oder Nummer).
Die Portnummer gibt an, welches Programm auf diesem Rechner die über
das Netz übertragenen Informationen verarbeiten soll. Portnummern unter
1024 haben eine vordefinierte Bedeutung und können nur mit SupervisorPrivilegien (root unter Unix) verwendet werden. Portnummern über 1024
sind "frei". Für Java- Anwendungen, die von gewöhnlichen Benutzern
geschrieben werden, kommen also meist nur Portnummern über 1024 in
Frage, und man muss sicherstellen, dass nicht jemand anderer auf
demselben Rechner dieselbe Portnummer schon für andere Zwecke
verwendet.
Server sind die Rechner, die ein bestimmtes Service bieten und damit die
Kunden (Clients) "bedienen".
Clients ("Kunden") sind die Benutzer, die das Service des Servers in
Anspruch nehmen wollen, bzw. die von ihnen dafür benützten Rechner.
216
Ergänzungen
Vorgehensweise:
Der Server "horcht" (listen) mit Hilfe einer ServerSocket auf eine
Portnummer, d.h. er wartet darauf, dass ein Client etwas von ihm will
("einen Request sendet"). In diesem Fall baut er, meist in einem eigenen
Thread, eine Verbindung (connection) mit dem Client über eine Socket auf,
liest eventuell vom Client kommende Befehle und Dateneingaben und
sendet jedenfalls Meldungen und Ergebnisse an den Client.
Clients bauen über eine Socket eine Verbindung (connection) zum Server
auf, senden eventuell Befehle oder Daten an den Server und lesen
jedenfalls alle vom Server kommenden Informationen.
217
Ergänzungen
Datenbanken
Zu den wichtigsten Anwendungsgebieten von Java zählen UserInterfaces zu Datenbanksystemen.
Das Java-Programm kann dabei ein Applet, eine Applikation oder ein
Servlet sein und kann am selben Rechner wie die Datenbank laufen oder
auch auf einem anderen Rechner und von dort über das Internet oder ein
Intranet auf die Datenbank zugreifen.
Die "Java Database Connectivity" (JDBC) ist im Sinne der
Plattformunabhängigkeit von Java so aufgebaut, dass das Java- Programm
von der Hard- und Software des Datenbanksystems unabhängig ist und
somit für alle Datenbanksysteme (MS-Access, Oracle etc.) funktioniert.
Mit den im JDBC enthaltenen Java-Klassen (Package java.sql) kann man
Daten in der Datenbank so bequem speichern und abfragen wie beim Lesen
und Schreiben von Dateien oder Sockets. Auf diese Weise kann man die
Vorteile von Java, die vor allem bei der Gestaltung von (graphischen und
plattformunabhängigen) User-Interfaces liegen, mit der Mächtigkeit von
Datenbanksystemen verbinden.
218
Ergänzungen
Java Beans
Unter Java Beans ("Kaffeebohnen") versteht man kleine Java- Programme
(Klassen) mit genau festgelegten Konventionen für die Schnittstellen, die
eine Wiederverwendung in mehreren Anwendungen (Applikationen und
Applets) ermöglichen, ähnlich wie bei Unterprogramm-Bibliotheken in
anderen Programmiersprachen. Dies ist vor allem in Hinblick auf das
Software-Engineering von komplexen Programmsystemen interessant.
Dafür gibt es ein eigenes Beans Development Kit BDK, das man zusätzlich
zum JDK installieren kann, und ein Package java.beans, das ab Version 1.1
im JDK enthalten ist,
Beans werden auch von vielen Software-Tools (IDE) unterstützt. Auch die
Klassenbibliothek des JDK ist seit Version 1.2 weitgehend nach den BeansKonventionen geschrieben, und manche Softwarefirmen verkaufen spezielle
Java-Beans für bestimmte Anwendungen.
Es ist empfehlenswert, auch beim Schreiben eigener Java-Programme
möglichst die Konventionen von Java-Beans einzuhalten, also z.B. dass
jede Klasse einen Default-Konstruktor mit leerer Parameterliste haben soll,
dass die Methoden für das Setzen und Abfragen von Datenfeldern Namen
der Form setXxxxx und getXxxxx bzw. isXxxxx haben sollen, oder dass alle
Klassen so "selbständig" programmiert werden sollen, dass sie unabhäng
davon funktionieren, wie andere Klassen programmiert wurden.
219
Ergänzungen
Verwendung von Unterprogrammen
(native methods, JNI)
Man kann innerhalb von Java-Applikationen auch Unterprogramme
aufrufen, die in einer anderen Programmiersprache geschrieben sind,
insbesondere in den Programmiersprachen C und C++. Solche
Unterprogramme werden als "eingeborene" (native) Methoden bezeichnet,
das entsprechende Interface als Java Native Interface (JNI).
Der Vorteil liegt darin, dass man sämtliche von dieser Programmiersprache
unterstützten Funktionen und Unterprogramm-Bibliotheken verwenden
kann. Der Nachteil liegt darin, dass die Java-Applikation dann im
allgemeinen nicht mehr Plattform- oder auch nur Rechner-unabhängig ist.
220