Präsentation herunterladen
Die Präsentation wird geladen. Bitte warten
Veröffentlicht von:Tobias Marcus Fried Geändert vor über 7 Jahren
1
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
2
Was ist eine Programmiersprache?
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.
3
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
4
Welche Sprachen gibt es?
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 (hole Inhalt der Speicherzelle e4h in a1- register) 04 2a (addiere zum Inhalt des a1- Register eine 46) a3 10e4 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
5
Die Programmiersprache Java ist
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]):
6
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 float- Zahl oder eine Zeichenkette) sind System- programmiersprachen 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.
7
Eigenschaften von Java:
Was ist Java? Eigenschaften von Java: einfach objektorientiert architekturneutral (portabel) verteilt sicher multithreaded dynamisch performant
8
1. einfach: Was ist Java? 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)
9
2. objektorientiert: Was ist Java?
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
10
3. architekturneutral: Was ist Java?
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
11
4. architekturneutral: Was ist Java?
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)
12
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)
13
6. multithreaded: Was ist Java?
Gleichzeitig mehrere Ausführungsstränge in einem Programm (z.B. ausführen umfangreicher Berechnungen und gleichzeitig Interaktion mit Benutzer)
14
7. dynamisch: Was ist Java?
Klassen können zur Laufzeit dynamisch nachgeladen werden und Objekte daraus instanziiert werden.
15
8. performant: Was ist Java?
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.
16
9. architekturneutralität
Was ist Java? 9. architekturneutralität
17
Online Klassenbrowser
Was ist Java? Online Klassenbrowser
18
Einordnung Was ist Java?
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 (Tek- Tools), JOE Applets laufen innerhalb eines Browsers oder Appletviewer (SUN) ab Java ist nicht Javascript
19
Die Java Umgebung Was ist Java? 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-Compile- Debug Prozess, kontextsensitive Hilfe, GUI-Builder, Versionsverwaltung, Templates, zusätzliche Klassenbibliotheken • Beispiele: Borland JBuilder, Sun Forte, Micro-soft Visual J++, ...
20
Einsatz des JDK von SUN Allgemeines zu Java erstellen:
• 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:
21
Installation von Java Download des JDK: Download von Java (Win95/NT)
22
Installation von Java (Win95/NT)
23
Installation von Java (Win95/NT)
Modifiziern des Zugriffspfad in der Autoexec.bat Datei (nur Win95/98):
24
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
25
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
26
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 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.
27
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.
28
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.
29
Darstellungsmethoden
Tabelle
30
24:15 = 1 Rest 9 Beispiel: GGT Beispiel: Bestimme GGT von 24 und 15:
6 :3 = 2 Rest 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"
31
Flußdiagramm Flussdiagramm
32
Struktogramm
33
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%)
34
Natürlichsprachlicher Algorithmus
Start Zinseszins Lies Startkapital WENN Startkapital<0 DANN Ausgabe "Negatives Startkapital" SONST Lies Zinssatz WENN Zinssatz<0 DANN Ausgabe "Zinssatz negativ" Lies Dauer WENN Dauer<0 DANN Ausgabe "Dauer negativ" 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
35
Struktogramm
36
Flussdiagramm
37
Schritte zur Programmentwicklung
Formulierung des Problems 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)
38
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“);
39
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 b ein: 0 0.0 ist unzulaessiger Wert
40
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 Celsius 0 I .. 300 I 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 do- while Schleife.)
41
2 Arten von Datentypen: Primitive 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’;
42
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 = f;
43
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....");
44
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
45
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.
46
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); }
47
Kontrollfluß und Schleifen
if – else if (boolscher Ausdruck) statement else Beispiel: if (a % 2 == 0) { System.out.println(“a ist gerade“); } else { System.out.println(“a ist ungerade“); While Schleife while (boolscher Ausdruck) i = 1; a = 0; while (a < 10) { a = a + i; i = i + 1;
48
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++; }
49
do – Schleife for – Schleife do do { Schleifen
statement while (boolscher Ausdruck); Beispiel (Test zu Beginn/Ende der Schleife): do { System.out.println(a); a++; } while (a < 50); while (a < 50) { } for – Schleife for (init; boolscher Ausdruck; Schritt) Beispiel: for (int i = 1; i < 100; i++) { System.out.println(“i = “ + i);
50
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++)
51
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); }
52
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);
53
Switchanweisung Switch Statement Beispiel: 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“); default: System.out.println(c + „ ist ein Konsonant“);
54
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 : lang/String.html
55
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“); }
56
* 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(); }
57
Erstellen Sie zu den in den Aufgaben 1 bis
4 aus der Vorlesung „Algorithmen“ erstellten Algorithmen die zugehörigen Java- Programme.
58
Eindimensionale Arrays
Erzeugen (2 Möglichkeiten): Erzeugung durch new-Operator: float v[ ] = new float[4];
59
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)
60
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) { for(int i = 0; i < lt.length; i++) System.out.println(lt[i]); } Beispiel: (Summe des Arrays lt) int summe =0; summe = summe + lt[i]; System.out.println("Summe: " +summe);
61
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; System.out.println(nums[i]); } Beispiel: (Suchen des größten Wertes im Array) public class ArrayGreat { double [ ] nums = new double[10]; //Klammernb koennen auch hier stehen 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]);
62
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: int a1[ ]= {1,2,3,4,5}; // Definition von a1 a2 = a1; // Zuweisung von a1 an a2 for(int i = 0; i < a1.length; i++)
63
Arrays Kopieren von Arrays (by reference): Ausgabe:
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]+" "); a=b; System.out.print(a[i]+" "); a[0]=33; } Ausgabe: a: b: a: a: b:
64
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; a=3; } Ausgabe: a: 1 b: 2 a: 2 a: 3
65
Arrays Kopieren von Arrays (by value): Ausgabe: a: 1 2 4 8 16
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.arraycopy(a,0,b,0,a.length); System.out.print(a[i]+" "); a[0]=33; } Ausgabe: a: b: a: b: a:
66
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.arraycopy(a,0,b,b.length,a.length); System.out.print(a[i]+" "); a[0]=33; } 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);
67
Mehrdimensionale Arrays (Felder)
byte ZweiDimArray[ ][ ]; Deklaration der Variablen ZweiDimArray mit Typ byte[][] (Array-von-Array-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 byte-Arrays 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];
68
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:
69
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++) { System.out.print (matrix[i][j] +" "); System.out.println(); } Ausgabe:
70
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 1 2 2 3 4
71
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.
72
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 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]+“ „); }
73
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); 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]+“ „);
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); System.out.print(nums[i]+“ „); System.out.println(); return nums; } public static void ausgabe (int[ ] 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); ausgabe(nummer);
75
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); System.out.print(nums[i]+“ „); System.out.println(); return nums; } public static void ausgabe(int[ ] 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); ausgabe(nummer);
76
Objektorientierte Softwareentwicklung
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
77
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.
78
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.).
79
Prinzip der objektorientierten Programmierung
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).
80
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 * * r; } public double area() { return * 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());
81
Klassen und Objekte a = area(c); verwendet, sondern
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; // Initialisiere den Kreis mit c.y = 2.0; // Mittelpunkt (2,2) und c.r = 1.0; // 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 Objekterzeugung: Circle c = new Circle(); // Konstruktor
82
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 * * r; } public double area() {return * r*r; } }
83
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 * * r; } public double area() {return * 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; c1.r=2; } Ausgabe: Area c1: Area c2: Area c1: Area c2: Area c1: Area c2:
84
Klassen und Objekte Klassenvariablen: Zugriff auf 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 * * r; } public double area() {return * r*r; } } Zugriff auf Klassenvariablen: System.out.println(“Kreise: “ + Circle.num_circles); Konstanten: public static final double PI= ; public double x,y,r; // ... etc.
85
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).
86
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 c = Circle.bigger(a,b); // oder b.bigger(a);
87
Beispiele zu Klassen Klassen und Objekte 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“, f, 680.5f); System.out.println(„Mein Auto: „+ ente);
88
Beispiele zu Klassen Klassen und Objekte 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; 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;
89
Beispiele zu Klassen Klassen und Objekte
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));
90
Aufgaben zu Klassen Aufgaben Aufgabe 1
Schreibe eine Klasse, die die komplexen Zahlen repräsentiert. 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 Erstelle einen oder mehrere geeignete Konstruktoren zur Instanziierung von Polynomen 2. Grades 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.
91
Vererbung Vererbung von Klassen 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 { String matrNr; Student(int id, String name, String tel, String matrNr) { this.matrNr = matrNr;
92
Vererbung von Klassen Beispiel Benutzergruppen: Mitarbeiter Frage:
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.
93
Vererbung: Grundprinzip
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!
94
Vererbung: Grundprinzip
Vererbung von Klassen Vererbung: Grundprinzip
95
Vererbung in Java Vererbung von Klassen
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.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).
96
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");
97
Vererbung von Klassen Beispiel: Das Prinzip:
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. 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.
98
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!
99
Vererbungshierarchie
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; ... }
100
Vererbung von Methoden
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.
101
Überschreiben von Methoden
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 */ } { return name + ":" + tel + ", " + matrNr; }
102
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.
103
class Unterklasse extends Oberklasse {
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.
104
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 super.print(); System.out.println("Leiter der Abteilung: "+ this.Abteilung);
105
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 }
106
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", f, 680.5f); System.out.println("Mein Auto: "+ ente);
107
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", f, 680.5f,"Normal",28); System.out.println("Mein Auto: "+ ente);
108
Vererbung von Klassen Objektklasse Object
109
Vergleich von Objekten
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(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)));
110
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 3/13==3/13 ? true 13/3.equals(3/13) ? false 13/3.equals(13/3) ? 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; } ... 13/3.equals(13/3) ? true
111
Daten verstecken und kapseln
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.
112
Erreichbarkeit von Klassenelementen
Vererbung von Klassen Erreichbarkeit von Klassenelementen Sichtbarkeit Erreichbar für public protected friendly private Gleiche Klasse Ja Klasse im gleichen Paket Nein Subklasse im anderen Paket Keine Subklasse, anderes Paket nein
113
Aufgaben zu Klassen Aufgaben 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. Erstelle einen oder mehrere geeignete Konstruktoren 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. 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
114
Aufgaben zu Klassen Aufgaben 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 Erstelle einen oder mehrere geeignete Konstruktoren 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.
115
Aufgaben zu Klassen Aufgaben 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: SIEB = alle natürlichen Zahlen von 2 bis N Primzahlen = leere Menge wiederhole die Schritte (4) bis (6) solange, bis SIEB leer wird bestimme die kleinste Zahl MIN in SIEB füge MIN zu Primzahlen hinzu entferne MIN und alle seine ganzahligen Vielfachen aus SIEB Schreibe ein Programm, das diesen Algorithmus implementiert.
116
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.
117
Exception-Handling Exceptions
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 */
118
Exceptions Beispiel: Ausgabe: Exception gefangen
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(); at ExceptionMethods.main
119
Eigene Exceptions definieren und erzeugen
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 throws- Klausel 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.
120
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() g();
121
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)
122
Exception Matching Exceptions
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“);
123
Exceptions Die Sneeze Exception wird natürlich von der ersten Catch-
Klausel gefangen. Wenn die erste Catch-Klausel gelöscht wird, so ist der code immer noch lauffähig, da catch (Annoyance) alle Annoyance- Exceptions 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.
124
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
125
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 (){ // Ein Client benutzt die Geraete class Wohnzimmer { ... Irgendeine Methode ... // Neues Geraet kaufen Stereoanlage hifikiste= new StereoAnlage (...); // Das Geraet verspricht einiges.... ..... hifikiste.playNextTitle(); hifikiste.getNextRadioStation(); ....
126
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 { 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();
127
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
128
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“)
129
Applets Erstellen eines Applets: Ausgabe des Applets: HTML-Datei:
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>
130
Applets Aufruf des Appletviewers: Darstellung im Appletviewer
appletviewer FirstApplet.html Darstellung im Appletviewer
131
Applets Darstellung im WWW-Browser
Öffnen mit Menüpunkt Open Page des File Menüs im Netscape Browser
132
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);
133
Applets Die HTML-Datei <HTML>
<APPLET code="SecondApplet.class" width=500 height=300> </APPLET> </HTML> Aufruf des Appletviewers: appletviewer SecondApplet.html Darstellung im Appletviewer
134
Applets Darstellung im WWW-Browser
Öffnen mit Menüpunkt Open Page des File Menüs im Netscape Browser
135
Applets Weitere Beispiele HTML-Datei <html> <body>
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>
136
Applets
137
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); public boolean keyDown(Event e, int key) { if ((e.id == Event.KEY_PRESS) && (key == ’c’)) { clear(); else return false; public boolean action(Event e, Object arg) { if (e.target == clear_button) { public void clear() { g.setColor(this.getBackground()); g.fillRect(0, 0, bounds().width, bounds().height);
138
Applets Applet zu Beginn Applet nach dem Zeichnen
139
Das Event-Modell von Java 1.0
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 Component-Objektes übergeben, in dem sie aufgetreten sind. (Component ist die Superklasse aller GUI-Komponenten).
140
Das Event-Modell von Java 1.0 (Fortsetzung)
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“.
141
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); public boolean keyDown(Event e, int key) { if ((e.id == Event.KEY_PRESS) && (key == ’c’)) { clear(); else return false; public boolean action(Event e, Object arg) { if (e.target == clear_button) { public void clear() { g.setColor(this.getBackground()); g.fillRect(0, 0, bounds().width, bounds().height);
142
Das Event-Modell von Java 1.1
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 Event- Listener 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.
143
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) {;}
144
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_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;
145
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);
146
Events
147
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); }
148
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
149
Graphische Benutzeroberfläche
AWT Oberfläche
150
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)
151
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()
152
Graphische Benutzeroberfläche
Button Konstruktoren: Button() Button(text) Methoden (Auswahl): 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;
153
Graphische Benutzeroberfläche
Textfeld Konstruktoren: TextField() TextField(String text) TextField(int columns) TextField(String text, int columns Methoden (Auswahl): 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);
154
Graphische Benutzeroberfläche
TextEditor Konstruktoren: TextArea(int rows, int columns) TextArea(String text) TextArea(String text, int rows, int columns) TextArea(String text, int rows, int columns, int scrollbars) Konstanten: 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()
155
Graphische Benutzeroberfläche
Label Konstruktoren: Label() Label(String text) Label(String text, int alignment) Konstanten: CENTER LEFT RIGHT Methoden (Auswahl): String getText() void setText(String str)
156
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() Checkbox getCurrent() boolean setCurrent()
157
Graphische Benutzeroberfläche
Auswahlbox Konstruktor: Choice() Methoden (Auswahl): 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");
158
Graphische Benutzeroberfläche
List Konstruktor: List() List(int rows) List(int rows, boolean multipleSelect) Methoden (Auswahl): 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");
159
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)
160
Graphische Benutzeroberfläche
Menuleisten Aussehen: Komponenten: Frame MenuItem Menu
161
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(); }
162
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");
163
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);
164
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“);
165
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>
166
Graphische Benutzeroberfläche
Layoutmanager Ausgabe: weitere Layoutmanager: Grid Layout Card Layout
167
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(); }
168
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");
169
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"); }
170
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);
171
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(); }
172
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); }
173
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);
174
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_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; }
175
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");
176
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");
177
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");
178
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(); }
179
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(); upper = Integer.parseInt(tmp); System.out.println("neue Grenze: "+upper); 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");
180
Graphische Benutzeroberfläche
Ergebnis von DrawFkt1
181
Graphische Benutzeroberfläche
Ergebnis von Textbox Ergebnis von TextBox1 Ergebnis von TextBox2
182
Das Input-Output-System von Java
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.
183
Typen von InputStream Streams
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.
184
Typen von OutputStream
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.
185
Reader und Writer Streams
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); }
186
Andere Art des Exception-Handlings
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");
187
Die Methoden von InputStream
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.
188
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]);
189
Die Methoden von OutputStream
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.
190
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 class FileDemoIO { int i=0; FileOutputStream out = new FileOutputStream("tmp2"); out.write(3); FileInputStream in = new FileInputStream("tmp2"); i = in.read(); System.out.println("Test = "+ i);
191
Die Klasse File Streams
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 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.
192
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.
193
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.
194
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]);
195
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);
196
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.
197
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
198
Threads Beispiel: Ein einfacher Thread Ausgabe:
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
199
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);
200
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 (); thread.sleep (Math.round (1000.0*Math.random ())); System.out.println („ZweiterThread: „ + i);
201
Threads Ausgabe: misun3:106>java ThreadDemo ErsterThread: 0
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
202
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");
203
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);
204
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 (); thread.sleep (Math.round (1000.0*Math.random ())); System.out.println ("ZweiterThread: " + i);
205
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);
206
Abstract Windowing Toolkit (AWT)
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.
207
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.
208
Swing-Komponenten (JComponent)
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)
209
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.
210
Innere Klassen (inner class)
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.
211
Packages und import Ergänzungen
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 File- Separator 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.
212
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 import- Statement 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.
213
Java-Archive (jar) Ergänzungen
Ein Java-Archiv enthält Dateien und eventuell auch ganze Directory- Strukturen (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 Class- Files 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.
214
Java im Web-Server (CGI, Servlets)
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 Benutzer- Eingaben, 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 Script- Sprache 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 Java- Programme sofort direkt aufrufen kann (z.B. die neueren Versionen von Apache, Netscape Enterprise Server und vielen anderen).
215
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.
216
Internet-Protokoll, Server und Clients
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 Supervisor- Privilegien (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.
217
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.
218
Datenbanken Ergänzungen
Zu den wichtigsten Anwendungsgebieten von Java zählen User- Interfaces 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.
219
Java Beans Ergänzungen
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 Beans- Konventionen 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.
220
Verwendung von Unterprogrammen (native methods, JNI)
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.
Ähnliche Präsentationen
© 2025 SlidePlayer.org Inc.
All rights reserved.