Sie sind auf Seite 1von 211

Ziele der Vorlesung Programmierung

Kontext: Programmierung im Software-Entwicklungsprozess Grundlegende objektorientierte Konzepte Programmieren in Java Neugier auf weiterfhrende Java-Themen

Anforderungen an die Beteiligten


Dozent: Vermitteln des Stoffes in angemessenem Tempo Gratwanderung zwischen Breite und Tiefe Ausgleich der unterschiedlichen Vorkenntnisse Blick ber den Vorlesungstellerrand bungsorganisatoren / Tutoren: Vertiefen der Vorlesungsinhalte durch bungen Einfhrung in die praktische Nutzung einer Programmiersprache Lernhilfen und zustzliche Herausforderungen
5 6

Anforderungen an die Beteiligten


Studierende: eigenstndige Nachbearbeitung Auseinandersetzung mit Primr- und Sekundrliteratur Teilnahme an der Vorlesung und an den bungen berwinden der Praxisschwelle vorbelastete Studierende (also die, die meinen sie knnten Java und/oder programmieren): darauf achten, dass der geeignete Einsprungpunkt nicht verpasst wird!

Hinweise zum Feedback


Mehrfache Abfrage Ihres Feedbacks und direkte Verffentlichung der Ergebnisse Versuch der Umsetzung der erkannten Verbesserungsmanahmen Interaktives Feedback jederzeit willkommen!

Hinweise zu Materialien
Folienskrip wird zur Verfgung gestellt, einige Teile werden in der Vorlesung entwickelt! Zu allen fehlenden Teilen wird auf Literatur verwiesen. Folien sind Stichpunkte! Es gilt das gesprochene Wort! bungen optionale Abschnitte Hilfreich: Anmerkungen in den Folien und handschriftliche Ergnzungen (-> aktive Teilnahme)

Literatur

Originalliteratur von JavaSoft http://www.javasoft.com/docs/index.html Sonstige Literatur

10

Literatur von JavaSoft


The Java Tutorial
Als Online- und Downloadversion Als Buchversion in deutsch und englisch (meist nicht so aktuell) Sehr umfangreich, ausfhrliche Beschreibung vieler Aspekte der Sprache und Einfhrung in den Umgang mit Klassenbibliotheken Gesamtbersicht der Klassenbibliotheken liefert "JDK 1.2 Documentation/Java 2 SDK, SE v1.3 Documentation Fr exakte Syntaxdefinition der Sprache ist die "Java Language Specification" gedacht. Es ist kein Programmierlehrbuch.

Literatur von JavaSoft


JDK 1.2 /Java 2 SDK, SE v1.3 Documentation
Als Online- und Downloadversion Gesamtbeschreibung der Klassenbibliothek Als Nachschlagewerk gedacht, kein Tutorial

Java Language Specification


Als Online- und Downloadversion Komplette Beschreibung der Syntax Sehr schwer zu lesen Syntaktische Feinheiten, die im Tutorial nicht deutlich werden

11

12

Literatur von JavaSoft


In der Uni-Bibliothek verfgbar!

Sonstige Literatur
"Einfhrung in die objektorientierte Programmierung mit Java"
Autoren: E.-E. Doberkat / S. Dimann Erschienen 1998 im Oldenbourg Verlag, Mnchen, ISBN 3-486-24786-7 Programmierlehrbuch, beschreibt verschiedene Programmiertechniken, Begleitung zur Vorlesung an der Universitt Dortmund

Java Virtual Machine Specification


Spezifikation der virtuellen Maschine Nur fr Leute gedacht, die selbst Java-Compiler schreiben wollen Wichtig, um offenen Standard zu gewhrleisten (im Gegensatz zu vielen Microsoft-Produkten)

"Java 1.1 lernen" Java Developer Connection


http://www.javasoft.com/jdc Kostenlose Anmeldung erforderlich Viele Informationen ber neueste Entwicklungen Downloadmglichkeit von Beta-Versionen
13

Autor: Guido Krger Erschienen bei Addison-Wesley-Longman 1997 Einfhrungsbuch, gut fr erste Schritte Keine erschpfende Behandlung vieler Themen, nur erster berblick Nicht als Nachschlagewerk zu empfehlen

14

Sonstige Literatur
Thinking in Java
Autor: Bruce Eckel http://www..eckelobjects.com/javabook.html

Sonstige Literatur
"Java in a nutshell"
Autor: David Flanagan, deutsche bersetzung: Peter Klicman Erschienen bei O'Reilly 1998 Lehrbuch fr den Fortgeschritten gut geeignet fr C/C++ - Programmierer Erschpfende Klassenbersicht Wichtige Details fr die Praxis

"Foundations of Computer Science


Autor: Alfred V. Aho, Jeffrey D. Ullman Erschienen bei W.H. Freeman and Company 1995 Grundlegende Konzepte und Datenstrukturen
15 16

Sonstige Literatur
"Fundamentals of Software Engineering"
Autor: Carlo Ghezzi, Mehdi Jazayeri, Dino Mandrioli Erschienen bei Prentice-Hall, 1991 guter berblick ber Software-Technologie und die Einbettung der Programmierung

Gliederung der Vorlesung


1 Vorwort und Zielsetzung 2 Einordnung der Vorlesung Programmierung 2.1 Kontext Informatik 2.2 Kontext Software-Entwicklung 3 Objektorientierte Analyse und objektorientierter Entwurf 4 Grundbegriffe zu Programmiersprachen 5 Java als objektorientierte Programmiersprache 6 Ein erstes Java-Beispiel

17

18

Gliederung der Vorlesung


7 Java-Syntaxkonstrukte 7.1 Primitive Datentypen, Literale und Variablen 7.2 Aufruf von Objekten, einfacher Nachrichtenaustausch 7.3 Operatoren, Ausdrcke, Zuweisungen 7.4 Anweisungen 8 Programmierkonventionen und Dokumentation 9 Rekursive Methoden 10 Innere Klassen 11 Elementare Java-Klassen 11.1 String 11.2 Felder 11.3 Object

Gliederung der Vorlesung


12 hnliche Objekte (Vererbung) 13 Schnittstellen (Interfaces) 14 Ausnahmen (Exceptions) 15 Pakete und Zugriffskontrolle 16 berblick ber Java-Klassenbibliotheken 17 Dynamische Datenstrukturen, ihre Anwendung und ihre Realisierung mit Java 17.1 Listen 17.2 Bume 17.3 Graphen 17.4 Schlangen 17.5 Stapel 17.6 Mengen
19 20

Gliederung der Vorlesung


18 Ein- und Ausgabe (java.io) 19 Graphische Oberflchen (java.awt, java.swing) 20 Applets (java.applet) 21Threads 22 Rckblick, Ausblick, Fazit

Kapitel 2
Einordnung der Vorlesung Programmierung

21

Kontext Informatik
Informatik: keine Naturwissenschaft (noch?) keine Ingenieurwissenschaft weil
bewhrte Abstraktionen / Lsungsmuster fehlen nicht einheitlich bezeichnet und verwendet werden zuverlssige Planungen der Erstellung von Lsungen kaum mglich sind

Kapitel 2.1
Kontext Informatik

24

Aufteilung Informatik
Theoretische Informatik: allgemeingltige Berechnungsmodelle, Gesetzmigkeiten, zunchst: anwendungsunabhngig Praktische Informatik: Anwendung der Ergebnisse und Erkenntnisse der theoretischen Informatik auf Probleme der Nutzbarmachung von Rechnern, Bau von Compilern, Entwurf von Spezifikationssprachen Angewandte Informatik: Anwendung der Ergebnisse der theoretischen und praktischen Informatik zum Zweck der Lsung real existierender Probleme, Ziel: Wirtschaftlichkeit

Kontext Informatik
Modellbildung und Abstraktion als durchgngig verwendete Prinzipien in der Informatik, z.B:
von der realen Welt zur Beschreibung der relevanten Teile von realen Problemen zu Entwrfen von Entwrfen zu Programmen

Hierbei die immer gleiche Frage: Was gehrt ins Modell? Was wird wegabstrahiert?

25

26

Kontext Informatik
Wahl der richtigen Abstraktion oft schon entscheidend fr den Erfolg der Entwicklung von Datenverarbeitungslsungen! Eine der wesentlichen Abstraktionen manifestiert sich in Programmen. Hierin spiegelt sich die Entscheidung, bestimmte Merkmale der realen Welt als fr den Problembereich aufzufassen und diese in bestimmter Weise abzubilden.

Kontext Informatik
Die Vorlesung Programmierung beschftigt sich mit der Frage, wie das Ergebnis der Abbildung (Programme) aussehen sollte. Hierbei wird angenommen, dass Klassen und Objekte die grundlegenden Konstrukte sind, um Programme zu reprsentieren / zu strukturieren. In der Vorlesung Programmierung wird genau eine Sprache zur Formulierung von Programmen vermittelt. Diese Sprache heit Java. Java ist objektorientiert.

27

28

Kontext Software-Entwicklung
Obwohl eine hohe volkswirtschaftliche und betriebswirtschaftliche Abhngigkeit von Software besteht

Kapitel 2.2
Kontext Software-Entwicklung

komplexe Software in allen Bereichen des Lebens eingebettete Software in PKWs, Haushaltsgerten Steuerung in der Verkehrs- und Energietechnik admininistrative Geschftsprozesse in fast allen Unternehmen Software-Kosten als substantieller Anteil in vielen IT-Etats (hufig: Wartung) Einflu auf fast alle Innovationen

ist die Entwicklung von Software nach wie vor mit hohen Risiken behaftet.
30

Abbruchrate von Software-Entwicklungsprojekten

Ursachen der Unzuverlssigkeit von SoftwareEntwicklung nach [CKI88]


B. Curtis, H. Krasner, N. Iscoe, A Field Study of the Software Design Process for Large Systems, Communications of the ACM, November 1988, Vol. 31, No. 11, pp 1268 - 1287

Thin Spread of Application Domain Knowledge


Anzahl Function Points 1 FP 10 FP 100 FP 1.000 FP 10.000 FP 100.000 FP Durchschnitt Frher als geplant 14,86 % 11,08 % 6,06 % 1,24 % 0,14 % 0,00 % 5,53 % Termingerecht 83,16 % 81,25 % 74,77 % 60,76 % 28,03 % 13,67 % 56,94 % Versptet 1,92 % 5,67 % 11,83 % 17,67 % 23,83 % 21,33 % 13,71 % Abgebrochen 0,25 % 2,00 % 7,33 % 20,33 % 48,00 % 65,00 % 23,82 %

Projekte in neuer Branche Technologiezentriertheit

Fluctuating and Conflicting Requirements


Markt verschiedene Kunden Erkenntnisprozesse Miverstndnisse

Communication and Coordination Breakdowns


Quelle: C. Jones, Large Software System Failures and Successes, in: American Programmer, Vol. 9, No. 5, September 1996
31

unterschiedliche Vorstellungen und Zielsetzungen Inkongruenzen zwischen Kompetenz und Verantwortung Kapitulation
32

Aspekte der Software-Entwicklung


Unter Software-Entwicklung verstehen wir das Zusammenspiel der folgenden vier Bereiche: Projektmanagement: Kosten, Zeit, Personal Qualittsmanagement: bereinstimmung mit den Anforderungen Konfigurationsmanagement: Verwalten aller Bestandteile einer Datenverarbeitungslsungen und ihrer Versionen Software-Erstellung: Erstellen aller Modelle (z.B. Programme)
33

Prinzipien des SWE


Prinzip: Grundsatz, den man seinem Handeln zugrundelegt Technik: Vorschrift zur Durchfhrung einer Ttigkeit (Was ist wie zu tun?) Methode: Planmig anwendbare, begrndete Technik zur Erreichung vorgegebener Ziele (Was ist wie und unter welchen Rahmenbedingungen zu tun, so da ein gutes Ergebnis erreicht wird?) Werkzeuge: Rechneruntersttzung fr Techniken und Methoden Sprache: syntaktische Regeln zur Untersttzung einer Methode oder Technik. Eine Sprache besteht aus ihrer Syntax und ihrer Semantik:
formale Sprachen haben eine formale Syntax- und Semantikdefinition (Aussagenlogik, Prdikatenlogik) semiformale Sprachen haben eine formale Syntax, aber keine klar definierte Semantik (SADT, UML) informale Sprachen haben weder eine formale Syntax noch eine formale Semantik (Deutsch, Englisch)
34

Prinzipien des SWE

Prinzip Striktheit und Formalitt


strikte Anforderungsdefinition strikte Dokumentation des Software-Prozesses und seiner Ergebnisse strikter Entwurf strikte Spezifikation aller Dokumente formale Beschreibung an kritischen Stellen
kritisch fr das Verstndnis kritisch im Hinblick auf sptere nderbarkeit kritisch im Hinblick auf das Schadenspotential von Miverstndnissen

Werkzeuge

OTW/PRADOS

Sprachen Methoden (Techniken) Prinzipien

UML/SADT OO / funktional Dekomposition

35

36

Prinzip Strukturierung
(separation of concerns / Unterteilung in Aspekte)
Beispiele von Aspekten
Funktionalitt Robustheit Performanz und Ressourcenverbrauch Organisation der Software-Entwicklung Konfigurations-Management und viele andere concerns Striktheit und Formalitt

Prinzip Strukturierung

Arten der Unterteilung


zeitliche Unterteilung: Anforderungsanalyse / Entwurf / Programmierung / Test qualitative Unterteilung: Effizienz / Robustheit / Korrektheit perspektivische Unterteilung: Verwendung von Datenstrukturen / Datenflu / Kontrollflu Dekomposition (Unterteilung in Bestandteile): Komponente 1, Komponente 2

Abhngigkeit zwischen Aspekten


Performanz und Datenintegritt Funktionalitt und Zielplattform

37

38

Prinzip Strukturierung

Prinzip Abstraktion

Dekomposition

Komposition
Legende
Komponente / Modul A

Trennung von wichtigen und unwichtigen Merkmalen Unterschlagung / Wegabstraktion der unwichtigen und Betonung der wichtigen zum Zweck der Konzentration auf das Wesentliche Gngige Abstraktionen
die Signatur einer Operation abstrahiert von der Realisierung der Operation die Konstrukte einer Programmiersprache abstrahieren von Prozessorendetails ein Datenfludiagramm abstrahiert von den Aufrufstrukturen zwischen Komponenten

A ruft B auf

39

40

Prinzip Abstraktion
Wichtigkeit und Unwichtigkeit ist relativ zum Zweck der Abstraktion

Prinzip Annahme der nderungsnotwendigkeit

Realitt
verkrzende Eigenschaften

Modell
erweiternde Eigenschaften

Software ist Gegenstand von nderungen. Ursachen fr nderungen:


Beseitigung von Fehlern (korrektive Wartung) Verbesserung nicht funktionaler Eigenschaften (perfektive Wartung) Erweiterung der Funktionalitt wegen sich ndernder Rahmenbedingungen (adaptive Wartung) Erweiterung der Funktionalitt wegen Erkenntnisgewinn whrend der Entwicklung

Erde

Landkarte

Verkrzende Eigenschaften im Modell Landkarte:


Wassertemperatur Fauna / Flora

Erweiternde Eigenschaften:
Lngen- und Breitengrade

41

42

Prinzip Annahme der nderungsnotwendigkeit

Aktivitten der Software-Entwicklung


In der Software-Erstellung gibt es eine Vielzahl von Aktivitten, zu den wichtigsten gehren:

Software 1.Version unklare Anforderungen


Software-Proze

geklrte Anforderungen an die Software

Software 2. Version

Software-Proze

weiter geklrte Anforderungen an die Software

...

Anforderungsanalyse Spezifikation Entwurf Programmierung Testen Inbetriebnahme

Software-Proze ist kein typischer Fertigungsproze !

43

A software engineer must of course be a good programmer, be well-versed in data structures and algorithms, and be fluent in one or more programming languages. ... The software engineer must be familiar with several design approaches, be able to translate vague requirements and desires into precise specifications, and be able to converse with the user of a system in terms of the application rather than in computerese. Ghezzi,Jazayeri,Mandrioli 1991, vgl. Literaturliste
44

Programmierung
Programmierung: Verwendung einer Programmiersprache, um Anforderungen, Spezifikationen, Entwrfe in maschinenausfhrbare Form zu formulieren. Um genau zu sein: um eine Form zu erreichen, die automatisch in eine maschinenausfhrbare Form bersetzt werden kann.

Objektorientierte Software-Erstellung
Drei Aktivitten auf der Grundlage der gleichen Grundkonstrukte:
Objektorientierte Analyse (OOA) Objektorientiertes Design (OOD) Objektorientierte Programmierung (OOP)

Analyse / Design wird durch objektorientierte Modellierungssprachen untersttzt


OMT (Object Modeling Technique) UML (Unified Modeling Language) => siehe http://www.rational.com

Programmierung mit objektorientierter Programmiersprache


Smalltalk, C++, Objective C, Java, Classic Ada, Delphi, Eiffel, Beta

hohes Wiederverwendungspotential
45 46

Kapitel 3
Objektorientierte Analyse und Design vgl separate pdf-Datei

Kapitel 4
Grundbegriffe zu Programmiersprachen

47

Programmiersprache
Die Syntax einer Programmiersprache legt fest, welchen Aufbau Programme haben. Lexikalische Ebene: wie werden aus Zeichen Wrter gebildet? Syntaktische Ebene: wie werden aus Wrtern Stze gebildet? Die Syntax wird durch eine Grammatik festgelegt.

Programmiersprache
Eine Grammatik ist gegeben durch ein Viertupel (S, T, N, P) mit:
S ist ein Startsymbol T ist eine Menge von Terminalsymbolen N ist eine Menge von Nichtterminalsymbolen P ist eine Menge von Produktionen / Ableitungsregeln

49

50

Programmiersprache
Terminalsymbole beschreiben Symbole, die in den Stzen der Sprache vorkommen. Nicht-Terminalsymbole kommen nicht in den Stzen der Sprache vor. Sie werden gebraucht, um die Anwendung der Ableitungsregeln zu koordinieren. Das Startsymbol ist ein ausgezeichnete Nicht-Terminalsymbol. Es legt fest, mit welcher Ableitungsregel begonnen wird, um zu einem syntaktisch korrekten Satz der Sprache zu kommen. Die Ableitungsregeln legen fest, wie eine Sequenz von NichtTerminal- und Terminalsymbolen durch eine Folge anderer Terminalsymbole und Nicht-Terminalsymbole ersetzt werden kann.
51

Programmiersprache
Beispiel einer Produktion:
einfacher-deutscher-Satz = Subjekt Prdikat Objekt {adverbialeBestimmung} Subjekt = Nomen | Personalpronomen Personalpronomen = Ich | Du | ...
{} steht fr 0 bis n-fache Formulierung [] steht fr Optionalitt (0 oder einfaches Vorkommen) | trennt Varianten voneinander fett: Terminalsymbole, kursiv: Nicht-Terminalsymbole

52

Programmiersprache
Wie ndert sich die Grammatik, wenn immer mindestens eine adverbiale Bestimmung vorkommen mu? Wie ndert sich die Grammatik, wenn ich zwischen adverbialen Bestimmungen des Ortes, der Zeit und der Art unterscheiden mchte?

Programmiersprache
Beispiel einer Produktion:
ClassDeclaration = {ClassModifier} class Identifier [extends SuperClass] [implements Interfaces] {FieldDeclarations}

Beispiel einer Grammatik:


Grammatik vllig-simpel = ( START, {(,),+,1,leer}, {S,START}, {START = S | leer, S = S+S | 1 | (S)} ) Prfung, ob der Satz (1+1) +1 in der Sprache vllig-simpel gltig ist: START -> S -> S+S (S) -> S+S 1 1

53

54

Programmiersprache
Welche Sprache wird durch die folgende Grammatik erzeugt? Grammatik unklar = ( S, {a,b,c}, {S,A,B}, {S = abc, S = aAbc, Ab = bA, Ac = Bbcc, bB = Bb, aB = aaA, aB = aa} )

Programmiersprache
L(G) = {anbncn | n 1}, wobei L(G) die Menge der Stze bezeichnet, die sich gem der Grammatik G erzeugen lassen.

55

56

Programmiersprache
Beweis von L(G) = {anbncn | n 1}: Induktionsanfang: Jede Ableitung beginnt mit der Anwendung der ersten oder zweiten Ableitung. Die erste liefert direkt abc (gehrt zur Sprache).

S = abc, S = aAbc, Ab = bA, Ac = Bbcc,

bB = Bb,

aB = aaA,

aB = aa

Induktionsschritt: Nun betrachten wir den Satz: D = aiAbici mit i 1. Annahme: Von diesem Satz aus erreichen wir nur Stze in der angenommenen Sprache. Beweis: Erst mal mu i-mal die Ableitung Ab = bA angewendet werden, denn nur so wandert das A nach rechts. Ergebnis: aibiAci Danach kann nur die Ableitung Ac = Bbcc angewendet werden. Ergebnis: aibiBbccci-1 = aibiBbc i+1 Danach kann nur noch i-mal bB = Bb angewendet werden. Ergebnis: aiBbi+1ci+1 Aus diesem Satz ergibt sich nun entweder: oder

57

ai+1bi+1ci+1 ai+1Abi+1ci+1

(gem aB = aa) (gem aB = aaA)


58

Programmiersprache
Fazit: Also enthlt L(G) genau die betrachteten Wrter (genau deshalb, weil es im Induktionsschritt keine weiteren Mglichkeiten der Anwendung von Ableitungen gab!) Bemerkung: Die betrachtete Sprache ist eine der typischen kontextsensitiven Sprachen! Um zu verstehen, da der Kontext ntig ist, mge man versuchen die gleiche Sprache mit einer kontextfreien Grammatik zu erzeugen.

Programmiersprache
Wenn auf der linken Seite aller Produktionen nur jeweils ein Nicht-Terminalsymbol steht, dann heit die Grammatik kontextfrei. Das bedeutet: die Ersetzung eines Nicht-Terminalsymbolen hngt nicht davon ab, in welchem Kontext das NichtTerminalsymbolen vorkommt. Java-Grammatik: www1.arcs.ac.at/users/mt/java/javasyntax.html#Number

59

60

Syntax-Beispiele Java
ClassDeclaration = {ClassModifier} class Identifier [extends SuperClass] [implements Interfaces] { FieldDeclarations } FieldDeclarations = {FieldDeclaration} FieldDeclaration = [DocComment] MethodDeclaration [DocComment] abstract InterfaceMethodDeclaration [DocComment] native NativeMethodDeclaration [DocComment] ConstructorDeclaration [DocComment] VarDeclaration StaticInitializer ;
61

Syntax-Beispiele Java
MethodDeclaration = ConstructorDeclaration = {MethodModifier} ConstructorModifier ResultType Declarator ( [ ClassName ( [ ParameterList ] ) ParameterList ] ) [ throws Exceptions ] [ throws Exceptions ] ConstructorBody Block MethodModifier = public | protected | private static final | synchronized

62

Programmiersprache
Die Semantik einer Programmiersprache legt fest, was die syntaktisch korrekten Stze der Sprache bedeuten. Die Semantik kann durch die Abbildung auf ein mathematisches Modell definiert werden (zum Beispiel auf Aussagen- oder Prdikatenlogik). blicherweise wird die Semantik einer Programmiersprache jedoch operational festgelegt. Das heit, die Bedeutung eines Satzes wird durch das Verhalten des Programms (das diesem Satz entspricht) auf einer Referenzmaschine definiert.
Zeit

bersicht ber die Entwicklung von Programmiersprachen


Objektorientierte Sprachen Bspe: C++, Smalltalk, Eiffel, Java Logische Sprachen Bsp: Prolog Konstrukte: Fakten, Regeln Imperative / Prozedurale Sprachen Bspe: Fortran, Cobol, Algol, PL1, Ada, C Prozeduren, while, case, if

Funktionale Sprachen Bspe: LISP, ML, Miranda Konstrukte: Funktionen

Assembler Bspe: RS600-Assembler Konstrukte: MV, ADD, GET)


Vorgngerbeziehung

63

Maschinensprache 001001

64

Charakterisierung / Vergleich
Java ist aus einem Projekt entstanden, Software fr elektronische Gerte zu entwickeln Daraus entstanden Anforderungen, die von Sun formuliert wurden Sun wirbt heute damit, dass Java diese Anforderungen erfllt Werbung und Wirklichkeit sind jedoch nicht deckungsgleich => Charakterisierungen von Java sind diskussionsbedrftig

Kapitel 5
Java als objektorientierte Programmiersprache

66

Einfach
Sun: Java ist einfach
Design nahe an C++, um Umstieg zu erleichtern Selten benutzte und schwer verstndliche Eigenschaften aus C++ wurden beseitigt
berladen von Operatoren Mehrfachvererbung

Objektorientiert

Sun: Java ist objektorientiert


Objektorientierte Funktionalitt realisiert Beste Konzepte der Sprachen C++, Objective C, Eiffel und Smalltalk

Garbagecollection vereinfacht Umgang mit Objekten, Programmierer mu Speicher nicht selbst freigeben

Diskussion
Ausgereifte Realisierung objektorientierte Eigenschaften ist eine Strke von Java

Diskussion
Mehrfachvererbung ist sicher berflssig berladen von Operatoren kann Lesbarkeit von Programmen erhhen Java ist sehr mchtig, daher nicht schnell zu erlernen Es ist einfach, verstndlich zu programmieren
67

68

Verteilt

Robust
Sun: Java ist ideal fr robuste Programmierung

Sun: Java ermglicht verteilte Programmierung


Standardprotokolle, wie TCP/IP, HTTP und FTP werden angeboten Zugriff auf Dateien ber URL's genauso einfach, wie Zugriff auf lokale Dateien

Java ist streng getypt, im Gegensatz zu C++ Java hat kein Zeigermodell => keine Integer-Zeiger-Konvertierung Garbagecollection

Diskussion
Plattformspezifische Unterschiede zwischen Unix und Windows bereiten jedoch Schwierigkeiten Diese sind jedoch lsbar

Diskussion
Oben aufgefhrte Schwachstellen in C++ sind in Java beseitigt aber: Klassenbibliotheken sind oft unausgereift

69

70

Sicher
Sun: Java legt viel Wert auf Untersttzung sicherer Netzwerkprogrammierung
Authentifizierungsalgorithmen basierend auf asymmetrischer Kryptographie Pointer-Semantik kann nicht manipuliert werden Applets knnen durch Signierung Rechte erhalten

Architekturneutral / Portabel
Sun: Java ermglicht plattformunabhngige SoftwareEntwicklung
Bytecode kann berall interpretiert werden AWT wird auf alle Plattformen abgebildet Sprache plattformunabhngig definiert, z.B. ist "int" immer 32 Bit lang, unabhngig von der Architektur

Diskussion
Die amerikanische Exportpolitik verhindert leider den direkten Export starker Verschlsselungssoftware Sicherheit eines Bytecode Verifyers nicht formal bewiesen, erfolgreiche Einbrche jedoch nicht bekannt

Diskussion
Leider sind API-Fehler plattformabhngig => "Write once test everywhere" :-) Portierung ist jedoch immer noch einfacher, als mit vielen anderen Sprachen
72

71

Dynamisch

Von C/C++ nicht bernommene Eigenschaften


Kein Prprozessor

Sun: Java ermglicht dynamische Programmierung


Bibliotheken knnen im laufenden System ausgetauscht und aktualisiert werden Keine Neucompilierung ntig

kein #define, #include oder typedef => Programmtext ist einfacher zu lesen

Keine Structures und Unions


Klassen erfllen gleichen Zweck

Keine Funktionen
Reiner objektorientierter Ansatz Es gibt aber Klassenmethoden, die hnliche Funktionalitt bieten

Keine Mehrfachvererbung von Klassen


Mehrfachvererbung in Interfaces jedoch mglich

73

74

Von C/C++ nicht bernommene Eigenschaften


Kein goto-Befehl
In strukturierter Programmierung nicht ntig Multilevel-break und Multilevel-continue kann goto ersetzen

Zusammenfassende Diskussion
Es ist Sun gelungen, den Bereich der Entwicklung verteilter Software-Systeme mit Java zu besetzen Sun hat bei dem Vorhaben eine breite Industrieuntersttzung Entwicklungen von komplexen Software-Paketen kommt aufgrund von Performance- und Stabilittsproblemen etwas langsamer voran

Kein berladen von Operatoren Keine automatische Typwandlung mit Informationsverlust


Expliziter Cast ntig

Keine Zeiger
Arrrays und Strings sind Objekte Objekte werden referenziert

75

76

Die Java Welt


Java ist mehr als eine Programmiersprache...

berblick zu Java

Die Java Welt


Entwicklung von Internet-Anwendungen Entwicklung von verteilten Anwendungen Java Applets
integriert in WWW-Seiten verbreitet ber das Internet

berblick zu Java

objektorientierte Programmierung plattformunabhngige Programme Klassenbibliothek und Programmier-Schnittstellen (Application Programming Interface API) Entwicklung und Vertrieb durch Sun Microsystems
Java Development Kit (JDK)/Software Development Kit (SDK) frei verfgbar

Java Applikationen
entworfen, um als separate Prozesse in einer Laufzeit-Umgebung auf beliebiger Plattform zu laufen kann auch ber das Internet vertrieben werden

77

78

bersetzen des Programmtexts

berblick zu Java

Vorteil: Plattformunabhngigkeit

berblick zu Java

Aus Java-Programmtext erzeugt der Java-Compiler eine JavaBytecode-Datei Auf dem Zielrechner interpretiert die Java Virtual Machine JVM diesen Bytecode und fhrt das Programm aus
Geschwindigkeitsprobleme

Compilierte Java Programme (d.h. Bytecode) laufen auf jeder JVM-fhigen Plattform

79

80

Bytecode / Class-Files
Java wird vom Java Compiler zu einer fest definierten Zielsprache bersetzt Die Zielsprache ist der Bytecode
sie ist maschinenhnlich, hat z.B. Register kann einfach interpretiert bzw. in Maschinencode anderer Plattformen bersetzt werden

JDK / JRE
Java Development Kit (JDK)/Software Development Kit (SDK) ist eine
kostenlose Software-Entwicklungsumgebung der Firma JavaSoft, um Java-Programme zu entwickeln Alle Entwicklungen sind mit JDK/SDK alleine mglich, kommerzielle Tools knnen jedoch Entwicklung untersttzen:
Visual Age (IBM) JBuilder (Inprise, Borland) Visual J++ (Microsoft) Java Workshop / Studio (Sun)

Jede Java-Klasse wird separat bersetzt und


in separater Datei, dem Class-File gespeichert. Das Format der Dateien wird Bytecode genannt. Auch andere Sprachen lassen sich nach Bytecode bersetzen.

Darf nicht ohne Lizenzgebhren weiterverkauft werden

Java Runtime Environment (JRE) ist eine


Untermenge des JDK/SDK, die bentigt wird, um Java-Applikationen laufen zu lassen Darf ohne Lizenzgebhren eigenen Produkten beigefgt werden
81 82

Virtual Machine / JIT-Compiler


Virtual Machine ist der Teil des JRE, der bentigt wird, um Bytecode zu interpretieren Classfiles werden nur bei Bedarf geladen und
entweder interpretiert oder vor Verwendung "just in time" in die Maschinensprache der Zielplattform bersetzt

Java Virtual Machine (JVM)


Bestandteile:
Byte Code Loader Byte Code Verifier Byte Code Interpreter

berblick zu Java

JIT-Compiler (Just-In-Time-Compiler) ist ein Compiler, der Klassen nur bei Bedarf zur Ausfhrungszeit bersetzt
Es gibt in der Regel Geschwindigkeitsvorteile im Vergleich zur Interpretation

83

84

Java Applikationen vs. Java Applets


Java Applets

berblick zu Java

Zusammenfassung
Applets / Applikationen

berblick zu Java

laufen innerhalb der JVM eines Webbrowsers haben eigene, festgelegte Zeichenflche im Webbrowser

Java Development Kit (JDK)/Software Development Kit (SDK) Compiler Java Runtime Environment (JRE) Java Virtual Machine (JVM) Interpreter, Just-in-time-Compiler (JIT) Bytecode, Class-Files Webbrowser Plattformunabhngigkeit
86

Java Applikationen
eigenstndige Applikationen laufen innerhalb der JVM werden auf der Befehlszeilenebene oder als Windows-Applikation gestartet

Programmieren in Java fr beide identisch


85

Klassen: Gleichartige Objekte


public class Girokonto { private int kontostand;

Klassen in Java

// in Pfennigen gerechnet

Kapitel 6
Ein erstes Java-Beispiel

public Girokonto() { kontostand = 0; }

/* Einzahlen und Abheben */ public void zahle (int pfennige){ kontostand = kontostand + pfennige; }
public int holeKontostand() { return (kontostand); } }

Modifier class Klassenname { Attribut-Deklarationen Methoden }

// /*

Kommentar Kommentar

*/

88

Von Klassen zu Objekten


Exemplare aus einer Klassen-Schablone:
Girokonto Kontostand (in Pfennigen) Ein-/Auszahlen Kontostand abfragen
Objekt Objekt Objekt Objekt

Klassen in Java

Attribute
Teile des Gesamtzustands eines Objekts
private int kontostand; private Girokonto meinKonto;

Klassen in Java

Modifier Datentyp attributname

Klasse ObjName = new Klasse(Typ1 name1, ...)

Erzeugen
Girokonto einKonto= new Girokonto();

Verndern von Attributen


kontostand = kontostand + pfennige;

Lschen: wenn nirgendwo mehr benutzt (automatische GarbageCollection) Zustand eines Objekts verndern ( Attribute) Nachrichten an ein Objekt senden ( Methoden)
89

Einkapseln von Attributen ( Ziel: mglichst alle Attribute einkapseln)


privat d.h. nur innerhalb des Objekts sichtbar ffentlich d.h. auch auerhalb des Objekts sichtbar (private) (public)
90

Methoden (1/2)

Klassen in Java

Methoden (2/2)
Aufruf von Methoden eines Objektes
konto.holeKontostand(); konto.zahle(+100);

Klassen in Java (Punkt-Notation, qualifizierter Zugriff)

Teile des mglichen Verhaltens eines Objekts (d.h. Nachrichten, die vom Objekt verarbeitet werden knnen)
public void zahle (int pfennige){ kontostand = kontostand + pfennige; } public int holeKontostand() { return (kontostand); }
Modifier Rckgabetyp Methodenname (Typ1 ParamName1,Typ2 Param...){ Liste von Anweisungen; [ return (Rckgabewert) ] }
91

Spezieller Rckgabewert: void

bergeben von Parametern


statt komplette Objekte zu bergeben, nur Zeiger darauf bei einfachen Datentypen als Wert kopiert (by reference) (by value)

Einkapseln von Methoden


privat, d.h. nur als interne Hilfs-Methode zugreifbar ffentlich, d.h. extern sichtbar (private) (public)
92

Spezielle Methode "main"


Einsprungpunkt bei "Ausfhren" einer Applikation

Klassen in Java

Hilfsklasse Bildschirm
Benutzereingaben und Bildschirmausgaben spter detaillierter, im Augenblick gengt Anwendersicht: "Welche Methoden gibt es?"

bergeben von Argumenten aus der Kommandozeile mglich fr Testen von Klassen-Implementierungen geeignet
public class TestGirokonto { ... public static void main(String[] args) { ... // Hier Code zum Testen einfgen } ... }

komfortable Ausgabe auf den Bildschirm


Bildschirm.gibAus (text)

komfortable Eingabe eines Textes von Tastatur


eingabetext = Bildschirm.gibEin()

Warten auf Tastendruck


Bildschirm.warteAufTastendruck()

93

94

bung: Attribute und Methoden


Motivation
Klasse erweitern um Attribute, Methoden Erzeugen von Objekten und Nachrichtenaustausch (Methoden) zwischen Objekten

bung: Attribute und Methoden


Lsung 1:
public class Girokonto {
...

private boolean istGesperrt;


...

Aufgaben Ergnzen Sie die Klasse "Girokonto":


zum Sperren eines Kontos: boolesches Attribut istGesperrt mit den Methoden void sperre(), void entsperre() und boolean istGesperrt() zum berschreiben des aktuellen Kontostandes mit einem bergebenen Betrag die Methode setzeKontostand()

public void sperre() { istGesperrt=true; } public void entsperre(){ istGesperrt=false; } public boolean istGesperrt (){ return (istGesperrt); }
...

Testen der Klasse "Girokonto" (siehe: Methode "main" in der Klasse "TestGirokonto" )
Erzeugen eines Girokonto-Objekts Nacheinander Einzahlen von 100 Pfennigen, Abheben von 20 Pfennigen und Einzahlen von 30 Pfennigen Anschlieend Kontostand ausgeben
95

}
96

bung: Attribute und Methoden


Lsung 2:
public class TestGirokonto { public static void main(String[] args) { Einsprung von der Kommandozeile [optional fr jede Klasse]

Zusammenfassung
Programm = Mehrere Objekte, die Nachrichten austauschen Klassen: Schablonen fr Objekte
Attribute, Methoden

// erzeuge neues Konto Girokonto konto = new Girokonto(); // fhre Transaktionen durch konto.zahle(+100); konto.zahle(+30); konto.zahle(-20); // gib Kontostand aus int aktuellerStand = konto.holeKontostand(); Bildschirm.gibAus(aktuellerStand);
} }
97

Objekte
Erzeugen

Klasse Bildschirm

Nachrichtenaustausch
Aufruf von Methoden eines Objektes (Punkt-Notation) z.B. konto.holeKontostand()

98

Kapitel 7
Java-Syntaxkonstrukte 7.1 Primitive Datentypen, Literale und Variablen 7.2 Aufruf von Objekten, einfacher Nachrichtenaustausch 7.3 Operatoren, Ausdrcke, Zuweisungen 7.4 Anweisungen

Kapitel 7.1
Primitive Datentypen, Literale und Variablen

Primitive Datentypen
Ganze Zahlen:
byte, short, int, long

Primitive Datentypen: ganze Zahlen


2er Komplement Datentypen vorzeichenbehaftet feste Gre, unabhngig von Maschinenwortgre
Typ byte Gre 8 Bit (1 Byte) 16 Bit (2 Byte) 32 Bit (4 Byte) 64 Bit (8 Byte) Wertebereich -27 ... 0 ... (27-1) -215 ... 0 ... (215-1) -231 ... 0 ... (231-1) -263 ... 0 ... (263-1)

Fliekommazahlen:
float, double

Andere Typen:
char, boolean

short int

Keine primitiven Datentypen:


String, Arrays (auch von einfachen Typen), Klassen allgemein

long

Vergleich C/C++: (short: 16 Bit, long: 32 Bit int: Maschinenwortlnge)


101 102

2er Komplement (Hier 8 Bit)


Bit Nummer 7 6 5 4 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 Dezimalwert 2 0 0 0 0 1 1 0 0 1 1 1 0 0 1 1 0 1 0 0 1 1 0 0 1 0 1 0 1 0 1 0 1 0 1 2 3 4 127 -128 -127 -2 -1
103

Primitive Datentypen: Fliekommazahlen


Fliekommazahlen nach IEEE 745 Mantisse und Exponent definiert Wert Unendlich ist ein definierter Wert (POSITIVE_INFINITY und NEGATIVE_INFINITY) NaN (Not a number) ist ein definierter Wert
Typ float Gre 32 Bit (4 Byte) Wertebereich +/- 3.4*1038 +/- 1.8*10308 Genauigkeit ca. 7 Dezimalst. ca. 15.5 Dezimalst.

Vorzeichenbit

Hherwertige Bits stehen links Hchstwertiges Bit ist Vorzeichenbit

double 64 Bit (8 Byte)

104

IEEE 745 Standard


Fliekommazahlen nach IEEE 745 setzen sich zusammen aus: Sign-Bit S (1 Bit) Exponent E (8 Bit fr float und 11 Bit fr double) Mantisse M (23 Bit fr float und 52 Bit fr double) Sind in E alle Bits gefllt, ist dies ein reservierter Zustand um Unendlich und NaN darstellen zu knnen

Primitive Datentypen: boolean


boolean kennt nur zwei Werte, true und false

Smtliche boolsche Logik in Java wird mit dem Datentyp boolean realisiert. Mibrauch von Integertypen fr boolsche Ausdrcke, wie in C und C++ blich, ist in Java nicht vorgesehen. boolean bentigt 1 Byte (=8 Bit) Speicher. Dies liegt nicht an der Java-Sprachsyntax, sondern am Mapping auf die Virtual Machine, die keine 1-Bit-Datentypen kennt.

105

106

Primitive Datentypen: Zeichen

char ist ein 16-Bit-Zeichen nach dem Unicode-Standard

Klasse String
Zeichenketten werden durch Objekte der Klasse String dargestellt allgemeine Objekte und Klassen werden spter grndlicher untersucht String ist jedoch besondere Klasse, da Literale (konstante Zeichenketten) und Operatoren (+ zur Konkatenation) definiert sind Anders als in C/C++ sind Strings keine Zeiger auf char bzw. Array von char, in Java gibt es keine Zeiger und Arrays sind gesonderte Konstruktionen, die nichts mit der Klasse String zu tun haben
108

Untere 7 Bit (128 Zeichen) von Unicode sind ASCII-kompatibel (bzgl. ASCII nach ANSI X3.4) Sonstige Bits werden bentigt um internationale Zeichenstze abbilden zu knnen. Verantwortlich ist das Unicode Consortium (http://www.unicode.org)

107

Primitive Datentypen in Java


Anwendungsbereich Java-Datentyp Beispiel

Literale
Literale sind konstante Zahlen, Zeichen bzw. Zeichenketten, die zur Initialisierung von Datentypen verwendet werden Jedes Literal hat einen eindeutigen Typ, bei Zuweisungen mu auf Typkonsistenz geachtet werden. Literale existieren fr die einfachen Datentypen int, long, float, double, char und boolean sowie fr die Klasse String.

Logik Buchstaben Ganze Zahlen

boolean char byte short int long


( 8 Bit) (16 Bit) (32 Bit) (64 Bit)

true und false z.B. a,b,c ... z.B. -13, -1, 0,1

Fliekomma

float (32 Bit) double (64 Bit)

z.B. z.B.

-3.3e-22f, 3.4E32
109 110

Literale: Wahrheitswerte
Fr den primitiven Datentyp boolean gibt es die Literale true und false.

Literale: ganze Zahlen


Ganze Zahlen lassen sich einfach durch den Dezimalwert darstellen (z.B. 0, 20, 4332, etc.) Ein Vorzeichen kann der Zahl vorangestellt werden (z. B. -323, +4238) Durch vorangestelltes "0x" lassen sich Zahlen durch ihre Hexadezimalwerte definieren. Die Buchstaben A bis F knnen hier sowohl klein, als auch gro geschrieben werden (z. B. 0x3AF, 0xfff178) Durch eine vorangestelle Null "0" werden Zahlen im Oktalsystem definiert (z. B. 04123, 01114)

111

112

Literale: ganze Zahlen


Standardmig sind Ganzzahlkonstanten vom Typ int, long-Konstanten werden durch ein Anfgen des Buchstabens L bzw. l erzeugt (z. B. 0L, 100000000000L) Achtung: l ist leicht mit 1 zu verwechseln, daher sollte L benutzt werden Fr die Datentypen byte und short existieren keine eigenen Literale, es drfen int-Literale verwendet werden, sofern der Wert klein genug ist

Literale: Fliekommazahlen
Fliekommazahlen bestehen aus einer Mantisse und einem optionalen Exponenten (zur Basis 10). Der Exponent wird durch ein "E" bzw. "e" von der Mantisse getrennt. (10E3 entspricht z. B. dem Wert von 1000) Sowohl Mantisse als auch Exponent knnen vorzeichenbehaftet sein (z. B. -10E8, +3e-4) Die Mantisse darf auch als Dezimalbruchdarstellung geschrieben werden (z. B. -5.334E+27)

113

114

Literale: Fliekommazahlen
float-Typen lassen sich durch ein angefgtes f bzw. F definieren. (z. B. 7f, 3.8F) double-Typen lassen sich durch ein angefgtes d bzw. D definieren. (z. B. 121D, 1.4E7d)

Literale: Zeichen
Zeichen (char-Literale) werden durch einfache Anfhrungsstriche definiert. (z. B. 'a', '#', '=') Fr Sonderzeichen gibt es Escape-Sequenzen, die durch einen Backslash "\" eingeleitet werden. (z. B. '\n') Hierbei bedeutet: '\b' : backspace BS (Zeichen zurck) (ASCII: 8) '\t' : horizontal tab HT (horizontaler Tabulator) (ASCII: 9) '\n' : line feed LF (Zeilenvorschub) (ASCII: 10) '\f' : form feed FF (Seitenvorschub) (ASCII: 12) '\r' : carriage return CR (Wagenrcklauf) (ASCII: 13) '\' : double quote (doppeltes Anfhrungszeichen) '\'' : single quote (einfaches Anfhrungszeichen) '\\' : backslash (Rckwrts-Schrgstrich)
116

Fliekommazahlen lassen sich als solche von ganzen Zahlen unterscheiden, wenn eine der folgenden Eigenschaften erfllt ist: a) Es existiert ein Exponent (z.B. 1E3) b) Die Mantisse enthlt den Dezimalpunkt (z. B. 3.0) c) f, F, d oder D beendet das Literal Ist ein Fliekommaliteral nicht durch f bzw. F spezifiziert, hat es den Typ double
115

Literale: Zeichen
In einer Escape-Sequenz kann auch direkt der ASCII-Wert als Oktalzahl angegeben werden (z. B. '\17', oder '\3') Durch '\uxxxx' wird der Wert als Unicode-Sequenz angegeben, wobei fr jedes x eine Hexadezimalziffer angegeben werden mu. (z. B. '\0022' entspricht '\"' ) Achtung: die Unicode-Escape-Sequenzen werden in einer sehr frhen Phase des Compilers ausgewertet. Ein Zeilenvorschub als Unicode-Escape-Sequenz wird daher genauso behandelt wie eine neue Zeile im Editor.

String-Literale
Strings sind Verkettungen von Zeichen. String-Literale werden durch doppelte Anfhrungszeichen gekennzeichnet Alle Zeichen lassen sich analog den char-Literalen konstruieren. Beispiele fr String-Literale: "Begrenzung durch Anfhrungszeichen" "Das ist ein Text\nmit Zeilenvorschub"

117

118

Variablen
Variablen dienen dazu, Werte von speziellen Datentypen zu speichern und zu verarbeiten, die gespeicherten Werte knnen whrend der Ausfhrung eines Programms gendert werden; sie sind halt variabel. Die Werte, die eine Variable annehmen kann, sind durch ihren Typ festgelegt. Als erster Schritt mu eine Variable dem Compiler bekannt gemacht werden, diesen Vorgang nennt man Deklaration Dann mu ein Anfangswert (initialer Wert) zugewiesen, diesen Vorgang nennt man Initialisierung Verkrzend knnen beide Aktionen auch in einer Zeile erledigt werden.
119

Variablen
Ohne Deklaration kann keine Variable initialisiert werden Ohne Initialisierung kann keine Variable weiterverarbeitet werden (z. B. in Ausdrcken)

120

Variablen
Speicherung von Werten
Variablenname und Datentyp bei Initialisierungen mssen beide Seiten zuweisungskompatibel sein

Variablennamen
Variablennamen (sowie alle Bezeichner in Java) sind casesensitive, also man unterscheidet zwischen Gro- und Kleinschreibung Variablennamen beginnen stets mit Buchstaben (JavaLetter), dann knnen Buchstaben oder Zahlen folgen. Der Unterstrich "_" gehrt aus historischen Grnden auch zu den Buchstaben, kommt aber in der offiziellen Namenskonvention nicht vor, sollte daher nicht verwendet werden.

...

int kontostand; oder: int kontostand = 0;

Deklaration [mit Initialisierung] Datentyp Variablenname [= Wert]

... kontostand = kontostand + pfBetrag;

121

122

Deklaration
Variablen werden durch den Typ gefolgt von dem Variablennamen deklariert Mehrere Variablennamen knnen durch Kommata getrennt aufgefhrt werden, sie sind dann vom gleichen Typ Deklarationen sind Anweisungen, die mit Semikolon abgeschlossen werden Beispiel:
int anzahlPersonen; long millisekundenSeitGeburt; float greInCm, gewichtInKg; String name, wohnort;
123

Initialisierung
Initialisierungen werden mit Hilfe des Gleich-Operators realisiert, der rechte Wert wird dem linken zugewiesen. Initialisierungen sind Ausdrcke, die mit einem Semikolon abgeschlossen werden Bei Initialisierungen mssen beide Seiten den gleichen Typ haben Beispiel:
anzahlPersonen = 20; milliSekundenSeitGeburt = 568000000000L; greInCm = 185F; name = "Hans Mustermann";
124

Type Casting
Datentypen byte und short haben keine eigenen Literale Es mu das Literal von int genommen werden und der Wert nach byte bzw. short gewandelt werden (casting) Dies geschieht durch vorangestellte runde Klammern (CastOperator) Beispiel:
byte alterInJahren; alterInJahren = (byte)18;

Deklaration / Initialisierung in einer Zeile


Deklarationen und Initialisierungen knnen in einer Zeile erfolgen Auch hier lassen sich mehrere Deklarationen vom gleichen Typ durch Kommata voneinander trennen Beispiel:
float greInCm = 185, gewichtInKg = 79; String name="Hans Mustermann";

125

126

Zusammenfassung
primitive Datentypen
boolean, char, byte, short, int, long, float, double

Literale
Wahrheitswerte, ganze Zahlen, Fliekommazahlen, Zeichen, String-Literale

Kapitel 7.2
Aufruf von Objekten, einfacher Nachrichtenaustausch

Variablen
Namen Deklaration Initialisierung

127

Aufruf von Objekten


Konstruktoren: Aktivitten bei Objekterzeugung Referenzen als Verweise auf Objekte Garbage Collection bergabe von Parametern an Methoden Klassenattribute / Klassenmethoden Namensraum
berladen von Methoden berdecken von Attributen

Konstruktor
Methode, die automatisch bei Erzeugung eines Objektes aufgerufen wird Wird in der Regel benutzt, um Attribute zu initialisieren Dadurch charakterisiert, da der Methodenname mit dem Klassennamen bereinstimmt Konstruktoren besitzen keinen Rckgabewert (auch nicht void) berladen von Konstruktoren ist mglich

Vertiefung OO-Programm = Mehrere Objekte + Nachrichtenaustausch


Aufgaben verteilen (Spezialisten)

129

130

Konstruktoren

Aufruf von Objekten

Konstruktor
Argumente der Konstruktormethode werden bei Objekterzeugung durch new Klassenname(Argument1, Argument2, ...) an den Konstruktor bergeben Ohne Angabe eines Konstruktors ist nur der leere Konstruktor ohne Argumente definiert Ist ein (nicht leerer) Konstruktor definiert, mu der leere Konstruktor explizit definiert werden, um noch benutzt werden zu drfen

Methoden fr das Durchfhren von Arbeiten direkt bei der ObjektErzeugung:


Methodenname = Klassenname Folge von Anweisungen, die abzuarbeiten sind kein Rckgabewert

class Girokonto { ... public Girokonto() { kontostand = 0; ... } }

131

132

Referenzen auf Objekte


Bei primitiven Datentypen enthlt eine Variable direkt den Inhalt (z. B. einen Int-Zahlenwert) Bei Objekten von Klassen symbolisiert die Variable nur eine Referenz (einen Verweis) auf das Objekt Es knnen auch mehrere Referenzen auf ein Objekt zeigen Ein Referenz kann auch leer sein, null ist das Schlsselwort fr die leere Referenz Beispiel:
Girokonto k = null;

Referenzen auf Objekte


Mit dem ==-Operator kann man zwei Referenzen auf Gleichheit testen: Beispiel:
Girokonto k1 = new Girokonto(); ... Girokonto k2 = k1; ... if (k1 == k2) System.out.println( k1 und k2 verweisen auf dasselbe Objekt");

133

134

Referenzen auf Objekte


Mit dem ==-Operator kann man ebenso abfragen, ob eine Referenz leer ist: Beispiel:
Girokonto k; ... if (k == null) System.out.println(k ist leere Referenz");

Garbage Collection
Ist die letzte Referenz auf ein Objekt verschwunden da
die Referenzen den Gltigkeitsbereich verlassen haben, oder da null-Referenzen zugeweisen wurden

wird das Objekt der Garbage Collection zugefhrt => es sind keine free- oder delete-Methoden ntig Dies funktioniert auch, falls sich Objekte gegenseitig noch zyklisch referenzieren Mit
System.gc();

wird eine Empfehlung an die Garbage Collection ausgegeben, aktiv zu werden, in der Regel ist dies aber nicht ntig
135 136

Klassenattribute und -methoden


Attribute und Methoden gehren zu Objekten (also Instanzen) einer Klasse Aber: es gibt Klassenattribute und -methoden, die nicht zu Instanzen (also Objekten) gehren, sondern zu den Klassen selbst

Klassenvariablen
Attribute, die fr jedes Objekt neue Instanzen bilden, heien Instanzvariablen (Standardfall) Werden Attribute mit static gekennzeichnet, handelt es sich um Klassenvariablen, die fr die gesamte Klasse nur eine Instanz besitzen Klassenvariablen existieren auch ohne die Existenz eines Objektes. Auf sie kann durch Klassenname.Attributname zugegriffen werden.
137 138

Klassenmethoden
Methoden, die ausschlielich auf Klassenvariablen zurckgreifen, drfen mit static gekennzeichnet werden, sie heien Klassenmethoden. Klassenmethoden drfen auch nur Klassenmethoden benutzen Klassenmethoden knnen auch ohne Existenz eines Objektes mit Klassenname.Methodenname(...) aufgerufen werden. Die main()-Methode ist eine Klassenmethode, da zu Beginn noch keine Objekte erzeugt wurden
}
139

Beispiel
class Demo { int a; static int b; public static void main (String[] args) { a = 1; // nicht erlaubt b = 1; // erlaubt test(); // nicht erlaubt new Demo().test(); // erlaubt test2(); // erlaubt new Demo().test2();// erlaubt } void test() { a = 2; b = 2; } // erlaubt // erlaubt ... Demo d = new Demo(); d.a = 1; // erlaubt d.b = 1; // erlaubt Demo.a = 1; // nicht erlaubt Demo.b = 1; // erlaubt Demo.test(); // nicht erlaubt Demo.test2(); // erlaubt ...

static void test2() { b = 3; }

140

berladen von Methoden

Aufruf von Objekten

berladen von Methoden


Unterschiedliche Methoden mssen sich im Methodennamen oder in der bergabeparameterliste (oder in beidem) unterscheiden Hat eine Klasse mehrere Methoden mit identischem Namen nennt man diese Methode berladen In unterschiedlichen Klassen drfen auch Methoden mit identischem Namen und identischen bergabeparameterlisten deklariert werden

Wunsch fr Methoden/Attribute: Gleiche Namen fr gleiche Zwecke


z.B. Girokonto erzeugen ohne/mit einem initialem Kontostand

Benutzt werden sollen Methoden mit gleichen Namen Problem: Wie diese Methoden auseinanderhalten? Idee: unterscheide anhand Parameter-Typen: Methoden gleichen Namens mssen sich also im Typ von mindestens einem Parameter oder in der Anzahl der Parameter unterscheiden zahle (int betrag) zahle (int betrag, String verwendungszweck)

141

142

berdecken von Attributen


Aufruf von Objekten

Zugriff auf berdeckte Attribute


Variablendeklarationen in Klassenmethoden berdecken die Attribute der Klasse Die Attribute sind nur berdeckt, nicht berschrieben Auf Attribute der Klasse kann dann ber das Schlsselwort this zugegriffen werden this ist eine Referenz auf das zur Methode zugehrende Objekt

Verwenden von Variablen mit bereits benutzten Namen Zugreifen auf berdeckte Attribute ber this

public class Girokonto { private int kontostand; ...

// in Pfennigen gerechnet

public void setzeKontostand(int kontostand) { this.kontostand = kontostand; } ... }

143

144

bung: berladen von Konstruktoren, Methoden


Lernziele:
Erweitern einer Klasse um Attribute und Methoden bersicht behalten durch sinnvolles, sparsames Vergeben von Methodennamen (Namen mehrfach in einer Klasse vergeben)

bung: berladen
Lsungsmuster:

Aufruf von Objekten

Konstruktor-Methode -> Name identisch mit Klassenname berdecken des Namens kontostand (als Attributname und Variablenname) public class Girokonto {
...

Aufgabe:
Implementieren Sie eine zweite Konstruktor-Methode fr die Klasse Girokonto. Sie soll es ermglichen, da schon bei der Erzeugung eines Girokonto-Exemplars ein Wert fr den initialen Kontostand bergeben werden kann. Welchen Namen mu diese Methode tragen? Der bergebene Parameter soll kontostand heien. Es gibt in der Klasse "Girokonto" bereits ein Attribut mit diesem Namen. Stellt dies ein Problem dar? }

public Girokonto(int kontostand) { this.kontostand = kontostand; }


...

145

146

Zusammenspiel zwischen Objekten

Aufruf von Objekten

bung: Zusammenspiel von Objekten


Motivation: Zusammenspiel mehrerer Objekte, berladen von Namen Weg von Anforderungstext zu einer neuen Klasse ndern einer bestehenden Klasse

Aufruf von Objekten

In einem OO-System kooperieren Objekte, um gemeinsam eine Aufgabe zu lsen Jede Klasse kann etwas besonders gut (Spezialist)
z.B. Klasse "Girokonto" fr Umgang mit Girokonten

Aufgabe: Entwerfen und implementieren Sie eine neue Klasse Waehrungsrechner fr das Umrechnen von EuroCent in Pfennige (100 EuroCent 200 Pfennige)
berlegen Sie, ob diese Klasse Attribute besitzen mu? Welche knnte sie besitzen? Ergnzen Sie eine Methode "int wandeleInPfennig (int eurocent)" und eine Methode "int wandeleInEuroCent (int pfennige).

Beim Erstellen eines OO-Systems mssen Spezialisten ausgemacht werden


z.B. Erweiterung um Whrungsrechnen

Die Klasse "Girokonto" soll angepat werden:


Einem Girokonto-Objekt soll beim Erzeugen stets ein "individueller" Whrungsrechner bergeben werden knnen, der fr Konvertierungen benutzt wird. Verstecken Sie nach auen, da der Kontostand intern stets in EuroCent gespeichert wird und jede andere Whrung konvertiert wird (Information-Hiding).

147

148

bung: Zusammenspiel von Objekten


Lsung:
public class Waehrungsrechner { private int euroFaktor; public Waehrungsrechner(){ euroFaktor = 2; } public int wandeleInEuroCent (int pfennige){ int euroCent = pfennige / euroFaktor; return (euroCent); } public int wandeleInPfennig (int euroCent){ int pfennige = euroCent * euroFaktor; return (pfennige); } }

Aufruf von Objekten

bung: nderungen in Girokonto


public class Girokonto { private int kontostand = 0; private Waehrungsrechner wr; public Girokonto(Waehrungsrechner wr) { this.wr = wr; }

Aufruf von Objekten

public Girokonto(Waehrungsrechner wr, int kontostand){ this.wr = wr; // 1. Umrechnen des Betrags in EuroCent int euroCent = wr.wandeleInEuroCent(kontostand); // 2. Konstand aktualisieren this.kontostand = euroCent; }
149 150

bung: nderungen in Girokonto


public void zahle (int pfennige){ // 1. Umrechnen des zahlbetrags in EuroCent int euroCent = wr.wandeleInEuroCent(pfennige); // 2. Konto aktualisieren kontostand = kontostand + euroCent; }

Aufruf von Objekten

Zusammenfassung
Konstruktoren Referenzen Garbage Collection bergabe von Parametern an Methoden Klassenattribute / Klassenmethoden Namensraum
berladen von Methoden berdecken von Attributen

Aufruf von Objekten

public int holeKontostand(){ // 1. Umrechnen des aktuellen Kontostandes in Pfennige int pfennige = wr.wandeleInPfennig(kontostand);

// 2. Kontostand in Pfennigen zurckgeben return (pfennige); }

Vertiefung OO-Programm=Mehrere Objekte + Nachrichtenaustausch


Aufgaben verteilen (Spezialisten) Klasse Waehrungsrechner

151

152

Operatoren, Ausdrcke und Zuweisungen


Ausdrcke sind mehrere durch Operatoren und Klammern verknpfte Variablen oder Literale

Kapitel 7.3
Operatoren, Ausdrcke, Zuweisungen

Beispiel: 5*a + 7*(3 - b) ist ein (in diesem Fall arithmetischer) Ausdruck

Ausdrcke haben Ergebnisse eines bestimmten Typs, dieses Ergebnis kann einer Variablen zugewiesen werden.
Beispiel: c = 5*a + 7*(3-b);
154

Arithmetische Operatoren

Programmkonstrukte

Arithmetische Operatoren
Operator + + * / % ++ ++ --Bezeichnung Positives Vorzeichen Negatives Vorzeichen Summe Differenz Produkt Quotient Restwert Prinkrement Postinkrement Prdekrement Postdekrement

Programmkonstrukte

Arithmetische Operatoren: Bildung arithmetischer Ausdrcke Arithmetische Operatoren in Java:


Addition (+) und Subtraktion (-) Multiplikation (*) und Division (/) und Restbildung (modulo) (%)
Bedeutung +a ist synonym mit a -a kehrt das Vorzeichen um a + b ergibt die Summe von a und b a b ergibt die Differenz von a und b a * b ergibt das Produkt aus a und b a / b ergibt den Quotienten von a und b a % b ergibt den Restwert der Division von a durch b ++a ergibt a+1 und erhht a um 1 a++ ergibt a und erhht a um 1 --a ergibt a1 und verringert a um 1 a-- ergibt a und verringert a um 1

Zustzlich:
einstellige Operatoren Inkrement- und Dekrement-Operatoren mit Nebeneffekten

In Java lt sich dieser Operator sowohl auf ganze Zahlen als auch auf Fliekommazahlen anwenden!!

155

156

Postfix- und Prfix Increment und Decrement


Inkrement- und Dekrementoperatoren erhhen, bzw. erniedrigen eine Variable um 1, der Inhalt der Variable wird zurckgegeben ++ ist der Inkrement- und -- der Dekrementoperator Steht der Operator vor der Variablen (Prfix), so wird die Variable zuerst erhht (bzw. erniedrigt) und dann das Ergebnis zurckgegeben Steht der Operator hinter der Variablen (Postfix), so wird zuerst das Ergebnis der Variablen zurckgegeben, bevor sie erhht (bzw. erniedrigt) wird

Arithmetische Operatoren
Prinkrement
int a = 5; int b = ++a; Ergebnis: a = 6 b = 6 gleichbedeutend mit

Programmkonstrukte

a = a + 1; b = a;

Postinkrement
int a = 5; int b = a++; Ergebnis: a = 6 b = 5
158

gleichbedeutend mit

b = a; a = a + 1;

157

Arithmetische Operatoren (+, -, *, /, %)


Arithmetische Operatoren sind Infix-Operatoren Es gibt Addition (+), Subtraktion (-), Multiplikation (*), Division (/) und Modulo-Division (%) Modulo-Division bedeutet Divisionsrest, also 11 / 3 = 3, Rest 2, damit ist 11 % 3 gleich 2 Arithmetische Operatoren lassen sich (auch in gemischter Form) auf Variablen und Ausdrcke der Typen char, byte, int, long, float und double anwenden Divisionen durch Null sind nur fr die Typen float und double direkt erlaubt, bei char, byte, int und long wird eine Exception geworfen (spter ausfhrlicher)

Ergebnistypen bei arithmetischen Operatoren


+ - * / % char byte short int long float char int int int int long float byte int int int int long float short int int int int long float int int int int int long float long long long long long long float float double float double float double float double float double float double float double

double double double double double double double double


159 160

Ergebnistypen bei arithmetischen Operatoren


Beispiel:
short a,b,c; int d; a=7; b=8; c = a + b; d = a + b; // Deklaration // Initialisierung // Zuweisung unzulssig // Zuweisung zulssig

Implizite Typwandlungen
Bei einer Zuweisung mu der Ergebnistyp des Ausdrucks mit dem der Variablen bereinstimmen, es sei denn, implizite Typwandlungen sind erlaubt Implizite Typwandlungen sind in der Regel in Richtung grerer Typen erlaubt:
byte short int char long float double
Hinweis: char nach short wre prinzipiell verlustfrei mglich, ist aber dennoch unzulssig!

Fehlermeldung zur Compilezeit:


Incompatible type for =. Explicit cast needed to convert int to short. c = a + b; ^
161

Achtung: Wandlung von long nach float eventuell verlustbehaftet


162

Implizite Typwandlungen

Explizite Typwandlungen (Cast)


Explizite Typwandlungen sind durch Cast "(typ)" mglich.

Beispiel:
double a; // double b=10.0; int c=10; a = c; // // c = b; // Deklarationen und Initialisierungen

Beispiel:
double b=10.0; int c; c = (int)b;

// Zuweisung erlaubt, da Typ gewandelt

Zuweisung erlaubt, da Typwandlung implizit mglich Zuweisung nicht erlaubt

Typwandlungen sind in der Regel verlustbehaftet Bei Verlusten weder Fehlermeldungen noch Warnungen zur Laufzeit

163

164

Explizite Typwandlungen (Cast)


Beispiel: Typwandlung von short nach byte (hier ohne Verlust) Beispiel:

Explizite Typwandlungen (Cast)


Typwandlung von short nach byte (hier mit Verlust) 0000001000000010 (16 Bit, Wert entspricht 514) ... 00000010 ( 8 Bit, Wert entspricht 2) Programm:
short a = 514; byte b = (byte)a; // Typwandlung von short nach byte System.out.println(b);

0000000000110001 (16 Bit, Wert entspricht 49) ... 00110001 ( 8 Bit, Wert entspricht 49) 1111111111110001 (16 Bit, Wert entspricht -15) ... 11110001 ( 8 Bit, Wert entspricht -15)

Programmausgabe:
2
165 166

Vergleichsoperatoren
Vergleichen von Ausdrcken Ergebnistyp stets boolean In Java:
Gleichheitstest (==), Ungleichheitstest (!=) Grer (>), Kleiner (<) Grer gleich (>=) und Kleiner gleich (<=)

Programmkonstrukte

Vergleichsoperatoren

Programmkonstrukte

Achtung: Gleichheitstest (==) darf nicht mit Zuweisung (=) verwechselt werden Vergleich nicht fr String geeignet
Operator Bezeichnung == Gleich Bedeutung a==b ergibt true, wenn a gleich b ist. Im Falle von Referenztypen ist der Rckgabewert true, wenn beide Werte auf dasselbe Objekt zeigen. a!=b ergibt true, wenn a ungleich b ist. Im Falle von Referenztypen ist der Rckgabewert true, wenn beide Werte auf unterschiedliche Objekte zeigen. a > b ergibt true, wenn a grer b ist a < b ergibt true, wenn a kleiner b ist a >= b ergibt true, wenn a grer oder gleich b ist a <= b ergibt true, wenn a kleiner oder gleich b ist

!=

Ungleich

> < >= <=

Grer Kleiner Grer gleich Kleiner gleich

167

168

Vergleichsoperatoren
Veranschaulichung des Operators ==
Beispiel: int a = 3; int b = 4; int c = 7;

Programmkonstrukte

Zuweisungsoperatoren
Setzen des Wertes einer Variablen

Programmkonstrukte

= ist der Operator fr die Standardzuweisung

a + b == c ergibt true

Es gibt viele Zuweisungen mit Nebeneffekten: +=, -=, *=, /=, %=, ^=, &=, |=, <<=, >>= und >>>
a += b bedeutet a = a + b; a -= b bedeutet a = a - b; a *= b bedeutet a = a * b;
169 170

Zuweisungsoperatoren
Operator Bezeichnung = Einfache Zuweisung
+= -= *= /= %= &= |= ^=

Programmkonstrukte

Zuweisungsoperatoren
Veranschaulichung der Additionszuweisung
Beispiel: int a = 3, b = 5; a += b; ergibt: a = 8

Programmkonstrukte

Bedeutung a = b weist a den Wert von b zu und liefert b als Rckgabewert a += b weist a den Wert von a + b zu und liefert Additionszuweisung a + b als Rckgabewert Subtraktionszuweisung a -= b weist a den Wert von a b zu und liefert a b als Rckgabewert Multiplikationszuweisung a *= b weist a den Wert von a * b zu und liefert a * b als Rckgabewert a /= b weist a den Wert von a / b zu und liefert Divisionszuweisung a / b als Rckgabewert a %= b weist a den Wert von a % b zu und liefert Modulozuweisung a % b als Rckgabewert a &= b weist a den Wert von a & b zu und liefert UND-Zuweisung a & b als Rckgabewert a |= b weist a den Wert von a | b zu und liefert a ODER-Zuweisung | b als Rckgabewert a ^= b weist a den Wert von a ^ b zu und liefert EXKLUSIV-ODER-Zuweisung a ^ b als Rckgabewert
171

gleichbedeutend mit a = a + b;

172

Logische Operatoren
Vergleichen boolescher Werte In Java:
mit Short-Circuit-Evaluation (SCE)
UND (&&) ODER (||)

Programmkonstrukte

Logische Operatoren
Operator Bezeichnung ! Logisches NICHT
&& UND mit SCE

Programmkonstrukte

& ||

UND ohne SCE ODER mit SCE

ohne Short-Circuit-Evalutation (Kurzschlu-Auswertung)


UND (&) ODER (|)

ODER ohne SCE

Zustzlich:
logisches NICHT (!) EXKLUSIV-ODER (^)
173

EXKLUSIV-ODER

Bedeutung !a ergibt false, wenn a wahr ist und true, wenn a false ist a && b ergibt true, wenn sowohl a als auch b wahr sind. Ist a bereits falsch, so wird false zurckgegeben und b nicht mehr ausgewertet. a & b ergibt true, wenn sowohl a als auch b wahr sind. Beide Teilausdrcke werden ausgewertet. a || b ergibt true, wenn mindestens einer der beiden Ausdrcke a oder b wahr ist. Ist bereits a wahr, so wird true zurckgegeben und b nicht mehr ausgewertet. a | b ergibt true, wenn mindestens einer der beiden Ausdrcke a oder b wahr ist. Beide Teilausdrcke werden ausgewertet. a ^ b ergibt true, wenn beide Ausdrcke einen unterschiedlichen Wahrheitswert haben.
174

Logische Operatoren

Programmkonstrukte

Bitweise AND, OR, XOR


Vergleich der einzelnen Bits zweier ganzer Zahlen Fr alle ganzzahligen primitiven Datentypen Es gibt "bitweise und" bzw. AND (&), "bitweise inklusiv oder" bzw. OR (|) und "bitweise exclusiv oder" bzw. XOR (^)

Veranschaulichung der Operatoren || und &&


Beispiel: int a = 3, b = 5, c = 5;

(a == b) || (b == c) ergibt true (a == b) && (b == c) ergibt false

&&

false

true

||

false true

false false false true false true

false false true true true true


175

Fr jede Position der Bitdarstellung der beiden Eingabezahlen wird ein Bit berechnet und in der Bitdarstellung der Ergebniszahl an derselben Position abgelegt (siehe Beispiel)

176

Bitweise AND, OR, XOR


Beispiel:
00000011 00001001 ======== AND: 00000001 OR: 00001011 XOR: 00001010 entspr. 3 entspr. 9 entspr. 1 entspr. 11 entspr. 10

Verschiebeoperatoren
Durch Verschiebeoperatoren knnen Bitdarstellungen von Ganzzahldatentypen nach links, bzw. rechts verschoben werden. Links vom Operator steht der zu verschiebende Wert und rechts die Anzahl der Bits, um die verschoben werden soll "<<" ist der Links-Shift-Operator und ">>" und ">>>" sind Rechts-Shift-Operatoren Bei "<<" und ">>>" wird jeweils die Null nachgeschoben, bei ">>" das Vorzeichenbit a << n entspricht einer Multiplikation mit 2n und a >>> n entspricht einer Division durch 2n. => Geschwindigkeitsvorteile
178

Programm:
byte a=3, b=9;

System.out.println(a & b); System.out.println(a | b); System.out.println(a ^ b);

& 0 1

0 0 0

1 0 1

| 0 1

0 0 1

1 1 1

^ 0 1

0 0 1

1 1 0
177

String-Konkatenation
Der +-Operator kann verwendet werden, um zwei Objekte der Klasse String zu verknpfen Ist nur einer der Operanden ein Objekt der Klasse String, und ein anderer ein primitiver Datentyp, wird letzterer nach String gewandelt Beispiel:
int alter = 27; System.out.println("Alter : " + alter + " Jahre");

Unre Operatoren
Unre Operatoren werden immer vor einen Ausdruck gestellt Es gibt Plus- und Minusvorzeichen (+) und (-), sowie logische (!) und bitweise (~) Verneinung. Vorzeichen und bitweise Verneinung werden fr Ganzzahldatentypen verwendet, die logische Verneinung fr den Datentyp boolean

Ausgabe:
Alter: 27 Jahre
179 180

Bedingte Ausdrcke
Beispiel 1: Mit bedingten Ausdrcken lassen sich Alternativen in Ausdrcken beschreiben Sie werden in folgender Form benutzt: Ausdruck1 ? Ausdruck2 : Ausdruck3 Ausdruck1 mu einen Wert vom Typ boolean haben Ausdruck2 und Ausdruck3 sind zwei Ausdrcke mit Wert vom gleichen Typ Ist Ausdruck1 gleich true, so wird Ausdruck2 ausgewertet, sonst Ausdruck3

Bedingte Ausdrcke
int alter = 17; System.out.println(alter >= 18 ? "volljhrig" : "nicht volljhrig");

Ausgabe:
nicht volljhrig

Beispiel 2:
int alter = 18; double Mitgliedsbeitrag = alter >= 18 ? 200 : 100; System.out.println("Mitgliedsbeitr.:" + Mitgliedsbeitrag);

Ausgabe:
Mitgliedsbeitr.:200
181 182

Operator-Prioritten
Die Standard-Richtung fr die Auswertung von Operatoren ist von links nach rechts Zuweisungsoperatoren werden von rechts nach links ausgewertet Operatoren unterliegen einer Priorittenhierarchie, analog der Punkt- vor Strich-Regel, also der Ausdruck 5 + 3 * 3 + 1 reprsentiert den Wert 15, da die Multiplikation hhere Prioritt hat. Operatoren mit hchster Prioritt werden zuerst ausgewertet Durch Klammerung mit runden Klammern ( und ) kann die vorgegebene Hierarchie berwunden werden
Kategorie 0 1 2 3 4 5 6
183

Operator-Prioritten
Operatoren = += -= *= /= %= ^= &= |= <<= >>= >>>= ? : || && | ^ &
184

Zuweisung Bedingungsoperator logisches Oder logisches Und bitweise ink. Oder bitweise exkl. Oder bitweise Und

Niedrigste Prioritt

Operator-Prioritten
Kategorie 7 8 9 Vergleichsop. Vergleichsop. Verschiebeop. Operatoren == < << + * / % (type)expr > != <= >> >= >>>
Hchste Prioritt

Operator-Prioritten
Kategorie 13 unre Operatoren Operatoren ++expr --expr -expr ~ ! [] . +expr

instanceof

14 Postfix-Operatoren

expr++

expr--

10 additive Operatoren 11 multiplikative Op. 12 Erzeugungs- oder Typumwandlungsop.

new

185

186

Operator-Prioritten: Beispiele
int a, b=2; a = b << 1 + 2;

Operator-Prioritten: Beispiele
int a, b=2; a = (b << 1) + 2;

Addition hat hhere Prioritt als Verschiebeoperatoren Es wird daher zunchst 1+2 ausgewertet und der Wert von b (2) dann um das Ergebnis (3) nach links verschoben, man erhlt also 16. Dieser Wert wird dann der Variablen a zugewiesen, denn der Zuweisungsoperator hat die niedrigste Prioritt

Durch die Klammerung wird die Verschiebung zuerst durchgefhrt b um eins nach links verschoben ergibt 4. Dann wird 2 aufaddiert und das Ergebnis (6) der Variablen a zugewiesen

187

188

Operator-Prioritten: Beispiele
int a = 5, b; a += b = 8;

Zusammenfassung
Operatoren
arithmetische Operatoren Vergleichsoperatoren Zuweisungsoperatoren logische Operatoren bitweise Operatoren Verschiebeoperatoren unre Operatoren bedingte Ausdrcke

Programmkonstrukte

Auswertreihenfolge von links rechts nach links Zunchst wird b die Zahl 8 zugewiesen, dann wird der neue Wert von b auf a aufaddiert, a erhlt also den Wert 13
(a += b) = 8;

Fehler: Auswertreihenfolge lt sich nicht verndern, denn Ausdrcke drfen nie links auf einer Zuweisung stehen


189

Prioritten Typumwandlungen (Type Casting)


implizit / explizit
190

Zur Einordnung
Programme bestehen aus Klassen. Eine der Klassen eines Programms hat eine Methode namens main. Mit der wird die Ausfhrung begonnen. Danach werden in der Regel Objekte erzeugt, die dann fr bestimmte Aufgaben zustndig sind. Die Kommunikation zwischen den Objekten erfolgt ber den Aufruf von Methoden / das Versenden von Nachrichten. Was innerhalb einer Methode passiert, wird durch Anweisungen festgelegt. Grundbausteine der Anweisungen haben wir bereits kennengelernt:
Literale und Variable Operatoren
192

Kapitel 7.4
Anweisungen

Zur Einordnung
Der Algorithmus (also die Verarbeitungsvorschrift), der durch eine Methode realisiert wird, wird durch eine Menge von Anweisungen beschrieben. Die Arten von Anweisungen, die hierfr verwendet werden, diskutieren wir im folgenden. Danach kennen wir dann alle Grundbestandteile von JavaProgrammen.

Anweisungen
Anweisungen (auer Blcken) werden durch Semikolon voneinander getrennt. Blcke sind Sequenzen von Anweisungen, in der Regel geklammert mit {}, sie werden nicht durch Semikolon voneinander getrennt.
{ konto.zahle(+100); konto.zahle(+30); konto.zahle(-20); } { Anweisung1; Anweisung2; ... }

Deklarationen bzw. Initialisierungen innerhalb von Blcken sind nur innerhalb dieser gltig.
193 194

Anweisungen
Auch die bereits bekannten
Zuweisungen Deklarationen und Initialisierungen

Sichtbarkeit in Blcken
Da Deklarationen jenseits der ueren Grenze eines Blocks nicht bekannt sind, stellt sich bei Attributen und Variablen, die in mehreren Blcken namensgleich deklariert werden, die Frage, auf welches Attribut durch einen Attributnamen Bezug genommen wird. Der Zugriff auf die falschen Attribute ist eine hufige Fehlerursache.

sind Anweisungen. Einfache" Anweisungen werden der Reihenfolge nach abgearbeitet. Blcke, Bedingungen, Schleifen und Sprnge sind Anweisungen, sie beeinflussen den Kontrollflu. Sie beschreiben grere Strukturen als Ausdrcke, jedoch nicht so groe wie Klassen.
195

196

Sichtbarkeit in Blcken
Als generelle Regel der Sichtbarkeit lt sich formulieren:
es wird zunchst im aktuellen (also inneren) Block nach dem Attribut gesucht, wird es dort nicht gefunden, wird schrittweise nach auen vorgedrungen bis ein entsprechend benanntes Attribut gefunden wird.

Variablen in Blcken
public void zahle (int betrag) { int alterKontostand=kontostand;

Programmkonstrukte

Im Block deklarierte Variablen sind nur im Block sichtbar

Besonders verwirrend kann dabei sein, da Attribute und Variable erst ab der Deklarationsanweisung bekannt sind.

{ // hier ist der alterKontostand sichtbar int neuerKontostand = kontostand + 50000; ... // ab hier ist auch neuerKontostand sichtbar Bildschirm.gibAus(neuerKontostand); } // neuerKontostand unsichtbar, alterKontostand sichtbar int neuerKontostand = 1; // ab hier dann die neue Variable neuerKontostand sichtbar kontostand=kontostand + betrag; }
198

197

Bedingtes Verzweigen (if-Anweisung)


Bedingte Verzweigungen dienen zur Auswahl aus zwei Alternativen (siehe bedingte Ausdrcke)
if ( Ausdruck )

Bedingtes Verzweigen (if-Anweisung)


Der Teil else Anweisung2 ist optional. Liefert Ausdruck false, dann wird die if-Anweisung ohne weitere Ausfhrung verlassen. Unterscheidung zu Ausdruck1 ? Ausdruck2 : Ausdruck3:
bei der bedingten Verzweigung mssen Ausdruck2 und Ausdruck3 nicht notwendigerweise ein Ergebnis des gleichen Typs liefern.

Anweisung1; else Anweisung2;

Ausdruck mu ein Wert vom Typ boolean haben Anweisung1 wird ausgefhrt, falls Ausdruck den Wert true hat, sonst wird Anweisung2 ausgefhrt. Es wird zunchst Ausdruck ausgewertet. In Abhngigkeit vom Ergebnis dann Anweisung1 oder Anweisung2.
199 200

Bedingtes Verzweigen
Die if-Anweisung
if (kontostand < 0) Bildschirm.gibAus("Konto berzogen"); else Bildschirm.gibAus("Geld vorhanden");

Programmkonstrukte

Bedingtes Verzweigen
Blcke sind Anweisungen => Mehrere Anweisungen lassen sich innerhalb der if- oder else-Anweisung gruppieren
if (landeswhrung == DM) { neuerBetrag = betrag * 1.96; System.out.println("Guthaben:" + neuerBetrag + " DM"); } else System.out.println("Guthaben:" + betrag + " Euro");

if (ausdruck) anweisungA; else anweisungB;


ausdruck: boolean

else-Zweig ist optional ausdruck ist true false

Ausfhren von anweisungA Ausfhren von anweisungB

201

202

Bedingtes Verzweigen
Bedingte Verzweigungen sind selbst auch Anweisungen => Schachtelung von if-Abfragen mglich
if (beruf == schler) System.out.println("Schlertarif"); else if (beruf == rentner) System.out.println("Rentnertarif"); else System.out.println("Normaltarif");

Bewachte Anweisungen
switch ( Ausdruck ) { case Konstante1: Anweisungsfolge1; case Konstante2: Anweisungsfolge2; ... default: Anweisungefolge_n; }

Ausdruck ist vom Typ byte, short, int oder char Konstante_i sind Konstanten vom gleichen Typ wie Ausdruck Anweisungsfolge_i sind Folgen von Anweisungen, die durch Semikolon voneinander getrennt sind.

Der zweite else-Zweig bezieht sich auf die zweite if-Abfrage


203 204

Bewachte Anweisungen
switch ( Ausdruck ) { case Konstante1: Anweisungsfolge1; case Konstante2: Anweisungsfolge2; ... default: Anweisungefolge_n; }

Bewachte Anweisungen
switch ( Ausdruck ) { case Konstante1: Anweisungsfolge1; case Konstante2: Anweisungsfolge2; ... default: Anweisungefolge_n; }

Es wird zunchst Ausdruck ausgewertet. Alle Anweisungen ab der ersten Konstante, welche gleich dem Wert des Ausdrucks ist, werden abgearbeitet.

Die Anweisungsfolge hinter default: wird auch abgearbeitet, falls keine Konstante gleich dem Wert von Ausdruck ist. Die default-Zeile ist optional. Beispiel 33

205

206

Bewachte Anweisungen
switch ( Ausdruck ) { case Konstante1: Anweisungsfolge1; case Konstante2: Anweisungsfolge2; ... default: Anweisungefolge_n; }

Bewachte Anweisungen
Die switch-Anweisung
default-Teil ist optional
int zensur = 2; switch (zensur) { case 1: Bildschirm.gibAus("sehr gut"); break; case 2: Bildschirm.gibAus("gut"); break; ...

Programmkonstrukte
switch (ausdruck) { case constant1: anweisung1; case constant2: anweisung2; ... default: anweisung; } ausdruck: byte, short, int, long, char

Kommt die Anweisung break; in einer abzuarbeitenden Anweisungsfolge vor, so wird der gesamte von switch gefolgte Block verlassen.

default: Bildschirm.gibAus("das ist keine Zensur!"); }


207 208

Schleifen
Schleifen dienen dazu, die gleiche Anweisung mehrfach durchlaufen zu knnen Diese Anweisung kann auch ein Block sein, also mehrere Anweisungen gruppieren. Es gibt Abbruch- bzw. Laufbedingungen fr Schleifen Es gibt 3 Schleifentypen: while-Schleifen, do-while-Schleifen und for-Schleifen

Schleifen
Die while-Schleife

Programmkonstrukte

Die Laufbedingung Ausdruck ist vom Typ boolean Zunchst wird Ausdruck ausgewertet. Falls Ausdruck den Wert true liefert, wird Anweisung abgearbeitet. Dies wiederholt sich solange, bis Ausdruck den Wert false liefert Test vor Ausfhrung der Anweisungsfolge
int a=0; while (a < 100) { Bildschirm.gibAus(a); a = a + 10; }; while (ausdruck) anweisung; ausdruck: boolean

Ausgabe: 0, 10, 20, ..., 90


209

(nicht mehr: 100)


210

BEISPIEL 34

Schleifen
Die do-while-Schleife
Test nach Ausfhrung der Anweisungsfolge also mindestens ein Durchlauf

Programmkonstrukte

for-Schleifen (Zhlschleifen)
for (Initialisierungsliste; Ausdruck; Anweisungsliste) Anweisung
Initialisierungsliste ist eine Liste von Ausdrcken, die durch Kommata getrennt sind. Sie wird als Initialisierung vor Eintritt in die Schleife abgearbeitet (nur einmal!). Typischerweise weden hier Zhlervariablen vereinbart. Ausdruck ist die Laufbedingung und mu daher einen Wert vom Typ boolean liefern. Ist das Ergebnis false, wird abgebrochen, ansonsten wird als nchstes mit Anweisung der Schleifenrumpf abgearbeitet

int a=0; do { Bildschirm.gibAus(a); a = a + 10; } while (a < 100);

do anweisung while (ausdruck) ausdruck: boolean

Ausgabe: 0, 10, 20, ..., 90, 100

211

212

for-Schleifen (Zhlschleifen)
for (Initialisierungsliste; Ausdruck; Anweisungsliste) Anweisung
Anweisungsliste ist eine Liste von Anweisungen, die durch Kommata getrennt sind. Sie wird immer nach Anweisung ausgefhrt Nach der Auswertung von Ausdruck wird die Schleife dann fortgesetzt, wenn Ausdruck true liefert. Alle Anweisungen knnen optional weggelassen werden

Schleifen
Die for-Schleife
int i; for (i=0; i<3; i++) System.out.println(i);

Programmkonstrukte
for (init; test; update) anweisung; test: boolean

Ausgabe 0 1 2 Endlosschleife for ( ; ; );

213

BEISPIEL 36

214

Markierte Anweisungen
Eine Anweisung lt sich durch einen Namen markieren:

Markierte Anweisungen
Markierung : Anweisung
Markierung ist nur innerhalb der markierten Anweisung (Block, Schleife o. .) sichtbar Innerhalb von Bedingungs- und Zhlschleifen kann break und continue ohne Markierung verwendet werden. Hier wird die innerste umgebene Schleife als markiert betrachtet. Sprunganweisungen sind in der Regel ein Anzeichen schlechter Strukturierung, sie sollten vermieden werden. Immerhin gibt es keine allgemeine Sprunganweisung (goto)! BEISPIEL 38
216

Markierung : Anweisung
Markierung ist ein Bezeichner Ist Anweisung aus mehreren Anweisungen zusammengesetzt, es ist also zum Beispiel ein Block oder eine Schleife, so gilt: Mit "break Markierung" wird Anweisung abgebrochen und mit dem unmittelbar auf Anweisung folgenden fortgefahren Mit "continue Markierung" wird Anweisung abgebrochen und von Beginn an neu gestartet
215

Markierte Anweisungen
Beispiel: Ausgabe: 1 / 1 1 / 2 1 / 3 ===== 2 / 1 ===== 3 / 1 3 / 2 3 / 3 ===== 4 / 1 5 / 1 5 / 2 5 / 3 =====
217

Sichtbarkeit
{ ... int a; test : for (a=0; a<100; a++) { int b; for (int c=0; c<a; c++) { System.out.println(a*c); } } int d=7; System.out.println(a*d); }

Hier ist a sichtbar Hier ist test sichtbar Hier ist b sichtbar Hier ist c sichtbar Hier ist d sichtbar

marke1: for (i=1; i<6; i++) { marke2: for (j=1; j<4; j++) { System.out.println(i + " / " + j); if (i == 2) break marke2; // quiv zu if (i == 4) // break; continue marke1; } System.out.println("====="); }

218

Zusammenfassung Anweisungen
elementare Anweisungen Blcke

Programmkonstrukte

if switch

Kapitel 8
Programmierkonventionen und Dokumentation

Schleifen
while do-while for

Markierte Anweisungen Sichtbarkeit

219

Programmierkonventionen
Warum Programmierkonventionen (Code Conventions)?
Nur wenig Software wird ausschlielich vom originalen Autor gewartet Programmierkonventionen erleichtern Lesbarkeit und Verstndlichkeit selbst geringe Verbesserungen der Wartbarkeit rechtfertigen Anstrengungen in der Entwicklung

Ausblick in die Wartung Folgende Gegenstnde der Wartung knnen unterschieden werden:
Beseitigung von Fehlern, die den Software-Einsatz behindern: echte Entwicklungsfehler in der Wartung eingefgte Fehler Sicherstellung der nicht-funktionalen Anforderungen nach Auslieferung nderungen der Umweltbedingungen (Hardware, Fremdsoftware, Organisation) Jahr 2000 / EURO gesetzliche nderungen neue Basissysteme neue Anforderungen (die Kenntnis einer Version weckt neue Anforderungen!)
222

221

Ein Ausblick in die Wartung Lehmans Law of Uncertainty and Lehmans Law of Increasing Software Entropy bedeuten, da nderungen whrend und nach der Entwicklung unvermeidlich sind. Law of Uncertainty: Software ndert sich whrend ihres ganzen Lebenszyklus. Genauere Angaben zum Gegenstand der nderungen sind nicht vorhersehbar. Law of Increasing Software Entropy: nderungen einer Software machen ihre Struktur in der Regel unverstndlicher. Die innere Struktur einer Software geht mit fortschreitender Software-Lebenszeit verloren
223

Ausblick in die Wartung Das Verhltnis von Entwicklungsaufwnden zu Wartungsaufwnden wird in der Literatur in einem Bereich zwischen 1:4 und 1:2 angegeben. Das bedeutet, da zwischen 20% und 33% der gesamten Kosten auf die Entwicklung entfallen und da zwischen 80% und 67% auf die Wartung entfallen! Deshalb: Programmierkonventionen als eine Manahme der Verbesserung der Wartbarkeit! Andere Manahmen: Dokumentierte Ergebnisse von OOA und OOD, Verzicht auch Trick-Programmierung
224

Programmierkonventionen
Wie sollen sie eingesetzt werden?
Die offizielle Konventionen sollten als Basis dienen Sie funktionieren nur, wenn sie von jedem eingehalten werden Es kann projektspezifische Erweiterungen geben

Datei-Organisation
Keine Dateien mit mehr als 2000 Zeilen Abschnitte sollten durch Leerzeilen getrennt werden Jede Datei sollte nur eine ffentliche Klasse bzw. ein ffentliches Interface besitzen ffentliche Klasse / Interface ist am Dateianfang zu finden Datei hat vorgegebene Aufteilung:
Anfangskommentare Package und Import-Statements Klassen- und Interface-Deklarationen

225

226

Ordnung innerhalb einer Datei


Reihenfolge in einer Datei: Anfangskommentare in C-Format:
/* * Klassenname * * Versionsinformation * * Copyright-Vermerk */

Ordnung innerhalb einer Datei


Klassen- und Interfacedeklarationen in vorgegebener Reihenfolge:
Klassen / Interface - Kommentar (/** ... */) class oder interface Definition Klassen / Interface - Implementierungskommentar, falls ntig (/* ... */) Klassenvariablendeklarationen (static)

Package- und Import-Statements


package java.awt; import java.awt.peer.CanvasPeer;

Instanzvariablendeklarationen Konstruktoren Methoden (geordnet, also z.B. sollten ffentliche Klassen nicht zwischen privaten stehen)

227

228

Einrckungen
Es werden 4 Zeichen eingerckt Eine Zeile ist maximal 80 Zeichen breit Regeln fr Zeilenumbrche:
Umbruch auf hchstmglicher Ebene Umbruch vor Operatoren und nach Kommata Gleiche Hierarchieebenen sollen mglichst in folgender Zeile untereinanderstehen, falls nicht mglich, ist 8 Zeichen einzurcken z.B.:

Kommentare
Block-Kommentare sollen mit fhrendem * in folgender Form geschehen:
/* * Dies ist ein Kommentar. */

Einzeilenkommentare kommen vor dem entsprechenden Programmcode mit zugehriger Einrckung. Vor dem Kommentar steht eine Leerzeile
if (Bedingung) { /* Bedingung wird ausgewertet */ ... }

var = funktion1(Ausdruck1, funktion2(Ausdruck2, Ausdruck3));

229

230

Kommentare
Zeilenendekommentare (//) am Ende der Zeile sollten gengend eingerckt sein. Sie werden nicht fr mehrzeilige Kommentare benutzt, es sei denn, Programmtext wird auskommentiert
if (personImHaus == TRUE) { return Zimmernummer; } else { return Adresse; }

Deklarationen
Es sollte mglichst nur eine Deklaration pro Zeile erfolgen
String name; String strae; // Vor- und Nachname // Strae mit Hausnummer // Mglichst vermeiden

und nicht
String name, strae;

// Raum im Haus // Privatadresse

Auf keinen Fall drfen Deklarationen unterschiedlichen Typs, oder Methoden- und Attributdeklarationen in einer Zeile stehen
long kundennummer, getKundennummer(); String name, namensliste[]; // Vermeiden // Vermeiden

231

232

Deklarationen
Deklarationen sollten immer am Anfang eines Blocks stehen Mit Variablendeklarationen sollte nicht bis zur ersten Benutzung gewartet werden Lokale Variablen sollten, sofern mglich bei Deklaration auch initialisiert werden berdeckungen von Variablen einer hheren Ebene sollten vermieden werden:
int zhler; ... void funktion() { if (Bedingung) { int zhler; } } argv++; argc++;

Anweisungen
Eine Zeile sollte nur einen Ausdruck enthalten:
// Vermeiden!

In Blcken sollten ffnende Klammern am Zeilenende stehen Struktur von if- und if-else-Anweisungen:
if (Bedingung) { Anweisungen; } if (Bedingung) { Anweisungen; } else { Anweisungen; } if (Bedingung) { Anweisungen; } else if (Bedingung) { Anweisungen; } else if (Bedingung) { Anweisungen; }

// Vermeiden!

233

234

Namenskonventionen
Klassennamen
Substantive, groe Anfangsbuchstaben, ganze Worte, innere Worte beginnen mit Grobuchstaben class Datum; class KundenListe;

Namenskonventionen
Variablen / Attribute
am Wortanfang klein geschrieben, innere Worte beginnen mit Grobuchstaben Namen sollen selbsterklrend sein Datum meinGeburtsDatum = new Datum("1.1.1904"); Temporre Variablen drfen mit einem Buchstaben benannt werden hierbei gilt: i, j, k, m und n werden fr Integerzahlen benutzt c, d und e werden fr Zeichen benutzt

Interfacenamen
Analog zu Klassennamen

Methodennamen
Verben, klein geschrieben, innere Worte beginnen mit Grobuchstaben int gibKundenListe();

Konstanten
Konstanten werden komplett gro geschrieben, Worte durch "_" voneinander getrennt int MINIMALE_BREITE = 10;
236

235

Sonstige Konventionen
Klassen und Methoden sollten so privat wie mglich deklariert werden Konstanten sollten ber Namen in Programmcode eingebaut werden (bis auf bedeutungslose, wie -1, 0, 1) Mehrfachzuweisungen sollten vermieden werden
a = b = c; // Vermeiden!

Dokumentation
Es gibt 3 Sorten von Kommentaren:
// Rest der Zeile wird auskommentiert (C++-Methode) /* * Ein gesamter Abschnitt wird kommentiert, * Achtung: Schachtelung von Kommentaren ist * nicht mglich (C-Methode) */ /** * Eine Klasse oder Methode wird kommentiert, * aus diesem Kommentar lassen sich automatisch * HTML-Dokumentationen erstellen */

Klammerungen knnen selten benutzte Operatorprioritten verdeutlichen

Automatische Dokumentation geschieht mit Hilfe des Tools "javadoc" von JDK.
237 238

javadoc - Dokumentation
/** */ - wird vor Klassen- und Interface-Deklarationen sowie vor Methoden, Konstruktoren und Attributdeklarationen bercksichtigt Kommentar wird in HTML-Dokumentation von "javadoc" aufgenommen => HTML-Tags im Kommentar sind erlaubt /** ist Kommentaranfang und */ ist Kommentarende Innerhalb des Kommentars wird ein * am Zeilenanfang ignoriert Erster Satz des Kommentars ist gesonderter Zusammenfassungssatz. (Punkt als Endmarkierung)

javadoc - Dokumentation
Durch @-Zeichen innerhalb des Kommentars werden Tags eingefgt, um automatische Querreferenzen zu erzeugen: @see-Tag erzeugt allgemeine Querreferenz
Referenz zu anderer Klasse: @see java.io.InputStream @see String Referenz zu einer Methode einer Klasse: @see String#equals Referenz zu anderer HTML-Datei: @see <a href="spec.html">Java Spec</a>

@author-Tag um Autor zu kennzeichnen


@author Albert Einstein @author Albert Einstein, Max Born, Werner Heisenberg
240

239

javadoc - Dokumentation
@version-Tag kennzeichnet Version
@version 1.01beta

javadoc-Beispiel
/* Copyright (c) 1999 by * adesso-GmbH. * Dieser Kommentar soll nicht * mit aufgenommen werden */ /** * Klasse, um Datum zu * erfassen. * @see java.util.Date * @version 0.9 */ public class Datum { private int jahr; private int monat; private int zag; } /** * Datum wird gesetzt. * Es wird deutsche Notation * erwartet. */ void setzeDatum(String arg){ ... } /** * Wochentag wird berechnet. * Datum wird in deutscher * Notation zurckgegeben. */ String Wochentag() { ... }

@param-Tag
Erklrung fr Parameter in Methoden und Konstruktorendeklarationen: @param Name Name der Person mu bergeben werden

@return-Tag
Bedeutung des Rckgabeparameters

@exception-Tag
Erklrung von Ausnahmen in Methoden und Konstruktordeklarationen: @exception IndexOutOfBoundsException Die Feldgrenze wird berschritten

@deprecated-Tag (ab JDK 1.1)


Kennzeichnung veralteter Methoden
241

242

Struktur dieses Kapitels


Ein paar rekursive Methoden

Kapitel 9
Rekursive Methoden nach Doberkat/Dimann Kapitel 3

Rekursives Sortieren am Beispiel Heapsort Ein paar berlegungen zur berfhrung rekursiver in iterative Methoden

244

Fakultts-Methode
Die Fakulttsfunktion wird fr positive ganzzahlige n folgendermaen definiert: n! =

Rekursive Fakultts-Methode
berlegung: Was passiert hier bei der Ausfhrung? Beispiel: Fakultt(4)

1, n * (n-1)!,

falls n = 1 sonst

Das lt sich unmittelbar in einen Algorithmus umsetzen.


public double Fakultt (int n) { // Methodendeklaration return (n = 1 ? 1 : n*Fakultt(n-1)); }
245

Es wird der Namensraum fr einen Methodenaufruf aufgebaut. Hierin ist der Parameter n = 4 bekannt. Beim Aufruf wird die Operation 4 * Fakultt(3) ausgewertet. Hierzu wird der Namensraum fr einen Methodenaufruf aufgebaut. Hierin ist der Parameter n = 3 bekannt. Beim Aufruf wird die Operation 3 * Fakultt(2) ausgewertet.
246

Rekursive Fakultts-Methode
Beispiel: Fakultt(4) (Fortsetzung) Es wird der Namensraum fr einen Methodenaufruf aufgebaut. Hierin ist der Parameter n = 2 bekannt. Beim Aufruf wird die Operation 2 * Fakultt(1) ausgewertet. Hierzu wird der Namensraum fr einen Methodenaufruf aufgebaut. Hierin ist der Parameter n = 1bekannt. Es wird das Ergebnis 1 zurckgeliefert. 2 * Fakultt(1) wird damit zu 2 * 1, das Ergebnis 2 wird zurckgeliefert.
247

Rekursive Fakultts-Methode
Beispiel: Fakultt(4) (Fortsetzung) 3 * Fakultt(2) wird damit zu 3 * 2, das Ergebnis 6 wird zurckgeliefert. 4 * Fakultt(3) wird damit zu 4 * 6, das Ergebnis 24 wird zurckgeliefert. Dieses Beispiel zeigt, da bei rekursiven Methode der Stapel zur Verwaltung der aktuellen Methodenaufrufe (kurz: AufrufStack) stark wachsen kann.
248

Rekursive Fakultts-Methode
n=4 n=3 24 6

Iterative Fakultts-Methode
Beispiel: Ausgabe der Fakultten von 0! bis 10!
class Fakultaetsberechnung { public static void main(String[] args) { for (int i=0; i<=20; i++) System.out.println(rechneFak(i)); } static double rechneFak(int n) { // Methodendeklaration double ergebnis = 1; for (int i=1; i<=n; i++) ergebnis *= i; return ergebnis; // Rckgabe } }
249 250

n=2

n=1

Iterative Fakultts-Methode
Bei der iterativen Version der Fakultts-Methode wird nur eine Methode aufgerufen. Die liefert als Ergebnis den Fakulttswert, ohne da weitere Methodenaufrufe abgearbeitet werden mssen.

Rekursive Fibonacci-Methode
Beispiel: Fibonacci-Zahlen, positive, ganzzahlige Eingabe
public int fib(int n) { if (n < 3) return (1); else return (fib(n-1) + fib (n-2)); }
Ein Aufruf von fib fhrt zu zwei weiteren Aufrufen, dabei wird der Parameter kontinuierlich kleiner. Wie verhlt sich hier der Aufruf-Stack?
251 252

Rekursion
Ruft eine Anweisung innerhalb einer Methode die eigene Methode auf, bezeichnet man dies als rekursiven Aufruf. Die Methode wird rekursive Methode genannt. Bei einem rekursiven Aufruf einer Methode erhalten alle lokal definierten Variablen einen neuen, unabhngigen Namensraum. Fr die ausfhrende Maschine ist bedeutungslos, ob es sich um einen rekursiven Aufruf handelt! Rekursive Implementierungen sind oft einfacher zu verstehen, als iterative Implementierungen (vgl. Fakultt, Fibonacci). Iterative sind hingegen in der Regel performanter.
253

Rekursion
Fr die Definition einer rekursiven Methode werden bentigt: Eine Beschreibung, wie sich der Wert eines greren Objekts aus den Werten fr kleinere Objekte ergibt. Eine Terminierungsbedingung: Ist diese Bedingung erfllt, so mu angegeben werden, wie sich der Wert berechnen lt, ohne noch einmal auf die rekursive Methode zuzugreifen. Jeder Aufruf einer rekursiven Methode mu im Verlauf der Auswertung direkt (also im Aufruf selbst) oder indirekt (also im Rahmen weiterer rekursiver Aufrufe) die Terminierungsbedingung erreichen.

254

Rekursive Datenstrukturen
Rekursion ist nicht nur ein wichtiges Hilfsmittel fr die Formulierung von Algorithmen, sondern auch fr die Formulierung von Datenstrukturen. Beispiele: Eine Liste ist ein Einzelelement gefolgt von einer Liste oder die leere Liste. Eine Menge ist leer oder eine einelementige Menge vereinigt mit einer Menge. Oder Bume (dazu im folgenden mehr).
255

Rekursion - Bume
Nicht-rekursive Definition von Bumen: Ein Baum B besteht aus Knoten V und Kanten E, also B = (V,E). Knoten tragen Information, sie sind ber Kanten miteinander verbunden, also E = V x V. Kanten eines Baumes sind gerichtet, sie sind also ein Paar von Knoten (v1,v2). In einer Kante e = (v1,v2) wird v1 der Vaterknoten und v2 der Sohnknoten von e genannt.

256

Rekursion - Bume
Im Unterschied zu den allgemeineren Graphen sind Bume hierarchisch, das heit, es gibt keine zyklischen Verbindungen zwischen Knotenmengen. e = (v1,v2) E : ( i , i 2 v21, ..., v2i V | v21 = v2, v2i = v1, (v21,v22), ..., (v2i,v1) E) Ein Binrbaum (auch binrer Baum) ist dann ein Baum, in dem jeder Knoten maximal zwei Sohnknoten hat, d.h. v V : | { vi V | (v,vi) E } | 2

Rekursion - Bume
Rekursive Definition von binren Bumen: Die Grundstruktur eines Baumes lt sich leicht rekursiv definieren: Ein binrer Baum ist entweder leer oder er hat die folgende Form: w

B1 B2 wobei w ein Knoten und B1, B2 binre Bume sind. Zustzlich gilt, da ein binrer Baum nur endlich viele Knoten hat (Terminierungsbedingung!).
258

257

Rekursion - Bume
Der Knoten w, mit dem B1 und B2 oben verbunden sind, heit die Wurzel von B.

Rekursion - Bume
Wurzel

B1 und B2 heien linker bzw. rechter Unterbaum der Wurzel w.


Falls vorhanden, heien die Wurzeln von B1 und B2 linker bzw. rechter Sohn der Wurzel von B. Besitzt ein Knoten weder einen linken noch einen rechten Sohn, so wird er als Blatt bezeichnet.
259

Innere Knoten

Bltter

Bltter auf einer Ebene


tt Bl

er a

e ehr fm u

ren

en ben E

260

Rekursion - Bume
Ein Blatt ist dadurch ausgezeichnet, da der linke und der rechte Unterbaum leer sind. Ein innerer Knoten hat die Eigenschaft, da der rechte oder der linke Unterbaum nicht leer ist und da es sich nicht um die Wurzel handelt. Die Wurzel ist dadurch charakterisiert, da sie kein Sohn eines anderen Knotens ist.

Bume - Formalisierung der rekursiven Def.


Der leere Baum wird durch die leere Menge dargestellt, seine Knotenmenge ist leer, also Knoten() := . Seien B1 und B2 binre Bume, so da ihre Knotenmengen disjunkt sind, es gilt also Knoten(B1) Knoten(B2) = . Sei weiterhin w ein Knoten mit w Knoten(B1) Knoten(B2), dann heit B := (w, B1, B2) ein binrer Baum mit der Knotenmenge Knoten(B) := {w} Knoten(B1) Knoten(B2), der Wurzel w, linkem Unterbaum B1 und rechtem Unterbaum B2. Innere Knoten und Bltter lassen sich in dieser Formulierung ebenfalls mathematisch przise beschreiben.
262

261

Rekursion - Auf dem Weg zu Heapsort


Problem: Gegeben sei ein Feld a mit n Werten, die sortiert werden mssen. Ausgangssituation: Werte im Feld sind unsortiert Ziel: sortiertes Feld Idee 1: kleinsten Wert suchen, diesen mit dem ersten Wert tauschen, fast immer sehr langsam Idee 2: benachbarte Werte tauschen, wenn der zweite Wert grer ist. Solange bis alles sortiert ist. Langsam, wenn von vorne nach hinten durchgetauscht werden mu. Idee 3: Verwendung eines Binrbaums (Heapsort)
263

Rekursion - Auf dem Weg zu Heapsort


Wir verwenden die Zahlen 1 n zur Numerierung der Knoten eines binren Baums: 1 bildet die Wurzel, und der Knoten i > 1 hat i/2 als Vater, so da der linke Sohn eines Knotens gerade und der rechte Sohn eines Knotens ungerade ist, sofern der Knoten diese Shne hat. Damit knnen wir ein Feld ebenfalls als Baum darstellen: Ist das Feld a mit n Komponenten gegeben, so beschriften wir den Knoten i mit dem Feldelement a[i]. Im folgenden Beispiel haben wir das Feld mit den Elementen 7, 12, 0, 5, 9, 1, 3, 8, 13, 10, 15 als binren Baum dargestellt. Die Knoten i werden mit ihrer Beschriftung a[i] angegeben.
264

Rekursion - Auf dem Weg zu HeapSort


Knoten 1 7

Rekursion - Auf dem Weg zu Heapsort


Ein Feld gengt der Heap-Bedingung im Knoten i, falls im Unterbaum mit Wurzel i jeder Knoten eine kleinere Beschriftung als seine Shne trgt. Die Heap-Bedingung ist in den Knoten 3, 4, 5, 6, 7, 8, 9, 10, 11 erfllt, nicht jedoch im Knoten 2, da

Knoten 2

12

Knoten 3

Knoten 4

Knoten 5

1 Knoten 6

3 Knoten 7

a[2] = 12, a[4] = 5 und a[5] = 9

aber 12 > 5 und 12 > 9, und auch nicht im Knoten 1, da


a[3] = 0 und 7
265

8 Knoten 8

13 Knoten 9

10

15

Knoten 10 Knoten 11

> 0.
266

Lokale Gltigkeit der Heap-Bedingung


Knoten 1 7

Rekursion - Auf dem Weg zu Heapsort


Die Heap-Bedingung kann jedoch im Knoten 2 wie folgt hergestellt werden:

Knoten 2

12

Knoten 3

Knoten 4

Knoten 5

1 Knoten 6

3 Knoten 7

8 Knoten 8

13 Knoten 9

10

15

Wir vertauschen die Beschriftung im Knoten 2 mit der Beschriftung desjenigen Sohnes, der die kleinere Beschriftung trgt. In diesem Fall handelt es sich um den Knoten 4. Wir nehmen hierzu die kleinere der Beschriftungen der Shne, damit im Knoten 2 die HeapBedingung lokal erfllt ist: Die Beschriftung des Knotens 2 ist kleiner als die Beschriftungen seiner Shne (Ergebnis vgl. folgende Folie).

Knoten 10 Knoten 11 Heap-Bedingung im Teilbaum erfllt


267 268

Rekursion - Auf dem Weg zu Heapsort


Knoten 1 7

Herstellung der lokalen Heap-Bedingung im Knoten 2


Knoten 1 7

Knoten 2

Knoten 3

Knoten 2

Knoten 3

Knoten 4

12

Knoten 5

1 Knoten 6

3 Knoten 7

Knoten 4

12

Knoten 5

1 Knoten 6

3 Knoten 7

8 Knoten 8

13 Knoten 9

10

15

8 Knoten 8
269

13 Knoten 9

10

15

Knoten 10 Knoten 11

Knoten 10 Knoten 11
270

Rekursion - Auf dem Weg zu Heapsort


Nun ist zwar die Heap-Bedingung im Knoten 2 lokal hergestellt haben. Als Folge ist sie aber im Knoten 4 verletzt ist! Die Vertauschung der Beschriftung eines Knotens mit der kleineren Beschriftung eines seiner Shne, lt sich an dieser Stelle wiederholen, so da die Beschriftung 12 in ein Blatt, den Knoten 8, wandert. Trivialerweise ist die Heap-Bedingung in einem Blatt erfllt, so da wir durch das beschriebene Vorgehen schrittweise dafr gesorgt haben, da die Heap-Bedingung im Knoten 2 hergestellt wurde.

Rekursion - Auf dem Weg zu Heapsort


Knoten 1 7

Knoten 2

Knoten 3

Knoten 4

Knoten 5

1 Knoten 6

3 Knoten 7

12 Knoten 8

13 Knoten 9

10

15

Knoten 10 Knoten 11
272

271

Herstellung der Heap-Bedingung im Knoten 2


Knoten 1 7

Rekursion - Auf dem Weg zu Heapsort


Die Heap-Bedingung gilt aber immer noch nicht fr den Knoten 1, da die Beschriftungen beider Shne, der Knoten 2 und 3 kleiner sind als die Beschriftung der Wurzel des Baumes.

Knoten 2

Knoten 3

Knoten 4

Knoten 5

1 Knoten 6

3 Knoten 7

12 Knoten 8

13 Knoten 9

10

15

Knoten 10 Knoten 11
273 274

Rekursion - Heapsort
Definition: Das Feld a[1], , a[n] heit ein Heap, falls die Heap-Bedingung im Knoten 1 erfllt ist. Hieraus ergibt sich unmittelbar als Konsequenz, da das kleinste Element in einem Heap immer in der Wurzel, d.h. in a[1], steht.

Rekursion - Heapsort
1. Heap-Aufbau: Idee: Sei in i die Heap-Bedingung nicht erfllt (i ist also kein Blatt), wohl aber in allen Shnen. Dann werden folgende Vertauschungen vorgenommen:
2*i < n, 2*i + 1 > n: vertausche a[i] mit a[2*i]. Da i nur einen Sohn hat, ist die Heap-Bedingung in diesem Knoten erfllt. 2*i < n, 2*i + 1 < n: suche den Sohn k, k {2i, 2i+1}, so da gilt: a[k] = min {a[2*i], a[2*i + 1]}, vertausche a[i] mit a[k] und wende rekursiv diese Idee auf k an.

Der populre Sortieralgorithmus Heapsort arbeitet in zwei Phasen: Es ist ein Feld a mit n Elementen gegeben. In der ersten Phase wird dieses Feld in einen Heap umgestaltet, d.h. es wird dafr gesorgt, da der entsprechende binre Baum die Heap-Bedingung im Knoten 1 erfllt. In der zweiten Phase wird aus dem zuvor aufgebauten Heap systematisch ein geordnetes Feld erzeugt.
275

276

Rekursion - Heapsort
Dies fhrt zum Algorithmus Heapify, der rckwrtsgehend fr jeden Knoten k = n/2, , 1 die Heap-Bedingung erfllt. Rckwrtslaufen ist ntig, denn der Algorithmus sorgt dafr, da aus kleineren Heaps grere aufgebaut werden. Wenn wir in einem Knoten sind, dessen Unterbume beide die Heapbedingung erfllen, so wird durch die Bewegung des Knotenelements ja lediglich einer der Unterbume modifiziert, der andere Unterbaum bleibt in diesem Durchlauf unverndert.

Rekursion - Heapsort
Die Methode Heapify bekommt als Eingabe den Knoten dieserKnoten und die aktuelle heapGre des Feldes. Im ersten Schritt werden zunchst der linke und der rechte Sohn bestimmt. Danach findet eine Fallunterscheidung statt. Dabei wird untersucht, ob der linke Knoten noch im Feld und der rechte Knoten nicht mehr im Feld liegt: In diesem Fall mu lediglich getestet werden, ob die Beschriftung des Knotens grer ist als die Beschriftung seines einzigen Sohnes.

277

278

Rekursion - Heapsort
Der zweite Fall besteht darin, da auch der rechte Knoten noch im Feld liegt: In diesem Fall mu der Knoten mit der kleineren Beschriftung herausgesucht werden und die Beschriftung dieses Knotens mit der Beschriftung des eingegebenen Knotens verglichen werden. Falls es sich hierbei herausstellt, da die Heap-Bedingung verletzt ist, wird mit Hilfe der elementaren Methode Tausche der Inhalt dieses Knotens mit dem seines Sohnes vertauscht und Heapify mit dem Sohn und der Heapgre erneut aufgerufen.

Rekursion - Heapsort
void Heapify(int dieserKnoten, int heapGre) { int links = 2 * dieserKnoten, rechts = links + 1, derSohn; if (links <= heapGre && rechts > heapGre) { if (a[dieserKnoten] > a[links]) Tausche(dieserKnoten, links); } else if (rechts <= heapGre) { derSohn = (a[links] < a[rechts] ? links : rechts); if (a[derSohn] < a[dieserKnoten]) { Tausche(dieserKnoten, derSohn); Heapify(derSohn, heapGre); } 280 }}

279

Rekursion - HeapSort
Nachdem Heapify in der beschriebenen Art aufgerufen worden ist, stellt das Feld a einen Heap dar, der jetzt dazu herangezogen werden kann, das Feld zu sortieren. Wir hatten gerade festgestellt, da das kleinste Element in der Wurzel liegt. Also vertauschen wir zunchst a[1] mit a[n]. Damit haben wir bereits ein Element des Feldes, das kleinste, sortiert. Um das zweitkleinste Element zu bestimmen, sorgen wir nun dafr, da die restlichen n-1 Elemente wieder einen Heap bilden. Anschlieend knnen wir dessen Wurzel und a[n1] miteinander vertauschen und haben bereits zwei Elemente des Feldes sortiert, und so geht es weiter, bis alle Elemente sortiert sind.

Rekursion - HeapSort
Auf der folgenden Folie wird dieser erste Sortierschritt an einem Beispiel gezeigt. Die bernchste Folie demonstriert dann die nchsten beiden Sortierschritte, nach deren Ausfhrung bereits die drei letzten Elemente des Feldes sortiert sind, so da nun nur noch n3 Elemente betrachtet werden mssen. Das Feld ist vollstndig sortiert, wenn der im nchsten Sortierschritt noch zu betrachtende Heap nur noch aus der Wurzel besteht.

281

282

Sortieren mit einem Heap - erster Sortierschritt


Aufgebauter Heap

Sortieren mit einem Heap - 2. / 3. Sortierschritt


Zweiter Sortierschritt

1
erster Sortierschritt Austausch

6 4 6 9 12 4 1

Reorganisation des Heaps

12

8 9 12 7
bereits sortiert

bereits sortiert

Reorganisation des Heaps

Dritter Sortierschritt

9 12

12

12

1
283

1
284

Rekursion - Heapsort
Der Konstruktor fr die Klasse Heap allokiert das Feld a. Da a[0] nicht benutzt wird, bentigen wir ein Feld mit k+1 Elementen, um k Zahlen zu speichern. Die Initialisierung von a passiert ber die Methode Setze. Neben der bereits bekannten, privaten Methode Heapify werden die parameterlosen Methoden BaueHeap und Sortiere implementiert. Zusammen realisieren sie den Algorithmus Heapsort.

Rekursion - HeapSort
Der Aufbau eines ersten Heaps aus einem gegebenen Feld erfolgt durch den Aufruf der Methode BaueHeap. Da jedes Blatt des Baumes fr sich bereits einen Heap bildet, beginnen wir in der Mitte des Feldes mit dem Aufruf von Heapify und bauen so immer grere Heaps auf. Anschlieend fhrt die Methode Sortiere das bereits vorgestellte Vorgehen mit Vertauschen und Reorganisieren durch. Das Auslesen eines sortierten Feldes kann durch die mehrfache Ausfhrung der Methode Gib erfolgen

285

286

Rekursion - Klasse Heap


class Heap { private int[] a; Heap(int k) { a = new int[k+1]; } void Setze(int i, int x) { a[i] = x; } int Gib(int i) { return a[i]; } private void int t = a[eins] a[zwei] } Tausche(int eins, int zwei) { a[eins]; = a[zwei]; = t;
287

Rekursion - Auf dem Weg zu Heapsort


private void Heapify(int dieserKnoten, int heapGre) {wie vorne definiert } void BaueHeap() { for (int i = (a.length-1)/2; i >= 1; i--) Heapify(i, a.length-1); } void Sortiere() { BaueHeap(); for (int i = a.length-1; i > 1; i--) { Tausche(1, i); Heapify(1, i-1); } 288 }

Klassifikation rekursiver Methoden


Definition: Eine rekursive Methode heit linear, wenn in den einzelnen Zweigen der bedingten Anweisung, die die rekursiven Aufrufe steuert, jeweils hchstens ein Aufruf der Methode vorkommt. Beispiele:

Klassifikation rekursiver Methoden


Definition: Eine lineare rekursive Methode heit schlicht, wenn lediglich der Wert eines frheren Aufrufs bertragen eingeht. Beispiele: int F(int x, int y)) { int t = 0; if (y == 0) t = x; else if (y > 0) t = F(x * y, y - 1); return t; Fakultt ist nicht schlicht, denn es wird nach dem Aufruf noch multipliziert.
290

Die Methode Fakultt ist linear. Die Methode Heapify ist linear. Die Methode Fibonacci ist nicht linear.
289

Klassifikation rekursiver Methoden


Eine systematische Transformation schlichter rekursiver Methoden in nicht-rekursive Methoden ist auf einfache Weise mglich. Wir erlutern dies zunchst an einem Beispiel.
Beispiel: Sei F gegeben wie oben definiert. Wir berechnen F(a, 3) schrittweise: F (a, 3) = F (a*3, 2) = F (a*3*2, 1) = F (a*3*2*1, 0) = a*3*2*1

Klassifikation rekursiver Methoden


Behauptung: n 0 gilt F (x, n) = x * n! . Beweis (durch vollstndige Induktion): Induktionsverankerung n = 0: F (x, 0) = x = x * 0! Induktionsschritt: Induktionsvoraussetzung ist: F (x, n) = x * n! x N0 Wir wollen zeigen: x N0 : F (x, n+1) = x*(n+1)! F(x, n+1) = F (x*(n+1), n) = x*(n+1)* n! = x*(n+1)!
291 292 Induktionsvoraussetzung

Klassifikation rekursiver Methoden


Dies fhrt zu einer nicht-rekursiven Lsung. Das erste Argument wird als eine Art Akkumulator eingesetzt wird: Die Resultate werden im ersten Argument so lange angesammelt, bis y den Wert 0 erreicht hat. Dann werden sie ausgegeben. int Iterativf (int x, int y) { int x1 = x, y1 = y, tx, ty; while (y1 > 0) { tx = x1 * y1; ty = y1 - 1; x1 = tx; y1 = ty; } return x1;
293

Klassifikation rekursiver Methoden


Beh.:
F(x,y) = Iterativf(x, y)

Beweis (durch vollstndige Induktion nach y): Induktionsverankerung: Fr y=0 : Iteratif (x,y) = x = x * 0! = F(x, y). Induktionsschritt: Die Behauptung gelte fr ein y N0. Wir mssen ihre Gltigkeit fr y+1 nachweisen. Es mu also gezeigt werden, da nach x1 = x; y1 = y+1; while(y1 > 0) {} von Iterativf der Wert F(x, y+1) geliefert wird.
294

Klassifikation rekursiver Methoden


Die Schleife kann, da y+1 > 0, umformuliert werden zu:
tx = x1 * y1; ty = y1 - 1 ; // 1 x1 = tx; y1 = ty; // 2 while(y1 > 0) {}

Klassifikation rekursiver Methoden


In // 1 gilt: also:
x1 = x; y1 = y + 1; tx = x * (y + 1); ty = y;

Daraus erhlt man in // 2 (durch Einsetzen):


x1 = x * (y + 1); y1 = y;

Mit diesen Anfangswerten wird die Bedingungsschleife betreten, nach Induktionsvoraussetzung liefert Iterativf dann den Wert
F(x * (y+1), y) = x * (y+1) * y! = x*(y+1)! = F(x, y + 1)
295

was zu zeigen war.

296

Klassifikation rekursiver Methoden


Verallgemeinerung der Umformulierung der Schleife: Ist P(x) eine Aussage ber x und sind I1(x), I2(x) Anweisungen, so da I2(x) den Wert von x ndert, so sind die beiden folgenden Code-Fragmente gleichwertig.

Verallgemeinerung dieses Vorgehens


Gegeben sei die schlicht rekursive Methode: int F(int x, int y) {
// Deklarationen ausgelassen return (y > 0 ? F((x, y), y-1) : (x));

while(P(x)){ I2(x); } I1(x);

if(P(x)){ I2(x); } while(P(x)){ I2(x); } I1(x);


297

298

Verallgemeinerung dieses Vorgehens


Hier hngen die Funktionen und weder direkt noch indirekt von F ab. Die Methode F wird analog zum vorhergehenden Beispiel transformiert in:
int Iterativf (int x, int y) { // ohne Deklarationen x1 = x; y1 = y; while (y1 > 0) { tx = (x1, y1); ty = y1 -1; x1 = tx; y1 = ty; } return (x1); }
299

Verallgemeinerung dieses Vorgehens


Derselbe Beweis, den wir gerade fr die Fakulttsfunktion durchgefhrt haben, zeigt, da die rekursive Methode F und die iterative Methode Iterativf quivalent in dem oben besprochenen Sinne sind. Wir merken abschlieend an, da die Verallgemeinerung auf mehr als zwei Argumente leicht mglich ist.

300

Verschachtelte Klassen
Definition: Eine verschachtelte Klasse (nested class) ist eine Klasse, die Mitglied einer anderen Klasse ist. Wenn sie static ist, dann spricht man von einer static verschachtelten Klasse. Non-static verschachtelte Klassen heien auch innere Klassen (inner class). Man verwendet verschachtelte Klassen, um die Beziehungen zwischen Klassen zu veranschaulichen. Man sollte eine Klasse als verschachtelte Klasse einer umgebenden Klasse definieren, wenn sie nur in dieser Umgebung Sinn macht oder sogar auf die Funktionalitt der umgebenden Klasse angewiesen ist. Beispiel: Textcursor-Klasse in Textverarbeitungsklasse
302

Kapitel 10
Verschachtelte Klassen (nested classes) / Innere Klassen (inner classes)

Verschachtelte Klassen
As a member of its enclosing class, a nested class has a special privilege: It has unlimited access to its enclosing class's members, even if they are declared private. However, this special privilege isn't really special at all. It is fully consistent with the meaning of private and the other access specifiers. The access specifiers restrict access to members for classes outside of the enclosing class. The nested class is inside of its enclosing class so that it has access to its enclosing class's members.
(aus dem Java Tutorial)
303

Verschachtelte Klassen
Verschachtelte Klassen knnen als static definiert werden, dann heien sie static nested classes. Eine non-static verschachtelte Klassen heit inner class.
class EnclosingClass{ . . . static class AStaticNestedClass {...} class InnerClass {...} }

304

Verschachtelte Klassen
Wie fr static Methoden und Variablen blich gilt: ... a static nested class is associated with its enclosing class. And like class methods, a static nested class cannot refer directly to instance variables or methods defined in its enclosing class-it can use them only through an object reference. (Java Tutorial) As with instance methods and variables, an inner class is associated with an instance of its enclosing class and has direct access to that object's instance variables and methods. Also, because an inner class is associated with an instance, it cannot define any static members itself. (Java Tutorial) 305

Verschachtelte Klassen
Zur Unterscheidung: nested class reflektiert die syntaktische Beziehung zwischen Klassen (der Code einer Klasse erscheint im Code einer anderen). inner class reflektiert die Beziehungen zwischen Objekten der Klassen.

306

Verschachtelte Klassen
Verschachtelte Klassen dienen dazu, Klassen die nur lokal bentigt werden, im lokalen Rahmen zu definieren. Zweck der Verwendung verschachtelter Klassen ist es, grtmgliche bersicht zu gewhrleisten. Es gibt insgesamt 4 Arten von verschachtelten Klassen:
static verschachtelte Klassen innere Klassen lokale Klassen anonyme Klassen

Innere Klassen
class EnclosingClass { . . . class InnerClass { . . . } } Ein Objekt der Klasse InnerClass kann nur im Rahmen eines Objektes der Klasse EnclosingClass existieren. Es hat direkten Zugriff auf Instanzvariablen und Methoden des umgebenden Objekts.

(local classes) (anonymous classes)

307

308

Innere Klassen
Innere Klassen sind die wichtigste Anwendung verschachtelter Klassen! Innere Klassen werden oft im Sinne von Adaptern verwendet. Soll beispielsweise eine beliebige Struktur von Elementen in der Lage sein, einem Aufrufer bestimmte Information ber die Werte der Struktur zu bermitteln, so kann eine innere Klasse in der Rolle des Adapters dazu dienen, sich auf den Aufrufer einzustellen. Eine solche Klasse ist auerhalb der Struktur (fr die Informationen ber die Werte geliefert werden) bedeutungslos und deshalb eine innere Klasse zu der eigentlichen die Struktur realisierenden Klasse.
309

Innere Klassen
Beispiel Stapel: Die Elemente eines Stapels sollen fr externe Anfrager aufgezhlt werden. Diese Anforderung soll nicht mit der eigentlichen Stapelfunktionalitt vermischt werden. Als zustzliche Methoden werden identifiziert: public boolean hasMoreElements(); public Object nextElement(); Eine Bereitstellung in Form einer inneren Klasse ist ntig, wenn die Aufzhlung mehrfach simultan aufgerufen werden soll oder wenn in verschiedenen Aufzhlungen unterschiedlich reagiert werden soll. 310

Innere Klassen
Diese innere Klasse mu Zugriff auf die Stapelelemente haben und das unabhngig von den Stapelzugriffsmethoden. public class Stack { private Vector items; //code for Stack-Methoden ausgelassen class StackEnum { ... public boolean hasMoreElements() { ... } public Object nextElement() { ... } } } Hinweis: Die StackEnum Klasse benutzt direkt die Instanzvariablen von Stack-Objekten.
311

Lokale Klassen

Sie befinden sich innerhalb eines Code-Blocks und verhalten sich wie verschachtelte Klassen. Sie sind nur sichtbar innerhalb des Blocks, in dem sie definiert sind. Sie werden benutzt, wenn die Klasse nur innerhalb eines Code-Blocks gebraucht wird. Fr einmalige Anwendung, die keine Konstruktoren erfordert, sind anonyme Klassen geeigneter.

312

Anonyme Klassen
Anonyme Klassen Im vorherigen Beispiel hat der Klassenname StackEnum nichts zum Verstndnis des Programms beigetragen. Es gibt die Mglichkeit, innere Klassen ohne Namen zu definieren. Wir sprechen dann von anonymen Klassen. Hinweis: Anonyme Klassen sollten nur verwendet werden, wenn es um Klassen geht, die ganz sicher nur einen Zweck haben und die maximal zwei Methoden haben. Alles andere gefhrdet die Lesbarkeit des Codes.

Anonyme Klassen
Anonyme Klassen sind lokale Klassen ohne Namen Das bedeutet: man kann sie in einem Schritt definieren und benutzen Syntax: new NameOberklasse() {
// zustzliche Attribute und Methoden }

Sie haben keinen Konstruktor Sie sind praktisch, wenn eine Klasse nur ein einziges Mal gebraucht wird

313

314

Kapitel 11
Elementare Java-Klassen 11.1 String 11.2 Felder 11.3 Object

Kapitel 11.1
String

Klasse String
Zeichenketten werden durch Objekte der Klasse String dargestellt. Wir hatten schon gesehen, da String kein primitiver Typ, sondern eine vordefinierte Klasse ist!

Klasse String
Warum zwei String Klassen? The Java development environment provides two classes that store and manipulate character data: String, for constant strings, and StringBuffer, for strings that can change.

String ist eine besondere Klasse, da Literale (konstante Zeichenketten) und Operatoren (+ zur Konkatenation) definiert sind.
In enger Verbindung mit der Klasse String steht die Klasse StringBuffer.

You use Strings when you don't want the value of the string to change. For example, if you write a method that requires string data and the method is not going to modify the string in any way, use a String object. Typically, you'll want to use Strings to pass character data into methods and return character data from methods.
318

317

Klasse String

Methoden der Klasse String (Ausschnitt)


Konstruktoren: public String(char chars[])

Because they are constants, Strings are typically cheaper than StringBuffers and they can be shared. So it's important to use Strings when they're appropriate.
(aus dem Java Tutorial)

Konvertiert Array von Zeichen in einen String

public String(byte bytes[])


Konvertiert Array von Bytes in einen String Plattformspezifische Zeicheninterpretation wird benutzt

public String(StringBuffer buffer)


Konvertiert StringBuffer nach String

Beispiel:
char[] c = {'S', 'c', 'h', 'u', 'l', 'z', 'e'}; String s = new String(c); System.out.println(s);
319 320

String-Objekte

Elementare Java-Klassen

String-Konkatenation
Der +-Operator kann verwendet werden, um zwei Objekte der Klasse String zu verknpfen Ist nur einer der Operanden ein Objekt der Klasse String, und ein anderer ein primitiver Datentyp, wird letzterer nach String gewandelt Beispiel:

Objekte fr den Umgang mit Zeichenketten Aufruf von Methoden fr Erzeugen, Aneinanderhngen, Lngenmessung, Vergleich, ... Erzeugen
String vorname= new String ("Max") String nachname= "Mustermann" (Kurz-Form mit Literal)

Messen der Lnge


int laenge= name.length()

14

int alter = 27; System.out.println("Alter :

" + alter + " Jahre");

Aneinanderhngen (Konkatenation)

String name = vorname + nachname

(neues String-Objekt)

Ausgabe:
Alter: 27 Jahre

321

322

String-Objekte
Vergleichen (mit anderem Objekt):

Elementare Java-Klassen

Methoden der Klasse String (Ausschnitt)


Beispiel:
String s1 = "Test", s2=s1; String s3="Te", s4="st", s5; s5 = s3 + s4; System.out.println((s1 == s2) + " / " + s1.equals(s2)); System.out.println((s1 == s3) + " / " + s1.equals(s3)); System.out.println((s1 == s5) + " / " + s1.equals(s5));

public boolean equals(Object anObject)


Vergleicht String mit einem anderen Object auf Gleichheit Typ Object heit, da Objekte aller Klassen als Argument bergeben werden drfen (spter mehr) Operator "==" vergleicht nur, ob die Referenz identisch ist, also ob es sich um dasselbe Objekt handelt, und nicht, ob es inhaltlich identisch ist

String vorname2= "Max" boolean istGleich = vorname.equals(vorname2)

true

Ausgabe:
true / true false / false false / true

Achtung:

== vergleicht Referenzen beider Seiten miteinander!


false
323

boolean istGleicheReferenz = (vorname == vorname2)

324

Methoden der Klasse String (Ausschnitt)


public int length()
Gibt Lnge des Strings zurck

Methoden der Klasse String (Ausschnitt)


public String toLowerCase() public String toUpperCase()
Wandelt String in Kleinbuchstaben bzw. Grobuchstaben Funktioniert auch mit deutschen Umlauten "" wird bei toUpperCase nach "SS" gewandelt, Rckwandlung funktioniert hier natrlich nicht

public byte[] getBytes()


Konvertiert String in Array von Bytes Plattformspezifische Zeicheninterpretation wird benutzt

public int compareTo(String anotherString)


vergleicht zwei Zeichenketten lexikographisch basierend auf UnicodeNummern (Telefonbuchordnung) Ergebnis ist gleich 0, falls Strings identisch sind, kleiner 0, falls der String lexikographisch kleiner ist, als das Argument, grer 0, falls der String lexikographisch grer ist, als das Argument

Beispiel:
String a = "Schohndchen" System.out.println(a.toLowerCase()); System.out.println(a.toUpperCase()); System.out.println(a.toUpperCase() .toLowerCase());

Ausgabe:
schohndchen SCHOSSHNDCHEN schosshndchen

325

326

String und StringBuffer


String ist nur geeignet, um nicht nderbare Zeichenketten zu verarbeiten, denn z.B. bei Stringkonkatenation durch "+" wird ein neues Objekt erzeugt und die kompletten alten Inhalte kopiert.
Mssen in eine Zeichenkette laufend kleine Teilzeichenketten angefgt werden, so ist StringBuffer besser geeignet

Methoden der Klasse StringBuffer (Ausschnitt)


StringBuffer hat ein initiales Fassungsvermgen
Wird mehr bentigt, wird es automatisch erweitert Bei anfnglicher realistischer Voreinschtzung der bentigten Lnge lt sich die Effizienz steigern Konstruktoren: public StringBuffer()
Erzeugt Leerstring mit initialem Fassungsvermgen von 16 Zeichen

public StringBuffer(int length)


Erzeugt Leerstring mit spezifiziertem initialen Fassungsvermgen

public StringBuffer(String str)


Initialisiert StringBuffer mit vorgegebenem String.
327 328

Methoden der Klasse StringBuffer (Ausschnitt)


public StringBuffer append(String str)
Hngt eine Zeichenkette an den String an Fassungsvermgen wird dynamisch an die bentigten Gegebenheiten angepat

Methoden der Klasse StringBuffer (Ausschnitt)


Einfgen von Zeichen in StringBuffer-Objekte: StringBuffer sb = new StringBuffer("Drink Java!"); sb.insert(6, "Hot "); System.out.println(sb.toString()); Ergebnis: Drink Hot Java!

public int length()


Gibt die Lnge der aktuellen Zeichenkette zurck (nicht des aktuellen Fassungsvermgens)

public String toString()


Wandlung in eine Zeichenkette vom Typ String

Ersetzen von Zeichen an bestimmten Positionen: setCharAt ersetzt ein Zeichen an einer bestimmten Position innerhalb des StringBuffer-Objektes.

329

330

Methoden der Klasse StringBuffer (Ausschnitt)


Anhngen am Ende eines StringBuffer-Objekts:
StringBuffer sb = new StringBuffer("Drink Hot"); sb.append("!"); System.out.println(sb.toString());

Methoden der Klasse StringBuffer (Ausschnitt)


Reversieren eines StringBuffer-Objektes: class ReverseString { public static String reverseIt(String source) { int i, len = source.length(); StringBuffer dest = new StringBuffer(len); for (i = (len - 1); i >= 0; i--) { dest.append(source.charAt(i)); } return dest.toString(); } }
332

Ergebnis:

Drink Hot!

331

Methoden der Klasse StringBuffer (Ausschnitt)


Erluterung zum Reversieren: Die Anweisung StringBuffer dest legt fest, da ein StringBuffer-Objekt verwendet werden soll. Hierfr wird Speicherplatz allokiert.
StringBuffer(len) initialisiert das Objekt.

bung: String, Referenzen


Motivation

Elementare Java-Klassen

Benutzen von Zeichenketten bergabe von Referenzen statt kompletter Parameter-Objekte

Aufgabe Jedes Girokonto soll einen eigenen Konten-Inhaber bekommen. Entwerfen und implementieren Sie eine neue Klasse "Person:
Attribute: Vorname, Nachname, Strasse, Postleitzahl (plz) und Ort vom Typ String Methoden: void setzeName : Setzen von Vorname und Nachname void setzeAdresse : Setzen von Strasse, PLZ, Ort String holeInhaber : Rckgabe aller aneinanderfgten Attribute

Durch das Anhngen eines Zeichens an ein StrinBuffer-Objekt kann prinzipiell neue Speicherallokation ntig sein. Dies ist teuer. Deshalb wird im Reversieren ein passend langes StringBuffer-Objekt auf einmal allokiert.
333

...

334

bung: String, Referenzen

Elementare Java-Klassen

bung: String, Referenzen


Lsung 1:

Elementare Java-Klassen

Aufgabe (Forts.) Testen Sie nun die Klasse "Person" (vgl. Klasse "TestGirokonto").
Was kann/sollte man testen? Testen Sie auch folgendes: Erzeugen Sie zwei Konten und eine Person, setzen diese fr beide Konten als Inhaber. ndern Sie ein Attribut dieser Person und geben Sie danach fr beide Konten den Inhaber aus. Was fllt Ihnen auf?

public class Person { private String vorname, nachname, strasse, plz, ort; public Person(String vorname, String nachname, String strasse, String plz, String ort) { setzeName(vorname, nachname); setzeAdresse(strasse, plz, ort); } public void setzeName (String vorname, String nachname){ this.vorname=vorname; this.nachname=nachname; }
335 336

bung: String, Referenzen


...

Elementare Java-Klassen

bung: String, Referenzen


Lsung:

Elementare Java-Klassen

public void setzeAdresse(String strasse, String plz, String ort){ this.strasse=strasse; this.plz=plz; this.ort=ort; } public String holeInhaber(){ return (this.vorname+" "+this.nachname+", "+this.strasse +", "+this.plz+" "+this.ort); } }

public class Test2 { public static void main(String[] args) { Waehrungsrechner wr = new Waehrungsrechner(); Person herrMeyer = new Person ("Martin", "Meyer", "Saarstrasse 11", "D-44227", "Dortmund"); Girokonto konto1 = new Girokonto (herrMeyer, wr, 100); Girokonto konto2 = new Girokonto (herrMeyer, wr, 200); Bildschirm.gibAus(konto1.holeInhaber() ); Bildschirm.gibAus(konto2.holeInhaber() ); herrMeyer.setzeAdresse("Moselgasse 5", "D-44223", Dortmund");
337

Bildschirm.gibAus(konto1.holeInhaber() Bildschirm.gibAus(konto2.holeInhaber()

); );

338

Felder

Elementare Java-Klassen

Kapitel 11.2
Felder

array A collection of data items, all of the same type, in which each item's position is uniquely designated by an integer.

340

Felder

Elementare Java-Klassen

Eindimensionale Felder
Deklaration: Typ[] Feldname; (alternativ: Typ Feldname[];) Initialisierung: Feldname = new Typ[Feldgre]; Initialisierung mit Werten: Feldname = new Typ[]{Konst1, Konst2, ..., Konstn}; Deklaration und Initialisierung: Typ[] Feldname = new Typ[Feldgre]; Typ[] Feldname = { Konst1, Konst2 ...};

Objekte fr den Umgang mit Folgen von Objekten


Girokonto[] Konten; ... Konten = new Girokonto[100]; ... Typ feldname[] oder: Typ[] feldname Beim Erzeugen wird die Feldgre mitgegeben

belegen der Feldpltze


Index beginnt bei 0

konten[0]=... konten[1]=...

; ;

zugreifen auf ein einzelnes Feld-Objekt (mittels Index)

konten[2] ergibt das Girokonto-Objekt auf dem 3. Platz des Felds


341

342

Eindimensionale Felder
Zugriff auf Feldelemente: Feldname[Nummer];
Nummer ist eine Zahl vom Typ int zwischen 0 und Feldgre-1

Anwendung: Sortieren durch Einfgen


Problem: Eine unsortierte Folge von Zahlen soll geordnet werden. Dazu sollen die Zahlen zunchst in einem Feld int[] zahlen abgelegt werden, das anschlieend aufsteigend sortiert werden soll. Idee: Sind fr einen Indexwert i bereits die Elemente zahlen[0], , zahlen[i-1] aufsteigend sortiert, so suche man im bereits sortierten Bereich die Position k, an der zahlen[i] eingefgt werden kann, verschiebe zahlen[k], , zahlen[i-1] um genau eine Position weiter auf die Elemente zahlen[k+1], , zahlen[i] und setze zahlen[k] = zahlen[i].

Zugriff auf Feldlnge: Feldname.length Typ kann ein primitiver Datentyp oder auch eine Klasse sein Es knnen mehrere Referenzen auf ein Array zeigen

343

344

Anwendung: Sortieren
Bei der Bestimmung von k sind die folgenden Flle zu bercksichtigen: Alle Werte im sortierten Bereich sind kleiner als der einzusortierende Wert, d.h. zahlen[i-1] zahlen[i]: dann ist k = i. In allen anderen Fllen: k sei der kleinste Index t, t {1, , i-1}, fr den gilt: zahlen[i] zahlen[t] (Dann gilt also: zahlen[i] zahlen[k] und zahlen[i] > zahlen[k1], denn k ist minimal; fr zahlen[i] < zahlen[0] gilt: k = 0) Code fr die Bestimmung von k: k = 0; while ((k < i) & (zahlen[i] >= zahlen[k])) 345 k++;

Anwendung: Sortieren
Die Verschiebung erfolgt in folgender Weise:
merker = zahlen[i]; zahlen[i] = zahlen[i-1]; zahlen[i-1] = zahlen[i-2]; zahlen[k+1] = zahlen[k]; zahlen[k] = merker ;

Code fr die Verschiebung:


for (int j = i; j > k; j--) zahlen[j] = zahlen[j-1];

346

Anwendung: Sortieren
Die Analyse dieses Algorithmus zeigt, da fr das Element zahlen[i] der Test zur Bestimmung der Position des Einfgens, (k<i) & (zahlen[i]>=zahlen[k]), im ungnstigsten Fall i1-mal durchgefhrt wird. Dieser Fall liegt dann vor, wenn das einzufgende Element an das Ende des sortierten Bereichs plaziert wird. Fr die gesamte Zahlenfolge ist der ungnstigste Fall daher dann gegeben, wenn eine bereits sortierte Folge vorliegt. Fr n Elemente werden dann insgesamt 1 + 2 + + (n 1) = n*(n1)/2 Tests durchgefhrt. Fr eine lange Zahlenfolge von beispielsweise 10 000 Elementen knnte daher der Fall eintreten, da bis zu annhernd 50 Millionen Vergleiche ausgewertet werden mssen.
347

int[] zahlen; int merker=0, k=0; // Einlesen der Elemente for (int i = 0; i < zahlen.length; i++) { k = 0; while ((k < i) & (zahlen[i] >= zahlen[k])) k++; if (k != i) { merker = zahlen[i]; for (int j = i; j > k; j--) zahlen[j] = zahlen[j-1]; zahlen[k] = merker; } } // Ausgeben der Elemente
348

public class Sort { public static void main(String[] args) { int[] arrayOfInts = { 32, 87, 3, 589, 12, 1076, 2000, 8, 622, 127 }; for (int i = arrayOfInts.length; --i >= 0; ) { for (int j = 0; j < i; j++) { if (arrayOfInts[j] > arrayOfInts[j+1]) { int temp = arrayOfInts[j]; arrayOfInts[j] = arrayOfInts[j+1]; arrayOfInts[j+1] = temp; } }} for (int i = 0; i < arrayOfInts.length; i++) { System.out.print(arrayOfInts[i] + " "); } System.out.println(); }}
349

Mehrdimensionale Felder
mehrdimensionale Felder mglich

Elementare Java-Klassen

int[][] dreieck; dreieck = {{1}, {2,3}, {4,5,6}}; dreieck[1][0] ergibt 2


dreieck[1].length liefert die Ausdehnung der zweiten Dimension in der Abhngigkeit von der ersten Dimension, hier also 2, die Anzahl der Spalten der zweiten Zeile (denn die wird durch den Index [1] referenziert.

Initialisierung eines Feldes mglich (schon bei Deklaration)


mu alle Elemente belegen

int[][] dreieck = {{1}, {2,3}, {4,5,6}}


Typ Feldname = { Konst1, Konst2 ...}
350

Mehrdimensionale Felder
Deklaration: Typ[][] Feldname; // zweidimensional Typ[][][] Feldname; // dreidimensional (alternativ: Typ Feldname[][];) Initialisierung: Feldname = new Typ[Feldgre1][Feldgre2];
oder (fr nicht notwendigerweise rechteckige Arrays):

Mehrdimensionale Felder
Deklaration mit Initialisierung:
Grundtyp[][] Feldname = new Typ[Feldgr1][Feldgr2]; Grundtyp[][] Bezeichner={{Konst1,Konst2 ...},{...},...};

Zugriff auf Feldelemente:


Bezeichner[Nummer1][Nummer2]

Bezeichner = new Typ[Feldgre1][]; for (int i=0; i<Feldgre1; i++) Bezeichner[i] = new Typ[Feldgre_i];
351

Feldname ist Referenz auf das n-dimensionale Array Feldname[Nummer] ist Referenz auf ein (n-1)-dimensionales Teil-Feld Feldname.length ist die uere Feldlnge Feldname[Nummer].length ist die Feldlnge eine Ebene tiefer

352

Mehrdimensionale Felder
Beispiel:
int abteilungsAnzahl = 4; int[] abteilungsGre = {6, 17, 13, 14}; String[][] mitarbeiter = new String[abteilungsAnzahl][]; for (int i=0; i<abteilungsAnzahl; i++) mitarbeiter[i] = new String[abteilungsGre[i]]; mitarbeiter[0][0] mitarbeiter[0][1] ... (6 Leute) mitarbeiter[1][0] mitarbeiter[1][1] ... = "Max Born"; = "Werner Heisenberg"; = "Albert Einstein"; = "Nils Bohr"; // Abteilung 1

Mehrdimensionale Felder
Beispiel: Ausgabe zweidimensionaler Felder
float[][] matrix = new float[4][4]; setupMatrix(mat); // Eingabe der Werte for (int y=0; y < mat.length; y++){ for (int x=0; x < mat[y].length; x++) System.out.print(mat[y][x] + ); System.out.println(); }

// Abteilung 2

353

354

bung: Kartenverwaltung

Elementare Java-Klassen

bung: Kartenverwaltung

Elementare Java-Klassen

Motivation Vertiefen von FOR, IF-ELSE, Array und String Aus Anforderungstext zu Programmcode kommen Motivation fr Ausnahmebehandlung erkennen Aufgabe Entwerfen und implementieren Sie eine Klasse Kartenverwaltung, die folgende Tabelle verwaltet:
i 0 1 2 ... 34 ... 99 9999999 YYYY 343434 Y kartennr (Array mit 100 String-Obj.) 000 111 222 pins (Array mit 100 String-Obj.) A B C konten (Array mit 100 Girokonto-Obj.) (Zeiger auf ein Konto)

Vorgehen berlegen Sie sich, wie Sie die Tabelle in Java realisieren mchten (z.B. mehrere Arrays, parallel durchlaufen) Welche Attribute und Methoden soll die neue Klasse Kartenverwaltung haben? Wie kann man in der Tabelle eine Zeile lokalisieren zu einem vorgegebenen Eintrag (z.B. Kartennummer)? Schreiben Sie den Quellcode der Klasse Kartenverwaltung auf und beheben Sie ggf. auftauchende Fehler! berlegen Sie, auf welche Weise Sie diese neue Klasse testen knnen und schreiben Sie den Quellcode fr diese Testklasse!

355

356

bung: Kartenverwaltung

Elementare Java-Klassen

bung: Kartenverwaltung (1/4)

Elementare Java-Klassen

Methoden: erfasseWeiteresKonto: Eintragen von Konto, Kartennummer und Pin in eine Tabellenzeile holeKonto : Rckgabe des Kontos zu einer bergebenen Kartennummer : Rckgabe true falls Kartennummer und PIN zusammengehren false sonst

pinIstGltig

public class Kartenverwaltung { private String[] pins =new String[100]; private String[] kartennr =new String[100]; private Girokonto[] konten=new Girokonto[100]; //Feldindex des private int freiIndex; //frhesten //unbesetzten Eintrags public Kartenverwaltung(){ freiIndex=0; } // weiter auf nchster Folie

357

358

bung: Kartenverwaltung (2/4)

Elementare Java-Klassen

bung: Kartenverwaltung (3/4)


...

Elementare Java-Klassen

public void erfasseWeiteresKonto (String kartennummer, String pin, Girokonto konto){ kartennr[freiIndex]=kartennummer; pins[freiIndex]=pin; konten[freiIndex]=konto; freiIndex++; }

public Girokonto holeKonto (String kartennummer){ Girokonto dasKonto=null; for (int i=0; i<freiIndex; i++){ if (kartennummer.equals(kartennr[i])){ dasKonto=konten[i]; } } return (dasKonto); }

359

360

bung: Kartenverwaltung (4/4)

Elementare Java-Klassen

bung: Test_Kartenverwaltung
public class Test_Kartenverwaltung { public static void main(String[] args) {

Elementare Java-Klassen

public boolean pinIstGltig (String kartennummer, String pin){ int i; for (i=0; (! kartennummer.equals(kartennr[i])); i++) {} return (pin.equals(pins[i])); } }

// 1. Erzeuge Waehrunsgrechner, Person und drei Konten // mit initialen Konstnden von 100,200, 300 Pfennigen Waehrungsrechner wr=new Waehrungsrechner(); Girokonto konto1=new Girokonto(wr, 100); Girokonto konto2=new Girokonto(wr, 200); Girokonto konto3=new Girokonto(wr, 300); // 2. Erzeuge eine Kartenverwaltung und fge dort // die 3 Konten mit PIN ein Kartenverwaltung kv=new Kartenverwaltung(); kv.erfasseWeiteresKonto("111", "A", konto1); kv.erfasseWeiteresKonto("222", "B", konto2); kv.erfasseWeiteresKonto("333", "C", konto3);

361

362

bung: Test_Kartenverwaltung

Elementare Java-Klassen

bung: Test_Kartenverwaltung

Elementare Java-Klassen

// 3. hole von Kartenverwaltung (OHNE PIN-Prfung!) die Konten // und gib ihre Kontostande aus Bildschirm.gibAus("Der Kontostand fuer Kartennummer 1 ist " +kv.holeKonto("111").holeKontostand());
Bildschirm.gibAus("Der Kontostand fuer Kartennummer 2 ist "+kv.holeKonto("222").holeKontostand()); Bildschirm.gibAus("Der Kontostand fuer Kartennummer 3 ist "+kv.holeKonto("333").holeKontostand());

// 4. hole MIT PIN-Prfung das Konto2, gib Kontostand aus boolean istAkzeptiert=false; do { String eingabePIN=Bildschirm.gibEin("Bitte PIN fr fuer Konto 2");
if (kv.pinIstGltig("222", eingabePIN)) { istAkzeptiert=true; Bildschirm.gibAus("Die eingegebene PIN ist gueltig."); Girokonto dasKonto2=kv.holeKonto("222"); Bildschirm.gibAus("Kontostand: "+dasKonto2.holeKontostand()); } else{ Bildschirm.gibAus("Die eingegebene PIN ist nicht gueltig."); } } while (!istAkzeptiert); Bildschirm.warteAufTastendruck(); }
363

364

Die Klasse Object


Die Klasse Object ist die Oberklasse aller Klassen, und stellt einige Methoden zur Verfgung:
public String toString() Die toString()-Methode gibt eine (etwas kryptische) Wandlung eines Objektes in einen String sie sollte von Klassen berdeckt werden Die System.out.println-Methode akzeptiert beliebige Objekte als argument, sie benutzt die (eventuell selbst berschriebene) toString()-Methode Strings knnen mit beliebigen Objekten durch den +-Operator verknpft werden. Dazu wird implizit von den Objekten die toString()-Methode aufgerufen, um die String-Darstellung zu erhalten
366

Kapitel 11.3
Object

Die Klasse Object


public boolean equals(Object obj)
Das Objekt wird mit dem Argument auf Gleichheit berprft In der Standardimplementierung wird nur die Referenz verglichen (also, ob es sich im dasselbe Objekt handelt) Eine neue Methode sollte die equals-Methode berdecken, um einen Inhaltlichen Vergleich zu ermglichen Beispiel: Fr einen Kunden soll abgefragt werden, ob er bereits Kunde ist. Fr den Vergleich spielt der Name, der Geburtsort und das Geburtsdatum eine Rolle, nicht jedoch die Adresse

Die Klasse Object


public Object clone()
returniert eine wertegleiche Kopie des Objektes. Hinweis: Wenn in dem zu klonenden Objekt Referenzen auf andere Objekte (z.B. Arrays) vorkommen, so werden die Referenzen geklont, nicht aber die referenzierten Objekte. Auf diese Weise kommt es zu shared data. Ob das beabsichtigt ist, muss sorgfltig geprft werden. Diskussion des Stack-Beispiels

public final Class getclass()


returniert das Objekt, das die Klasse des Objektes reprsentiert, dessen Methode aufgerufen wird.

367

368

Vererbung
Klassen knnen zueinander in einer "ist ein"-Beziehung stehen

Kapitel 12
hnliche Objekte (Vererbung)

Beispiel: aber:

Jeder PKW ist ein Kraftfahrzeug, jedes Kraftfahrzeug ist ein Transportmittel auch jeder LKW ist ein Kraftfahrzeug und jeder Zug, jedes Schiff und jedes Flugzeug ist ein Transportmittel Transportmittel Zug Boot Flugzeug

Kraftfahrzeug PKW VW Golf Opel Astra

LKW Segelbooot Motorboot


370

Vererbung (anschaulich)
Sowohl PKWs, als auch LKWs besitzen Fahrersitze und Fahrertren, es handelt sich also um Attribute der Oberklasse Kraftfahrzeug Sowohl PKWs als auch LKWs haben die Methoden Sitz verstellen, Tr schlieen und fahren, es sind Methoden der Oberklasse Kraftfahrzeug PKWs haben jedoch mit der Rckbank und dem Kofferraum eigene Attribute und mit "hinten einsteigen" eigene Methoden LKWs haben mit der Ladeflche und dem Anhnger auch eigene Attribute und "beladen" ist eine eigene Methode => Unterklassen PKWs und LKWs besitzen alle Attribute und Methoden der Oberklasse, haben jedoch noch zustzliche
371

hnlichkeiten bei Objekten

Vererbung

Und bei Konten tritt so was hnliches natrlich auch auf :-) Zusammenfassen von gleichen Attributen und Methoden
Girokonto kontostand : int inhaber : Person habenzinsen : int sollzinsen : int dispo : int holeKontostand() zahle() Sparkonto kontostand : int inhaber : Person habenzinsen : int holeKontostand() zahle() kuendigen() Festgeld kontostand : int inhaber : Person habenzinsen : int mindBetrag : int laufzeit : int holeKontostand() zahle() kuendigen()

372

Erweiterung des Klassenmodells


Konto
kontostand : int inhaber : Person habenzinsen : int holeKontostand() zahle()

Vererbung

Verhltnis zwischen Objekten erbender Klassen


Die vererbende Klasse heit Superklasse. Die erbenden Klassen sind Unter- oder Subklassen. Konto ist also die Superklasse der Klassen Girokonto, Festgeldkonto, Sparkonto. Diese sind die Subklassen der Klasse Konto.

Girokonto
sollzinsen : int dispo : int

Festgeldkonto Sparkonto
mindBetrag : int laufzeit : int kuendigen() kuendigen()
373 374

Verhltnis zwischen Objekten erbender Klassen


Alle Objekte sind Konten! Einige sind besondere Arten von Konten. Die Menge der Sparkonten, Girokonen, Festgeldkonten ist jeweils eine Teilmenge der Menge der Konten Die Teilmengen sind disjunkt.
Konto Sparkonto Girokonto

Verhltnis zwischen Objekten erbender Klassen


Wir nehmen folgende Deklarationen an:
Girokonto einGirokonto; Sparkonto einSparkonto; Konto einKonto, einAnderesKonto;
Sparkonto Girokonto

Konto

Legale Zuweisungen:
Festgeldkonto Festgeldkonto

einGirokonto = new Girokonto(); einSparkonto = new Sparkonto(); einGirokonto.sollzinsen = 12; einKonto = einGirokonto; einAnderesKonto = new Sparkonto();
375 376

Verhltnis zwischen Objekten erbender Klassen


Wir nehmen folgende Deklarationen an:
Girokonto einGirokonto; Sparkonto einSparkonto; Konto einKonto, einAnderesKonto;
Konto Sparkonto

Verhltnis zwischen Objekten erbender Klassen


Erluterungen: Jedes Sparkonto / Girokonto ist auch ein Konto, deshalb ist einKonto = einSparkonto legal. Ein Objekt der einer Klasse kann also mehrere Erscheinungsformen haben, es kann ein Objekt der Klasse selbst sein oder es kann ein Objekt einer der Unterklassen dieser Klasse sein. Es ist also polymorph.

Nicht legale Zuweisungen:


einSparkonto = einGirokonto; einGirokonto = new Sparkonto();

Girokonto Festgeldkonto

377

378

Verhltnis zwischen Objekten erbender Klassen


Erluterungen: Nicht jedes Konto ist ein Sparkonto. Ist dann einSparkonto = einKonto legal? Ja, denn Objekte der Klasse Sparkonto sind wandelbar zu Objekten der Klasse Konto. Allerdings ist der Zugriff auf alle Attribute nicht mglich, denn einKonto hat ja nicht die Sparkonto-Attribute.

Verhltnis zwischen Objekten erbender Klassen


Erluterungen: Was passiert bei folgender Anweisung? if (x%2 == 0) einKonto = einSparkonto; else einKonto = einGirokonto; Der Compiler ist nicht in der Lage, die Klasse von einKonto zu ermitteln. Die Klasse von einKonto nach dieser Zuweisung ist nicht vorhersehbar. einKonto kann also nach der Anweisung eine von mehreren Klassen haben, es ist halt polymorph.
379 380

Verhltnis zwischen Objekten erbender Klassen


Erluterungen: Ist
einKonto = (x%2==0 ? einGirokonto : einSparkonto)

Die Klasse Konto


public class Konto { private int kontostand = 0; private Waehrungsrechner wr; private Person inhaber; private int habenzinsen;

Vererbung

erlaubt?

public Konto (Person inhaber, Waehrungsrechner wr) { this.inhaber = inhaber; this.wr = wr; }

381

382

Die Klasse Konto

Vererbung

Die Klasse Girokonto


public class Girokonto extends Konto {

Vererbung

public void zahle (int pfennige) { int euroCent = wr.wandeleInEuroCent(pfennige); kontostand += euroCent; } public int holeKontostand() { int pfennige = wr.wandeleInPfennige(kontostand); return (pfennige); } } // Ende der Klasse Konto

private int sollzinsen; private int dispo; } // Ende der Klasse Girokonto

Schlsselwort: extends

383

384

Vererbung (technisch)
Vererbung wird ber Schsselwort extends realisiert:
class Unterklasse extends Oberklasse { ... // Hier zustzliche Attribute und Methoden }

Vererbung (technisch)
Jede Klasse hat genau eine Oberklasse (Java kennt keine Mehrfachvererbung) Ist keine Oberklasse definiert (kein extends), so ist die Systemklasse Object die Oberklasse => Object ist eine Oberklasse fr alle Klassen (bis auf Object selbst)

Die neu definierte Unterklasse erweitert also die anderswo definierte Oberklasse um neue Attribute und Methoden. Alle Methoden und Attribute der Oberklasse werden bernommen.
385 386

Vererbung (technisch)
Konstruktoren werden nicht vererbt, Konstruktoren der abgeleiteten Klasse mssen neu definiert werden! ber Schlsselwort super kann am Anfang eines Konstruktors der abgeleiteten Klasse ein Konstruktor der Oberklasse aufgerufen werden. Beispiel: class A {
A(String name) { ... } } class B extends A { B(String name, int a) { super(name); // Aufruf des Oberkl.... // Konstruktors } }
387

Vererbung (technisch)
Wenn in der ersten Anweisung des Subklassen-Konstruktors nicht einer der Konstruktoren der Superklasse aufgerufen wird, dann wird der parameterlose Superklassen-Konstruktor (Standard-Konstruktor) automatisch aufgerufen, bevor irgendeine andere Anweisung des Subklassen-Konstruktors aufgerufen wird. Die Verwendung von super ist die einzige Situation, in der die Quelle einer Referenz fr die Wahl der auszufhrenden Methode / den Zugriff auf ein Attribut verantwortlich ist.

388

Zugriffsrecht: protected

Vererbung

Zugriffsrecht: protected

Vererbung

private Methoden und Attribute sind nur in der Klasse zugreifbar, in der sie definiert sind. Sie sind nicht in den erbenden Klassen zugreifbar.
Oft ist es so, da Methoden und Attribute nicht von auen zugreifbar sein sollen, da sie aber schon vererbt werden sollen. Genau dies wird durch das Schlsselwort protected vereinbart.

protected Methoden und Attribute sind in der Klasse selbst und in allen Subklassen sichtbar.

Konto
habenzinsen ist hier unbekannt

private kontostand protected habenzinsen

benutzt
Bankautomat

erweitert
Girokonto

habenzinsen ist hier bekannt

389

390

Zugriffsrecht: protected

Vererbung

berschreiben von Methoden in Vererbungshierarchien Methode: berechneZinsen (int tage) gleiche Implementierung in Sparkonto und Festgeld aber: in Girokonto Berechnung aus Sollzinsen und Habenzinsen Lsung: Standard-Implementierung in Konto und berschreiben in Girokonto

protected Methoden und Attribute einer Oberklasse A knnen auch in einer Unterklasse B zur Oberklasse A zugreifbar, d.h. genau:
sie knnen benutzt werden ber eine Referenz auf ein Objekt der Klasse A oder auf ein Objekt einer Unterklasse der Klasse A.

391

392

berschreiben von Methoden


public class Konto { ...

Vererbung

berschreiben von Methoden

Vererbung

/** berechnet fr die Anzahl Tage die angefallenen Zinsen */ protected int berechneZinsen(int tage) { Float zinsen = new Float(kontostand*(habenzinsen/100)*(tage/360)); return (zinsen.intValue()); } Wrapper-Klasse: Float ... }
393

public class Girokonto extends Konto { ... protected int berechneZinsen(int tage) { int guthaben = holeKontostand(); if (guthaben > 0) { Float zinsen = new Float(guthaben*(habenzinsen/100)*(tage/360)); return (zinsen.intValue()); } else { Float zinsen = new Float(guthaben*(sollzinsen/100)*(tage/360)); return (zinsen.intValue()); } } 394 }

Zugriff auf berschriebene Attribute / Methoden


In einem Objekt einer abgeleiteten Klasse ist super eine Referenz auf das Teilobjekt der Oberklasse Attribute und Methoden der Oberklasse lassen sich so ansprechen (auch berschriebene Attribute und Methoden) Beispiel:
class A { int variable; void methode() { ... } } class B extends A { int variable; // berschreibendes Attr. void methode() { // berschreibende Meth. ... } void methode2() { // Zugriff auf super.variable = 3; // berschriebene super.methode(); // Attribute und } // Methoden der } // Oberklasse
395

Schlsselwort: final
Verhindert, da eine Methode berschrieben wird
public final int holeKontostand() { ... }

Vererbung

Erben von einer Klasse verbieten


public final class Girokonto extends Konto { ... }

Alle Methoden und Attribute einer finalen Klasse sind implizit auch final.

396

Schlsselwort: final

Vererbung

Einschub: Klasse Datum (wird gleich bentigt)


public class Datum { public Datum(int tag, int monat, int jahr) { ...} public void setzeDatum(int tag, int monat, int jahr) public static Datum aktuellesDatum() { ... } { ... }

Finale Klassen und Methoden sind aus Sicherheitsgrnden zuweilen erforderlich. Sie tun das, was sie tun sollen und knnen nicht manipuliert werden. Typische Anweisung: eine Methode zur Passwort-Prfung.

final - Attribute sind Konstanten, sie drfen nicht verndert werden


public final int mwst;

public boolean istSpaeterAls(Datum dat) { ...} public boolean istAbgelaufen() { ...} public boolean istGleich (Datum dat) public int gibDifferenz(Datum dat)
397

{ ...}

{ ...}
398

Abstrakte Methoden/Klassen

Vererbung

Abstrakte Methoden/Klassen
public abstract class Konto { protected Datum letzteTransaktion; ...

Vererbung Schlsselwort: abstract vor Methode und Klasse

Situation: Jede Subklasse hat die gleiche Methode aber unterschiedliche Implementierung Beispiel: auszahlen(int betrag)
Girokonto: beliebige Auszahlung bis Limit Sparkonto: Restguthaben von DM 5,- ntig (auer nach Kndigung) Festgeld: Auszahlung erst nach Ende der Laufzeit

Lsung: abstrakte Methode in der Superklasse. Eine abstrakte Methode ist eine Methode, die nicht realisiert ist. Die abstrakte Methode der Superklasse gibt dann nur die Signatur der Methode an, nicht aber ihre Realisierung.
399

public void einzahlen(int betrag) { Datum heute = Datum.aktuellesDatum(); int zinstage = heute.gibDifferenz(letzteTransaktion); int zinsen = berechneZinsen(zinstage); zahle(betrag+zinsen); } public abstract int auszahlen(int betrag); }
400

Beispiel: Klasse Girokonto

Vererbung

Abstrakte Methoden/Klassen

Vererbung

class Girokonto extends Konto { ... public int auszahlen(int betrag) { Datum heute = Datum.aktuellesDatum(); int zinstage = heute.gibDifferenz(letzteTransaktion); int zinsen = berechneZinsen(zinstage); zahle(zinsen); if (kontostand-betrag > dispo) { zahle(-betrag); return (betrag); } else Bildschirm.gibAus(Kein Auszahlen mglich); return (0); } }
401

Enthlt eine Klasse eine abstrakte Methode, so ist die ganze Klasse abstract Eine abstrakte Klasse kann nicht instanziiert werden. D.h., es knnen keine Objekte zu dieser Klasse erzeugt werden. Es kann nur Objekte zu den nicht abstrakten Unterklassen geben. Abstrakte Methoden mssen in den Subklassen implementiert werden (oder die Subklassen sind wieder abstract)

402

Polymorphie
Wunsch: Alle Objekte aus der Oberklasse Konto sollen in der gleichen Weise behandelt werden knnen. Lsung: Polymorphie Eine Oberklassen-Referenz kann auch auf Objekte der Subklassen verweisen. Methoden der Oberklasse knnen so aufgerufen werden. Wurde eine Methode von einer Subklasse berschrieben, so wird nicht die Methodenimplementierung der Oberklasse aufgerufen, sondern die Implementierung der Subklasse.
403

Polymorphie

Vererbung

Methoden knnen so mit allen mglichen Konten arbeiten


public int berechneVermoegen(Konto[] konten) { int vermoegen = 0; for (int i=0; i<konten.length; i++) { Konto k = konten[i]; vermoegen += k.holeKontostand(); } return (vermoegen); }

Methodenaufruf wird an die entsprechende Subklasse weitergeleitet

404

Polymorphie (technisch)
Polymorphie wird bei Vererbung durch berschreiben der Methoden der Oberklasse erreicht, dabei mu die Signatur (also Parameterliste und Rckgabetyp) mit der Methode der Oberklasse bereinstimmen. Beim berschreiben werden die allgemeineren Methoden (der Oberklasse) durch die konkreteren der Unterklasse berschrieben.

Polymorphie (technisch)
Auch wenn ein Objekt durch eine Variable eines allgemeineren Typs referenziert wird, so werden immer die zum Objekt gehrenden Methoden aufgerufen. berschreiben darf nicht mit berladen verwechselt werden, bei berladenen Methoden hat man unterschiedliche Signaturen und nur der Methodenname ist der gleiche.

405

406

Instanceof
Da jedes Objekt auch ber Referenzen der Oberklasse angesprochen werden kann, ist nicht immer klar, zu welcher Klasse ein Objekt gehrt. Daher gibt es das Schlsselwort instanceof, um die Klassenzugehrigkeit zu bestimmen:

bung: Vererbung
Motivation
Vererben von Attributen und Methoden berschreiben von Methoden

Vererbung

Aufgabe
Nutzen Sie die Gemeinsamkeiten von Girokonto, Sparkonto und Festgeldkonto in der gemeinsamen Oberklasse Konto. Implementieren Sie die Klasse Festgeldkonto als Erweiterung der Klasse Konto neue Attribute: laufzeit und mindBetrag neue Methoden: erweiterter Konstruktor : bergeben der Laufzeit auszahlen(int betrag) : Auszahlung der Summe nach Ende der Laufzeit kuendigen() : identisch mit auszahlen

if(Objektname instanceof Klassenname) Anweisung


Die Abfrage liefert auch dann true, wenn durch Klassenname eine Oberklasse fr das zu Objektname zugehrige Objekt angegeben wird
407

Schreiben Sie eine Testklasse


benutzen Sie die Methode setzeDatum der Klasse Datum, um die letzteTransaktion zurckzusetzen

408

bung: Vererbung

Vererbung

bung: Vererbung
public Festgeld (Person inhaber, Waehrungsrechner wr) { super(inhaber, wr); } public Festgeld (Person inhaber, Waehrungsrechner wr, int initialkontostand, int laufzeit) { super(inhaber, wr, initialkontostand); this.laufzeit = laufzeit; if (initialkontostand < mindBetrag) { Bildschirm.gibAus("Mindest-Betrag wird nicht erreicht"); } }

Vererbung

public class Festgeld extends Konto { private int laufzeit = 1080; // Laufzeit: 3 Jahre public static int mindBetrag = 250000; public Festgeld (Person inhaber, Waehrungsrechner wr, int initialkontostand) { super(inhaber, wr, initialkontostand); if (initialkontostand < mindBetrag) { Bildschirm.gibAus("Mindest-Betrag wird nicht erreicht"); } }

409

410

bung: Vererbung
public void setzeLaufzeit (int neueLaufzeit) { this.laufzeit = neueLaufzeit; } public int kuendigen () { return (auszahlen(holeKontostand())); }

Vererbung

public int auszahlen (int betrag) { if (betrag == holeKontostand()) { Datum heute = Datum.aktuellesDatum(); int abgelaufeneZeit = heute.gibDifferenz(letzteTransaktion); if (abgelaufeneZeit >= this.laufzeit) { int zinsen = holeWaehrungsrechner().wandeleInPfennig (berechneZinsen(laufzeit)); int pfennige = holeKontostand()+zinsen; zahle(-betrag); return (pfennige); } else { Bildschirm.gibAus("Laufzeit noch nicht errreicht"); } } else { Bildschirm.gibAus(Auszahlung der ges. Summe ntig"); } }
412

411

Zusammenfassung
Finden hnlicher Objekte
Vererbungsbeziehung

Vererbung

Zugriffsrecht: protected berschreiben von Methoden


Schlsselwort: final

Kapitel 13
Schnittstellen (Interfaces) vgl. Kapitel zu Interfaces aus Ken Arnold, James Gosling, The Java Programming Language, Second Edition, Addison-Wesley

Abstrakte Methoden Polymorphie


413

Motivation
Interfaces sind Klassen ohne Methodenimplementierungen. Interfaces werden auch Schnittstellen genannt. Im Doberkat/Dimann-Buch werden sie Abstraktionen genannt. Grundlegende Motivation:
Trennung Spezifikation / Realisierung Ermglichung von Mehrfacherbung

Motivation: Trennung Spezifikation / Realisierung


Realisierung ist noch nicht bekannt, aber man wei schon, was realisiert werden soll. Man will mehrere auch konkurrierende Realisierungen zulassen und dabei sicherstellen, da gewisse Eigenschaften gewhrleistet werden. Die grundlegenden Eigenschaften werden durch Signaturen festgelegt. Die Signatur einer Methode legt ihr Eingabe/Ausgabeverhalten fest, also die Typen der Eingabeparameter und den Rckgabewert.

415

416

Erluterung Signatur
NatSig = (S, F) mit S={Nat, Bool} F={0Nat, succNat, +Nat, =Nat} type: F S* x S 0Nat () x Nat oder 0Nat:() Nat succNat Nat x Nat oder succNat : Nat Nat +Nat Nat x Nat x Nat oder +Nat : Nat x Nat Nat =Nat Nat x Nat x Bool oder =Nat : Nat x Nat Bool true Bool () x Bool oder true Bool :() Bool false Bool () x Bool oder false Bool :() Bool =bool Bool x Bool x Bool oder =bool : Bool x Bool Bool 1Nat () x Nat oder 1Nat:() Nat
417

Motivation: Mehrfacherbung
Mehrfacherbung (multiple inheritance) = eine Klasse besitzt mehrere Oberklassen
KFZ Inventar

Signatur der Algebra der natrlichen Zahlen

Leihwagen

Problem: Lsung: aber:

Welche Methode wird bei Namenskonflikten gewhlt? In Java nicht mglich! hilfreiches Ersatzkonstrukt verfgbar: Interface
418

Interfaces
Bsp: Lookup und Verwendung der Lookup-Typen
interface I { Methodendeklarationen; }

Interfaces
Klassen knnen von einem oder mehreren Interfaces und auch zustzlich von einer Oberklasse erben:
class NameUnterklasse extends NameOberklasse implements Interface1, Interface2, ... { ... }

extends ist das Schlsselwort fr Interfacevererbung:


interface Unterinterface extends Oberinterface { Interfacebody }

Klassen erben von Interfaces ber das Schlsselwort implements Bsp: SimpleLookup
419

Werden von einer Klasse nicht alle Methoden des Interfaces implementiert, mu sie mit abstract gekennzeichnet werden Analog zum Erben von Oberklassen ist Polymorphie mglich
420

Interfaces
Die Supertypen einer Klasse A sind die Klasse B, von der A erbt, die Interfaces, die A implementiert, und die Supertypen, dieser Klasse und Interfaces. Alle Interface-Methoden sind implizit public und abstract.
Begrndung: public weil alle realisierenden Klassen wissen mssen, was sie realisieren sollen, abstract weil das das Merkmal von Interfaces ist.

Abstrakte Klasse versus Interface


Eine Klasse ist abstrakt, wenn mindestens eine ihrer Methoden abstrakt ist. Insofern ist ein Interface ein Spezialfall einer abstrakten Klasse. Ein Interface hat halt ausschlielich abstrakte Methoden. Der Vorteil im Hinblick auf Mehrfacherbung ist, da es ohne Implementierungen bezglich Methoden auch keine Konflikte geben kann.
public interface Konto { public void einzahlen(); public void auszahlen(); ... }

Alle Attribute sind implizit public, static und final


Begrndung: Es kann nur um Konstanten gehen, die immer gleich verwendet werden (also final). Diese braucht man dann nicht pro Objekt, sondern nur pro Klasse (also static).
421

422

Interfaces
Interface wird durch Klasse implementiert
public class Privatkonto implements Konto { public void einzahlen() { ... } public void auszahlen() { ... } } modifier class cName implements iName { ... }

Interfaces
Interfaces knnen eigene Vererbungshierarchie bilden fr Interfaces ist Mehrfacherbung erlaubt:
public interface Konto extends Vertrag, Historisierbar { public void einzahlen() { ... } public void auszahlen() { ... } }

interface I extends I1,I2 { Methodendeklarationen; }

423

424

Interfaces
eine Klasse kann mehrere Interfaces implementieren
alle vorgegebenen Methoden mssen realisiert werden

Mehrfacherbung
Mit Interfaces lt sich Mehrfacherbung erreichen

Klasse A Klasse B

Interface

public class Privatkonto implements Konto, Zhler { public void einzahlen() { ... } public void auszahlen() { ... } public int inkrementiere() { ... } }

public class SubName extends SuperName implements InterfaceName, ..., InterfaceName { ...

class C implements I1,I2 { ... }

Klasse C

Lsung: Implementierung eines Interfaces

Klasse A

Interface I

Klasse C
425 426

Interfaces
Interface kann als Typ fr eine Referenz dienen, d.h. Interfaces untersttzen polymorphes Verhalten wie Oberklassen.
Girokonto dasGiro = new Girokonto(); Konto kto = dasGiro; kto.einzahlen(500); Das durch kto referenzierte Objekt bestimmt die Methode, die ausgefhrt wird!

Interfaces

interface W {} interface X extends W {} class Y implements W {} class Z extends Y implements X

{}

W X Z
427 428

Interfaces

Interfaces
Namenskonflikte beim Realisieren mehrerer Interfaces:

interface W {} interface X extends W {} interface Y extends W {} class Z implements X, Y {}

Was passiert, wenn eine Methode mit dem gleichen Namen in zwei zu realisierenden Interfaces vorkommt? 1. Fall: berladen 2. Fall: eine Realisierung 3. Fall: unlsbarer Konflikt (gleiche Parameter, unterschiedliche Rckgabetypen)

W X Z Y

Was passiert bei gleichnamigen Attributen? Referenzierung ber InterfaceName.Attribute


429 430

Interfaces
Interfaces haben keine ausgezeichnete Wurzel, von der alle Interfaces erben (anders als Klassen, die alle von Object erben). Dennoch knnen Ausdrcke eines beliebigen Interface-Typen an eine Referenz auf ein Objekt der Klasse Object zugewiesen werden, denn ein Objekt, das ein Interface implementiert ist halt irgendein Objekt und damit auch vom Typ Object.

Garantieren von Methoden


Trennung von Deklaration und Implementierung
Deklaration

Interface

public interface Konto { public void einZahlen(); public void ausZahlen(); ... }

public interface iName { Methodendeklarationen; } Interfaces knnen von anderen Interfaces erben (extends)

431

432

Garantieren von Methoden


Trennung von Deklaration und Implementierung
Implementierung

Interface

Interfaces versus abstrakte Klassen


Interfaces erlauben eine Art Mehrfacherbung. Eine Klasse kann nur von einer anderen Klasse erben, selbst dann wenn die vererbende Klasse nur abstrakte Methoden hat.

public class Girokonto implements Konto { public void einZahlen() { ... } public void ausZahlen() { ... } }

public class cName implements iName { } Klassen knnen mehrere Interfaces implementieren (implements i1, i2, ...)

Eine abstrakte Klasse kann teilweise implementiert sein, sie kann ber protected Attribute, static Methoden usw. verfgen. Interfaces knnen nur public Konstanten und Methoden ohne Realisierungen beinhalten. Tipp: Jede grundlegende Klasse, von der geerbt wird, sollte die Implementierung eines Interface sein! Nur dann knnen andere Klassen (die schon erben) von der allgemeinen Festlegung profitieren.

433

434

Ausnahmen - Wieso eigentlich?


(Etwas naive) Annahme:

Kapitel 14
Ausnahmen (Exceptions)

Algorithmen sind so entworfen, da alle denkbaren Zustnde behandelt werden. Ungewollte Terminierungen (Abstrze) knnen deshalb gar nicht vorkommen.
Beispiel: beim Einfgen eines Elementes in eine Liste werden alle denkbaren Flle (Einfgen in leere Liste, Einfgen vor erstem Listenelement, Einfgen zwischen Listenelemente, Einfgen hinter dem letzten Listenelement) unterschieden und korrekt behandelt.

Wozu also Ausnahmen?


436

Ausnahmen - Wieso eigentlich?


Das Ende der Naivitt: Algorithmen werden durch das Zusammenwirken von Objekten realisiert. Objekte entscheiden autonom ber die Ausfhrung von Methoden, knnen dabei aber nicht den Gesamtzustand des Systems bercksichtigen. Wenn eine Ausfhrung nicht erfolgen kann, dann erfolgt eine Ausnahme, die entsprechend behandelt werden kann (und mu). Viele Objekte mit internen Zustnden fhren zu einer Zustandsexplosion, so da es nicht mehr handhabbar ist, alle Zustnde explizit zu unterscheiden.
437

Ausnahmen - Wieso eigentlich?


Und noch ein pragmatischer Grund: Selbst wenn es in kleineren Programmen mglich ist, alle Ausfhrungen abzufragen und deshalb auch ohne Ausnahmen auszukommen, so wird durch die ganze Fallunterscheiderei der eigentlich Algorithmus verschleiert. Das Konzept der Ausnahmebehandlung wirkt dem entgegen, indem der eigentliche Algorithmus von der Ausnahmebehandlung getrennt wird.

438

bersicht ber dieses Kapitel


Was sind Ausnahmen? / Grundidee der Ausnahmebehandlung
Die Klasse java.lang.Exception

Was sind Ausnahmen?


Ausnahmen knnen im Programmablauf auftreten
Division durch Null Datei nicht vorhanden ...

Werfen von Exceptions Weiterleiten von Exceptions Fangen von Exceptions Die Klassen Exception, Error, RuntimeException

Ziel ist aber: Erstellen eines stabilen Programms Ausnahme: Zustand, der das Programm daran hindert, im normalen Ablauf fortzufahren Trennung von Fehlerbehandlungscode und regulrem Code Es kann leichter sein, Ausnahmen eintreten zu lassen und sie ordentlich zu behandeln als sie unbedingt zu vermeiden.
439 440

Grundidee der Ausnahmebehandlung


Es gibt vordefinierte Ausnahmen, diese knnen erweitert werden. In der Definition von Methoden wird definiert, welche Ausnahmen auftreten knnen. Beim Aufruf von Methoden wird definiert, wie die mglicherweise auftretenden Methoden behandelt werden. Hierzu wird der potentiell Ausnahmen verursachende Code in einen try{...}-Block eingebettet.

Grundidee der Ausnahmebehandlung


Wenn im try{...}-Block Ausnahmen auftreten, werden sie gefangen. Was dann passiert, wird im catch{...}-Block festgelegt. Nach dem Fangen und Verarbeiten wird im finally{...}Block definiert, was zum Abschlu der Ausnahmebehandlung passiert. Und nun erst mal ein Beispiel!

441

442

Die Klasse java.lang.Exception


public class Exception ... { public Exception() {..}; public Exception(String s) {...}; // und von java.lang.Throwable geerbt: // Kurzbeschreibung des Fehlers public String toString() {...}; // Details des Fehlers public String getMessage() {...}; // Details mit Aufrufstack public String printStackTrace() {...}; ... }
443

Werfen von Ausnahmen


... if (kontostand-betrag > dispo) { zahle(-betrag); return (betrag); } else throw new Exception(); ...

throw new Exception (); throw new Exception(Text);

444

Definition des Werfens von Ausnahmen in Methoden


Modifier Rckgabetyp Methodenname (...) throws Exception {

Definition des Werfens von Ausnahmen in Methoden Die Ausnahmen, die geworfen werden knnen, mssen deklariert werden, weil Programmierer, die Methonden aufrufen, das Ausnahmeverhalten genauso kennen mssen wie das normale Verhalten (Signatur). Die in der Methodendefinition deklarierten Ausnahmen werden auch checked Ausnahmen genannt (im Unterschied zu den nicht explizit deklarierten und vom Compiler nicht explizit geprften Laufzeitausnahmen).

public int auszahlen(int betrag) throws Exception { Datum heute = Datum.aktuellesDatum(); int zinstage = heute.gibDifferenz(letzteTransaktion); int zinsen = berechneZinsen(zinstage); zahle(zinsen); if (kontostand-betrag > dispo) { zahle(-betrag); return (betrag); } else throw new Exception(Konto nicht gedeckt); }
445

446

Definition des Werfens von Ausnahmen in Methoden Das heit: RuntimeException (z.B. ClassCastException, ArithmeticException) werden nicht explizit deklariert. Sie knnen von jeder Methode geworfen werden und werden deshalb auch nicht vom Compiler berprft (sie bleiben unchecked), d.h. Exceptions der Klassen java.lang.Error und java.lang.RuntimeException und deren Unterklassen mssen nicht in der throws-Deklaration gekennzeichnet werden.

Aufrufen von Methoden, die Ausnahmen werfen


Beim Aufruf einer Methode, die in ihrer throws-Anweisung Ausnahmen auflistet, bleiben drei Mglichkeiten:
Fangen und Behandeln Fangen, Abbilden auf eigene Ausnahme, Werfen der eigenen Ausnahme Deklarieren der Ausnahme in der aufrufenden Methode und dann Fangen und Weiterleiten der Ausnahme

Immer dabei: Fangen von Ausnahmen!

447

448

Fangen von Ausnahmen


Mit try und catch werden Exceptions aufgefangen
try-Block: catch-Block: finally-Block: Bereich, in dem Ausnahmen auftreten knnen Bereich, in dem die Fehlerbehandlung stattfindet optional, wenn vorhanden, wird er auf jeden Fall ausgefhrt

Fangen von Ausnahmen


try { statements } catch (exception_type1 identifier1) { statements } catch (exception_type2 identifier2) { statements .... } finally { statements }

Mehrere catchBlcke!

... Konto k = new Konto(); Werfen try { k.auszahlen(10000); Fangen } catch (Exception e) { Bildschirm.gibAus(e.getMessage()); } finally { Aufrumen Bildschirm.gibAus(k.holeKontostand()); } 449

450

Verarbeiten von Ausnahmen


Der Rumpf des try-Blockes wird ausgefhrt bis eine Ausnahme auftritt oder bis zum Ende (falls keine Ausnahme auftritt). Wenn eine Ausnahme auftritt wird jeder catch-Block geprft (von oben nach unten), um diejenigen catch-Blcke zu finden, die die Ausnahme fangen knnen. Es drfen keine Ausnahmen gefangen werden, die im try-Block nicht auftreten knnen. Fr einen passenden catch-Block wird der Identifier auf das aufgetretene Exception-Objekt gesetzt. Kein weiterer catchBlock wird ausgefhrt (also nur der erste passende!). Es mu also darauf geachtet werden, da die catch-Blcke unterschiedliche Ausnahmen fangen.
451

Verarbeiten von Ausnahmen


Wenn kein passender catch-Block gefunden wird, sickert die Ausnahme in weiter auen liegende try-Blcke durch. Wenn ein finally-Block vorkommt, dann wird er ausgefhrt, nachdem der try-Block abgearbeitet ist (entweder durch normale Beendigung, Ausnahme oder return/break). Ein finally-Block ist sinnvoll, um notwendige Resourcen freizugeben (z. B. Schlieen einer Datei), denn der Programmcode auerhalb des try-Blocks wird nicht mehr erreicht, falls innerhalb eines catch-Blocks wieder eine Ausnahme geworfen wird.
452

Ausnahmebehandlung
Ausnahmen knnen auftreten durch explizite throw-Anweisung Aufruf einer Methode mit throws- Deklaration

Ausnahmebehandlung

Auffangen und Weiterwerfen (throw im catch-Block) ist sinnvoll, um wichtige Zusatzinformationen anzuhngen Kann in einer Methode eine Ausnahme auftreten, mu sie
entweder durch try und catch aufgefangen werden oder durch throws in der Methodendeklaration weitergeleitet werden

453

454

Exception, Error, RuntimeException


Exception:
nicht fr ernsthafte, kritische Fehler Einsatz als Feature im Programmablauf

Schreiben eigener Ausnahmen


Neue Klasse wird von java.lang.Exception abgeleitet :
public class KeineDeckungException extends Exception { public KeineDeckungException() { super(); } public KeineDeckungException(String s) { super(s); } }
455 456

Error:
Schwerwiegende Fehler der Virtual Machine Sollten nicht selbst geworfen oder aufgefangen werden

RuntimeException
Systemfehler, die nicht deklariert werden mssen Beispiel: Teilung durch Null (0)

Benutzen eigener Ausnahmen


public class Girokonto extends Konto { ... public int auszahlen(int betrag) throws KeineDeckungException { ... if (kontostand-betrag > dispo) { zahle(-betrag); return (betrag); } else throw new KeineDeckungException(Konto nicht gedeckt); } }

bung: Behandlung von Ausnahmen


Motivation Schreiben eigener Ausnahmen Benutzen von Ausnahmen Aufgabe Identifizieren Sie zwei weitere Ausnahmen und schreiben Sie jeweils eine neue Klasse fr diese Ausnahme Erweitern Sie das Programm so, da diese Exceptions geworfen, weitergeleitet und gefangen werden Testen Sie die genderten Klassen mit der der Klasse TestKartenverwaltung. Verursachen Sie dabei absichtlich Fehler.

Auffangen der Exception:

try { k.auszahlen(1000); } catch (KeineDeckungException e) { Bildschirm.gibAus(e.getMessage()); }


457

458

bung: Behandlung von Ausnahmen


public class KontoNichtVorhandenException extends Exception { public KontoNichtVorhandenException () { super(); } public KontoNichtVorhandenException (String s) { super(s); } }

Exceptions

bung: Behandlung von Ausnahmen


public class Kartenverwaltung { ...

Exceptions

public class LaufzeitNichtErreichtException extends Exception { public LaufzeitNichtErreichtException () { super(); } public LaufzeitNichtErreichtException (String s) { super(s); } }
459

public Konto holeKonto (String kartennummer) throws KontoNichtVorhandenException { Konto dasKonto = null; for (int i=0; i<freiIndex; i++){ if (kartennummer.equals(kartennr[i])){ dasKonto = konten[i]; } } if (dasKonto == null) throw new KontoNichtVorhandenException(); return (dasKonto); } ... }
460

bung: Behandlung von Ausnahmen


public class TestKartenverwaltung { public static void main (String[] args) { Waehrungsrechner rechner = new Waehrungsrechner();

Exceptions

bung: Behandlung von Ausnahmen

Exceptions

Person inhaber = new Person(Urs, Mller, Hauptstr. 1,

12345, Berlin); Girokonto k = new Girokonto(inhaber, rechner, 100); Festgeld f = new Festgeld(inhaber, rechner, 100000); Kartenverwaltung verwaltung = new Kartenverwaltung(); verwaltung.erfasseWeiteresKonto("1", 1234", k); verwaltung.erfasseWeiteresKonto(2", 5678", f); try { Festgeld geld = (Festgeld) verwaltung.holeKonto(2); geld.kuendigen(); } catch (LaufzeitNichtErreichtException e) { Bildschirm.gibAus(e.getMessage()); }
461

try { Girokonto gKonto = (Girokonto) verwaltung.holeKonto("1); gKonto.auszahlen(1000); } catch (KontoNichtVorhandenException e1) { Bildschirm.gibAus(e1.getMessage()); } catch (KeineDeckungException e2) { Bildschirm.gibAus(Konto ist nicht gedeckt); } ... }

462

Pakete, Verkapselung, Zugriffskontrolle


Pakete, Verkapselung und Zugriffskontrollmechanismen sind Mglichkeiten, Programme besser zu strukturieren => Diese Mechanismen sind eine Grundvoraussetzung fr eine erfolgreiche Programmierung im Team berlegungen der Grobstrukturierung sollten vor dem Projektstart gemacht werden, und nicht nachher Modellierungssprachen wie UML knnen hier die Planung erheblich erleichtern, denn je grer das Software-Projekt ist desto wichtiger ist eine grndliche Planung

Kapitel 15
Pakete und Zugriffskontrolle

464

Pakete
Durch package Packagename; wird ein neuer Namensraum als Paket zusammengefat Die package-Anweisung ist die erste Anweisung der Datei Zugehrige CLASS-Files stehen in einem Unterverzeichnes mit dem Namen Packagename, dessen Wurzel befindet sich in einem Verzeichnis, welches im CLASSPATH aufgenommen ist. Packages knnen auch Unter-Packages haben, analog zu Unterverzeichnissen im Dateisystem

Pakete
Pakete werden in der Regel durch eine Abbildung der PaketeStruktur auf das Dateisystem realisiert Unter-Pakete werden mit package Hauptpackagename.Unterpackagename; definiert Klassen aus anderen Paketen werden durch Packagename.Klassenname angesprochen

465

466

Pakete
Beispiel: Durch import Packagename.Klassenname; wird eine Klasse aus einem anderen Pakete bekannt gemacht. Sie kann dann wie eine lokal definierte Klasse ohne Angabe des Paketnamens benutzt werden. Mit import Packagename.*; werden alle Klassen im entsprechenden Paket bekanntgemacht import java.lang.*; wird immer ausgefhrt und mu nicht explizit angegeben werden
467

Pakete

Anlegen eines Wurzelverzeichnisses fr ein Projekt, hier C:\projekt (bzw. ~/projekt in UNIX). und Wechsel in dieses Unterverzeichnis (cd projekt). Fr Pakete mssen Unterverzeichnisse angelegt werden. Hier: "md utils" und "md hauptpackage". Java-Files fr die einzelnen Pakete mssen in den entsprechenden Unterverzeichnissen editiert werden. Hier: Datum.java im Verzeichnis utils und Startklasse.java im Verzeichnis hauptpackage.

468

Pakete
Datei Datum.java im Verzeichnis utils: package utils; class Datum() { int tag, monat, jahr; ... // nun die Methoden } Datei Startklasse.java im Verzeichnis hauptpackage:
package hauptpackage; import utils.*; class Startklasse { public static void main(String[] args) { Datum d = new Datum(); ... } }

Pakete

Zusammenfassung von Klassen

Zum Compilieren Angabe der Hauptdatei vom Wurzelverzeichnis aus.


javac hauptpackage/Startklasse.java

Pakete sind Sammlungen von Klassen und Interfaces


package demo; public class A { ... } Definition package PackageName; oder package PackgaeName.SubPackageName;

Abhngige Klassen werden (falls nicht schon geschehen) mit compiliert. Zum Ausfhren Angabe der zu startenden Klasse innerhalb der Paket-Hierarchie. Unterpakete werden durch Punkt gekennzeichnet:
java hauptpackage.Startklasse

Aufruf import demo.*; import demo.windows.* import Package.Klasse; import Package.*;

Ohne Angabe von import utils.* mte die Klasse Datum ber das Paket angesprochen werden:
utils.Datum d = new utils.Datum();
469

470

Zugriffskontrolle fr Klassen
Beispiel:

Zugriffskontrolle fr Klassen
package A; public class Test1 { } package A; class Test2 { } package A; class Haupt1 { void methode() { // beides erlaubt: Test1 t1 = new Test1(); Test2 t2 = new Test2(); } }
471

Klassen knnen standardmig nur auf andere Klassen aus dem gleichen Package zugreifen. Mit Hilfe der Zugriffsspezifikation public kann die Klasse auch nach auen sichtbar gemacht werden, also auch ber Paketgrenzen hinaus!

package B; import A.*; class Haupt2 { void methode() { // erlaubt: Test1 t1 = new Test1(); // nicht erlaubt: Test2 t2 = new Test2(); } }

public class Klassenname { ... }

472

bersicht Zugriffsrechte

Zusammenfassung von Klassen

Zugriffskontrolle fr Attribute / Methoden


Methoden und Attribute einer Klasse knnen optional eine der Sichtbarkeitsmodifikationen public, protected oder private erhalten. Ist nichts spezifiziert, gilt das Zugriffsrecht package Attribute sollten immer als private definiert werden. Der Zugriff auf die Attributwerte wird dann nur ber set- und getMethoden erlaubt.

Alle Zugriffsrechte in Java im berblick


Zugriff auf
Gleiche Klasse Klasse im gleichen Paket Subklasse im fremden Paket Keine Subklasse, fremdes Paket

public
Ja Ja Ja Ja

protected
Ja Ja Ja / Nein Nein

package private
Ja Ja Nein Nein Ja Nein Nein nein

473

474

Zugriffskontrolle fr Attribute / Methoden


public heit, das Attribut bzw. die Methode ist fr jeden sichtbar. protected heit, das Attribut bzw. die Methode ist innerhalb des Packages und in abgeleiteten Klassen sichtbar. Die Sichtbarkeit in abgeleiteten Klassen ist aber nur dann gegeben, wenn die Referenz auf das abgeleitete Objekt, von dem aus das protected-Attribut angesprochen werden soll, nicht eine Referenz vom Typ der Oberklasse ist. private heit, das Attribut bzw. die Methode ist nur innerhalb der Klasse sichtbar
475

Zugriffskontrolle fr Attribute / Methoden


Ohne Spezifikation kann man innerhalb des Packages auf Attribute bzw. Methoden zugreifen. Ist die Klasse nicht als public deklariert, kann auerhalb des Packages auch nicht auf Methoden oder Attribute zugegriffen werden, die als public deklariert sind.

476

Zugriffskontrolle fr Attribute / Methoden


Beispiel:
package A; public class ZugriffsTest { private int priv; protected int prot; public int pub; int pack; private void privMethode() { } protected void protMethode() { } public void pubMethode() { } void packMethode() { } public void test( ZugriffsTest z) { // Alle Zugriffe erlaubt priv = 1; z.priv = 1; prot = 1; z.prot = 1; pub = 1; z.pub = 1; pack = 1; z.pack = 1; privMethode(); protMethode(); pubMethode(); packMethode(); z.privMethode(); z.protMethode(); z.pubMethode(); z.packMethode(); } }
477

Zugriffskontrolle fr Attribute / Methoden


Beispiel: ZugriffsTest2 im gleichen Package wie Zugriffstest
package A; public class ZugriffsTest2 { public static void main(String[] args) { ZugriffsTest t = new ZugriffsTest(); t.priv = 1; t.prot = 1; t.pub = 1; t.pack = 1; // // // // n. erlaubt erlaubt erlaubt erlaubt
478

// nicht erlaubt: t.privMethode(); // erlaubt: t.protMethode(); t.pubMethode(); t.packMethode(); } }

Zugriffskontrolle fr Attribute / Methoden


Beispiel: ZugriffsTest3 abgeleitet von ZugriffsTest und im gleichen Package wie ZugriffsTest
package A; public class ZugriffsTest3 extends ZugriffsTest { public static void main(String[] args) { ZugriffsTest3 t = new ZugriffsTest3(); t.priv = 1; t.prot = 1; t.pub = 1; t.pack = 1; // // // // n. erlaubt erlaubt erlaubt erlaubt t.privMethode(); t.protMethode(); t.pubMethode(); t.packMethode(); // // // // n.e. erl. erl. erl.

Zugriffskontrolle fr Attribute / Methoden


Beispiel: ZugriffsTest4 abgeleitet von ZugriffsTest und nicht im gleichen Package wie ZugriffsTest
package B; import A.*; public class ZugriffsTest4 extends ZugriffsTest { public static void main(String[] args) { Zugriffstest4 t = new ZugriffsTest4(); t.priv = 1; // n. erlaubt t.prot = 1; // erlaubt t.pub = 1; // erlaubt t.pack = 1; // n.erlaubt t.privMethode(); t.protMethode(); t.pubMethode(); t.packMethode(); // // // // n.e. erl. erl. n.e.

} void test3 () { priv = 1; // n. erlaubt prot = 1; // erlaubt pub = 1; // erlaubt pack = 1; // erlaubt privMethode(); // n.e. protMethode(); // erl. pubMethode(); // erl. packMethode(); // erl. } }
479

} void test4 () { priv = 1; // n. erlaubt prot = 1; // erlaubt pub = 1; // erlaubt pack = 1; // n. erlaubt privMethode(); // n.e. protMethode(); // erl. pubMethode(); // erl. packMethode(); // n.e. } }
480

Zugriffskontrolle fr Attribute / Methoden


Beispiel: ZugriffsTest5 abgeleitet von Zugriffstest und nicht im gleichen Package wie ZugriffsTest
package B; import A.*; public class ZugriffsTest5 extends ZugriffsTest { public static void main(String[] args) { Zugriffstest t = new ZugriffsTest5(); t.priv = 1; // n. erlaubt t.prot = 1; // n. erlaubt t.pub = 1; // erlaubt t.pack = 1; // n.erlaubt } } t.privMethode(); t.protMethode(); t.pubMethode(); t.packMethode(); // // // // n.e. n.e. erl. n.e.

Verkapselung
Verkapselung ist ein Grundprinzip der Objektorientierung, und kann als Empfehlung verstanden werden, Zugriffskontrollen richtig einzusetzen also: Jede Klasse legt mit Hilfe der Zugrifsrechte selbst fest, wer auf ihre Attribute und Methoden zugreifen darf, hierbei gilt:
Methoden, die nicht dokumentiert sind, bzw. nur Hilfsfunktionen fr andere Methoden sind, sollten private oder zumindest protected sein Attribute sollten nicht public sein, um nderbarkeit und Datenkonsistenz sicherzustellen Fr Zugriffe auf Attribute sollten get- und set-Methoden zur Verfgung gestellt werden, die zugehrigen Attribute sollten dann private sein

Im Unterschied zu ZugriffsTest4 wird hier ber eine Referenz auf Zugriffstest auf die Attribute bzw. Methoden zugegriffen. Fr
Zugriffstest t = new Zugriffstest();

erhalten wir die gleichen Zugriffseinschrnkungen (nur publicZugriff)


481

482

Verkapselung

Gesamtbeispiel Klasse Datum


Klasse Datum unter Bercksichtigung von: Verkapselung / Zugriffskontrolle Ausnahmebehandlung Zeigt auch, was von Packages sichtbar gemacht werden mu! D.h. vieles bleibt intern nur das ntigste wird nach auen bekannt gemacht

Verstecken von Implementierungsdetails ist wichtig, um nderbarkeit der Implementierung zu gewhrleisten. Eine nicht sichtbare Methode kann auch nicht von anderen benutzt worden sein. Verstecken von Implementierungsdetails kann das Verstndnis erleichtern, da nur die fr den Endanwender wichtige Schnittstellen zugreifbar sind.

483

484

Gesamtbeispiel Klasse Datum


Realisierung der folgenden Funktionalitten: Wochentagberechnung Differenzbildung zwischen Daten (in Tagen) Addition eines Datums mit einem Offset (in Tagen) Feiertagsberechnungen

Klasse DatumException
Klasse Datum bekommt eine eigene Exception-Klasse fr Fehlerbehandlung
package utils; /** * Exception fr Fehlerbehandlung der Klasse Datum. */ public class DatumException extends Exception { public DatumException() { super(); } public DatumException(String s) { super(s); } }
485 486

Klasse Datum - Attribute


Attributdefinitionen der Klasse Datum
package utils; import java.io.*; /** * Klasse zur Verwaltung von Datumsobjekten */ public class Datum implements Serializable { private int tagkonst; // Konstante mit Tagen seit Christi Geburt // Konstanten fr Tag, Monat und Jahr. // Daten lassen sich aus tagkonst berechnen, daher // als transient definiert. private transient int tag, monat, jahr; private final static String[] wt = {"Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"}; // Hier nun die Methoden, nchste Folien }
487

Klasse Datum - ffentl. Konstruktoren


/** * Konstruktor mit Tag, Monat und Jahr. * @exception utils.DatumException * Datum ist nicht gltig nach Gregorianischem Kalender * (Gregorianischer Kalender seit 15.10.1582) */ public Datum (int tag, int monat, int jahr) throws DatumException { init(tag, monat, jahr); // Initialisierung der Attribute }

Achtung: Fr Kommentare sollten HTML-Umlaute verwendet werden, also "&uuml;" fr "". Hier aber "" fr die bessere Lesbarkeit.
/** * Konstruktor fr 1. Januar eines Jahres. */ public Datum(int jahr) throws DatumException { init(1,1,jahr); }
488

Klasse Datum - priv. Initialisierungsmethoden


/** * Berechnung der Tage, die seit eines Bezugsdatums vergangen sind. * Dieser Tag liegt vor dem 15.10.1582, dem Start des Gregorianischen * Kalenders. * Wichtig fr Differenzbildung von Daten und fr Wochentags- bzw. * Feiertagsberechnungen. */ private synchronized int getTageKonst(int tag, int monat, int jahr) { boolean schalt = (jahr%4 == 0 && (jahr%100 != 0 || jahr%400 == 0)); return (jahr-1) * 365 + (jahr-1)/4 - (jahr-1)/100 + (jahr-1)/400 + (monat-1)*31 - (monat>2 ? 3 : 0) + (monat>2 && schalt ? 1: 0) - (monat>4 ? 1 : 0) - (monat>6 ? 1 : 0) - (monat>9 ? 1 : 0) - (monat>11 ? 1 : 0) + tag; }
489

Klasse Datum - priv. Initialisierungsmethoden


/** * Initialisiert das Attribut tagkonst. * Der bentigte Wert kann mit getTageKonst(tag, monat, jahr) * berechnet werden. * @exception utils.DatumException * Datum vor Einfhrung des Gregorianischen Kalenders */ private void init(int tagkonst) throws DatumException { this.tagkonst = tagkonst; if (tagkonst < 577736) throw new DatumException("Nur Gregorianischer Kalender" + " ab 15.10.1582 wird unterttzt"); }

490

Klasse Datum - priv. Initialisierungsmethoden


/** * Initialisiert Attribute jahr, monat und tag bei bereits * initialisiertem Attribut tagkonst. */ private synchronized void setTagMonatJahr() { jahr = 1500; monat = 1; tag = 1; while (getTageKonst(tag, monat, jahr+100) <= tagkonst) jahr += 100; while (getTageKonst(tag, monat, jahr+10) <= tagkonst) jahr += 10; while (getTageKonst(tag, monat, jahr+1) <= tagkonst) jahr ++; while (getTageKonst(tag, monat+1, jahr) <= tagkonst) monat++; tag += tagkonst - getTageKonst(tag, monat, jahr); }

Klasse Datum - priv. Initialisierungsmethoden


/** * Initialisiert Attribute jahr, monat und tag und tagkonst. * * @exception utils.DatumException * Datum ist nicht gltig nach Gregorianischem Kalender. * (Gregorianischer Kalender seit 15.10.1582). * Hierbei werden alle Regeln der Datumsbildung bercksichtigt. */ private synchronized void init(int tag, int monat, int jahr) throws DatumException { init(getTageKonst(tag, monat, jahr)); setTagMonatJahr(); if (tag != this.tag || monat != this.monat || jahr != this.jahr) throw new DatumException("Datum " + tag + "." + monat + "." + jahr + " existiert nicht"); }
491 492

Klasse Datum - privater Konstruktor


/** * Konstruktor, der aus der Tageskonstante ein Datumsobjekt * erzeugt. * Dummy-Parameter notwendig, um sich von Initialisierung ber * Jahreszahl zu unterscheiden. */

Klasse Datum - Objektserialisierung


/** * Bei Objektserialisierung wird nur das Attribut tagkonst * bercksichtigt. * Diese Methode sorgt fr eine Rekonstruktion der * Attribute tag, monat und Jahr bei Deserialisierung */

private Datum(int tagkonst, boolean dummy) throws DatumException { init(tagkonst); setTagMonatJahr(); }

private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); setTagMonatJahr(); }

493

494

Klasse Datum - ffentliche Methoden


/** * Berechnung des Wochentages. */ public String wochentag() { return wt[(tagkonst + 6) % 7]; }

Klasse Datum - ffentliche Methoden


/** * Gibt das Datum in i Tagen zurck. Auch negatives i mglich. * @exception utils.DatumException * Das Ergibnis liegt vor Einfhrung des Gregorianischen Kalenders. */ public Datum plus(int i) throws DatumException { return new Datum(tagkonst + i, true); }

/** * Gibt die Differenz zu einem Referenzdatum d in Tagen zurck. * Der Wert ist negativ, falls d in der Zukunft liegt, sonst positiv. */ public int diff(Datum d) { return tagkonst - d.tagkonst; }

/** * Gibt String-Reprsentation des Datums zurck. */ public String toString() { return wochentag() + ", den " + tag + "." + monat + "." + jahr; }

495

496

Klasse Datum - ffentliche Methoden


/** * Berechnet Ostersonntag des entsprechenden Jahres nach der Gauschen * Osterformel (1800), welche fr die Jahre 1583 bis 8202 gltig ist. * @exception utils.DatumException * Falls Osterformel nicht gltig. */ public Datum OsterSonntag() throws DatumException { if (jahr < 1583 || jahr > 8202) throw new DatumException("Osterformel gilt von 1583 bis 8202"); int a = jahr % 19; int b = jahr % 4; int c = jahr % 7; int m = (8 * (jahr/100) + 13) / 25 - 2; int s = jahr/100 - jahr/400 - 2; int M = (15 + s - m) % 30; int N = (6 + s) % 7; int d = (M + 19*a) % 30; int D; if (d == 29) D = 28; else if (d == 28 && a >= 11) D = 27; else D = d; int e = (2*b + 4*c + 6*D + N) % 7; return new Datum(22,3,jahr).plus(D+e); }
497

Klasse Datum - ffentliche Methoden


// Auf Ostern basierende Feiertage: public Datum PfingstSonntag() throws DatumException { return OsterSonntag().plus(49); } public Datum RosenMontag() throws DatumException { return OsterSonntag().plus(-48); } public Datum Himmelfahrt() throws DatumException { return OsterSonntag().plus(39); }

// Feste Feiertage: public Datum ErsterWeihnachtstag() throws DatumException { return new Datum(25,12,jahr); } public Datum Maifeiertag() throws DatumException { return new Datum(1,5,jahr); }
498

Klasse Datum - Anwendung


package hauptpackage; import utils.*; public class Anwendung { public static void main(String[] args) { try { Datum d = new Datum(1,1,2000).plus(10000); System.out.println("Am " + d + " wird das 3. Jahrtausend" + " 10000 Tage alt."); } catch (DatumException e) {} } }

Klasse Datum - Anwendung


package hauptpackage; import utils.*; public class Anwendung { public static void main(String[] args) { try { System.out.println("Ostersonntage:"); for (int i=1995; i<=2010; i++) System.out.println( new Datum(i).OsterSonntag()); } catch (DatumException e) {} } }

Ausgabe:
Ostersonntage: Sonntag, den 16.4.1995 Sonntag, den 7.4.1996 Sonntag, den 30.3.1997 Sonntag, den 12.4.1998 Sonntag, den 4.4.1999 Sonntag, den 23.4.2000 Sonntag, den 15.4.2001 Sonntag, den 31.3.2002 Sonntag, den 20.4.2003 Sonntag, den 11.4.2004 Sonntag, den 27.3.2005 Sonntag, den 16.4.2006 Sonntag, den 8.4.2007 Sonntag, den 23.3.2008 Sonntag, den 12.4.2009 Sonntag, den 4.4.2010
500

Ausgabe:
Am Mittwoch, den 19.5.2027 wird das 3. Jahrtausend 10000 Tage alt.
499

Klassenbibliothek
Umfangreiche Klassenbibliotheken machen die Mchtigkeit von Java aus. Whrend sich der Sprachumfang kaum von dem anderer Sprachen unterscheidet, bedeutet die Verfgbarkeit einer umfangreichen Klassenbibliothek einen Vorteil. Von besonderer Bedeutung ist dabei, da die Bibliothek plattformbergreifend eingesetzt werden kann. Die Bibliothek ist in Pakete gegliedert. Nur dadurch wird sie handhabbar. Diese Pakete knnen wie selbstdefinierte Pakete verwendet werden.
502

Kapitel 16
berblick ber Java-Klassenbibliotheken

Klassenbibliothek
Klassenbibliotheken sehr umfangreich Hier nur Einblick in grobe Einteilung und wichtige Funktionalitten Vollstndige bersicht in JDK 1.2 Documentation bzw. Java SDK SE v1.3 Documentation => Nachschlagewerk

bersicht
java.applet java.awt java.beans java.io java.lang java.math java.rmi java.security java.sql java.util javax.swing (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.0) (JDK 1.2)

Java Klassenbibliotheken
Java-Applets (fr WWW-Browser) AWT-Komponenten Beans-Development Input / Output / Datenstrme Basispackage fr Java Zahlen groer Genauigkeit Remote Method Invocation Sicherheit, Kryptographie JDBC-Paket Verschiedene Hilfsklassen Swing-Komponenten Fr JDK 1.1.x: com.sun.java.swing (JDK 1.2) CORBA-Schnittstelle

org.omg.CORBA

503

504

java.applet
java.applet java.awt java.beans java.io java.lang java.math java.rmi java.security java.sql java.util javax.swing (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.0) (JDK 1.2)

Die Java Klassenbibliotheken


Java-Applets (fr WWW-Browser) AWT-Komponenten Beans-Development Input / Output / Datenstrme Basispackage fr Java Zahlen groer Genauigkeit Remote Method Invocation Sicherheit, Kryptographie JDBC-Paket Verschiedene Hilfsklassen Swing-Komponenten Fr JDK 1.1.x: com.sun.java.swing (JDK 1.2) CORBA-Schnittstelle

java.awt
java.applet java.awt java.beans java.io java.lang java.math java.rmi java.security java.sql java.util javax.swing (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.0) (JDK 1.2)

Die Java Klassenbibliotheken


Java-Applets (fr WWW-Browser) AWT-Komponenten Beans-Development Input / Output / Datenstrme Basispackage fr Java Zahlen groer Genauigkeit Remote Method Invocation Sicherheit, Kryptographie JDBC-Paket Verschiedene Hilfsklassen Swing-Komponenten Fr JDK 1.1.x: com.sun.java.swing (JDK 1.2) CORBA-Schnittstelle

org.omg.CORBA

org.omg.CORBA

505

506

java.beans
java.applet java.awt java.beans java.io java.lang java.math java.rmi java.security java.sql java.util javax.swing (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.0) (JDK 1.2)

Die Java Klassenbibliotheken


Java-Applets (fr WWW-Browser) AWT-Komponenten Beans-Development Input / Output / Datenstrme Basispackage fr Java Zahlen groer Genauigkeit Remote Method Invocation Sicherheit, Kryptographie JDBC-Paket Verschiedene Hilfsklassen Swing-Komponenten Fr JDK 1.1.x: com.sun.java.swing (JDK 1.2) CORBA-Schnittstelle

java.io
java.applet java.awt java.beans java.io java.lang java.math java.rmi java.security java.sql java.util javax.swing (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.0) (JDK 1.2)

Die Java Klassenbibliotheken


Java-Applets (fr WWW-Browser) AWT-Komponenten Beans-Development Input / Output / Datenstrme Basispackage fr Java Zahlen groer Genauigkeit Remote Method Invocation Sicherheit, Kryptographie JDBC-Paket Verschiedene Hilfsklassen Swing-Komponenten Fr JDK 1.1.x: com.sun.java.swing (JDK 1.2) CORBA-Schnittstelle

org.omg.CORBA

org.omg.CORBA

507

508

java.lang
java.applet java.awt java.beans java.io java.lang java.math java.rmi java.security java.sql java.util javax.swing (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.0) (JDK 1.2)

Die Java Klassenbibliotheken


Java-Applets (fr WWW-Browser) AWT-Komponenten Beans-Development Input / Output / Datenstrme Basispackage fr Java Zahlen groer Genauigkeit Remote Method Invocation Sicherheit, Kryptographie JDBC-Paket Verschiedene Hilfsklassen Swing-Komponenten Fr JDK 1.1.x: com.sun.java.swing (JDK 1.2) CORBA-Schnittstelle

java.lang
Basispaket der Sprache

Die Java Klassenbibliotheken

alle Systemklassen sind hier untergebracht Klassen drfen ohne import-Deklaration direkt angesprochen werden (vgl. System, String)

org.omg.CORBA

509

510

java.lang: Object, String und StringBuffer


Klasse Object
Die Mutter aller Klassen

Class
Klasse Class
Klasse um Klassennamen und Instanzen zu verwalten Die Klasse Object hat die Methode public final Class getClass() um zugehriges Class-Objekt zu erhalten Methode public String getName() gibt Namen der Klasse zurck Es lassen sich mit Hilfe des Class-Objektes verfgbare Konstruktoren und Methoden ermitteln (seit JDK 1.1) Neue Objekte der Klasse knnen so erzeugt werden, ohne da man Vorabinformationen hat (seit JDK 1.1)

Klassen String und StringBuffer


Zeichenketten

511

512

System
Klasse System
Sammlung von Klassenattributen und -methoden Anbindung an Standard-In, Standard-Out und Standard-Error-Stream (System.in, System.out und System.err) Systemnahe Methoden public static long currentTimeMillis()
gibt Millisekunden seit 1. Janur 1970 zurck

java.lang
java.lang.System

Die Java Klassenbibliotheken

Anbindung an Standard-Err, Standard-In, Standard-Out-Stream


public static final PrintStream err public static final PrintStream in { public static final PrintStream out ... System.out.println(Hallo); ...

public static void exit(int status)


Beendet das Programm (und die Virtuelle Maschine)

public static void gc()


Empfehlung an den Garbage - Kollektor, Speicher freizugeben. In der Regel nicht ntig.

public static void exit(int status)

Systemnahe Methoden
513

public static void gc()


514

Einhllende Klassen
Klassen Boolean, Byte, Character, Double, Float, Integer, Long, Short Ntzlich, wenn primitive Datentypen als Objekt bentigt werden, z.B. fr objektbasierte Datenstrukturen Alle einhllenden Klassen haben den entsprechenden einfachen Datentypen als Konstruktor
Beispiel: Float zahl=3.5; Float zahlHlle = new Float(zahl);

Einhllende Klassen
Byte, Double, Float, Integer, Long und Short (sowie java.math.BigDecimal und java.math.BigInteger) sind von abstrakter Klasse Number abgeleitet Fr Objekte der Klasse Number sind Wandlungen zu primitiven Datentypen mglich mit byteValue(), doubleValue(), floatValue(), intValue(), longValue() und shortValue() Beispiel: Konvertierung von String nach double String s = "1.345"; double d = new Double(s).doubleValue();

Alle einhllenden Klassen (bis auf Character) haben String als Konstruktorargument
Beispiel: Long l = new Long("2.142352123");
515

516

java.lang
java.lang.Math
Konstanten E und Pi

Die Java Klassenbibliotheken

java.math
java.applet java.awt java.beans java.io java.lang java.math java.rmi java.security java.sql java.util javax.swing (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.0) (JDK 1.2)

Die Java Klassenbibliotheken


Java-Applets (fr WWW-Browser) AWT-Komponenten Beans-Development Input / Output / Datenstrme Basispackage fr Java Zahlen groer Genauigkeit Remote Method Invocation Sicherheit, Kryptographie JDBC-Paket Verschiedene Hilfsklassen Swing-Komponenten Fr JDK 1.1.x: com.sun.java.swing (JDK 1.2) CORBA-Schnittstelle

Methoden fr Betrag, Rundung, Trigonometrische Funktionen, Exponent / Logarithmus, etc.

public static int abs(int a) public static native double sin(double a) public static native double sqrt(double a)

org.omg.CORBA

517

518

java.rmi
java.applet java.awt java.beans java.io java.lang java.math java.rmi java.security java.sql java.util javax.swing (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.0) (JDK 1.2)

Die Java Klassenbibliotheken


Java-Applets (fr WWW-Browser) AWT-Komponenten Beans-Development Input / Output / Datenstrme Basispackage fr Java Zahlen groer Genauigkeit Remote Method Invocation Sicherheit, Kryptographie JDBC-Paket Verschiedene Hilfsklassen Swing-Komponenten Fr JDK 1.1.x: com.sun.java.swing (JDK 1.2) CORBA-Schnittstelle

java.security
java.applet java.awt java.beans java.io java.lang java.math java.rmi java.security java.sql java.util javax.swing (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.0) (JDK 1.2)

Die Java Klassenbibliotheken


Java-Applets (fr WWW-Browser) AWT-Komponenten Beans-Development Input / Output / Datenstrme Basispackage fr Java Zahlen groer Genauigkeit Remote Method Invocation Sicherheit, Kryptographie JDBC-Paket Verschiedene Hilfsklassen Swing-Komponenten Fr JDK 1.1.x: com.sun.java.swing (JDK 1.2) CORBA-Schnittstelle

org.omg.CORBA

org.omg.CORBA

519

520

java.util
java.applet java.awt java.beans java.io java.lang java.math java.rmi java.security java.sql java.util javax.swing (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.0) (JDK 1.2)

Die Java Klassenbibliotheken


Java-Applets (fr WWW-Browser) AWT-Komponenten Beans-Development Input / Output / Datenstrme Basispackage fr Java Zahlen groer Genauigkeit Remote Method Invocation Sicherheit, Kryptographie JDBC-Paket Verschiedene Hilfsklassen Swing-Komponenten Fr JDK 1.1.x: com.sun.java.swing (JDK 1.2) CORBA-Schnittstelle

Kapitel 17 Dynamische Datenstrukturen

org.omg.CORBA

521

berblick

Dynamische Datenstrukturen

17.1 Listen 17.2 Bume 17.3 Graphen 17.4 Schlangen 17.5 Keller 17.6 Mengen

Unter dynamischen Datenstrukturen verstehen wir Strukturen, die je nach Bedarf und damit dynamisch wachsen und schrumpfen knnen (Unterschied zu Arrays!). Die Idee ist, da die einzelnen Elemente die zu speichernden / zu verarbeitenden Daten speichern und da diese Elemente miteinander verknpft werden. Die Art der Elemente ist dabei stark problemabhngig und variiert von Anwendung zu Anwendung. Fr die Verknpfung gibt es einige typische Muster. Diese typischen Muster sind in den klassischen dynamischen Datenstrukturen realisiert.
524

berblick

Dynamische Datenstrukturen

Wichtige dynamische Datenstrukturen


Listen, lineare Listen, doppelt verkettete Bume, binre Bume, binre Suchbume Graphen, gerichtete Graphen, ungerichtete Graphen Stack, Schlangen Mengen
Wie wird eine Instanz der Struktur intialisiert und Daten eingefgt bzw. entfernt ? Wie wird in den Strukturen navigiert ? Wie werden einzelne Werte in einer Struktur wiedergefunden ? Wie werden alle in einer Struktur abgelegten Werte besucht ?

Neben der Verknpfung werden diese Datenstrukturen auch noch dadurch charakterisiert, da es bestimmte Zugriffsmethoden gibt. Wie in der Objektorientierung blich, werden die dynamischen Datenstrukturen also durch die Art der Verknpfung der Elemente und die Zugriffsmethoden festgelegt. Weitere Methoden der Ausprgungen der dynamischen Strukturen hngen auch von der Struktur der Einzelelemente ab.

525

526

Zugriff ber Referenzen Eigenschaften von Referenzen:


Variable betrag: Referenz auf Objekt der Klasse Geld Soll eine Referenz auf kein Objekt verweisen, wird der Wert null zugewiesen berprfung der Referenz mittels Vergleichsoperator Geld betrag; Der Wert null fr Referenzen ermglicht ein Objekt explizit von if (betrag != null) einer Referenz zu lsen betrag.Drucke(); else betrag = new Geld(10, 25); Geld preis; preis = new Geld(48, 98); preis = null; Referenz preis verweist auf Objekt der Klasse Geld Zuweisung auf null vernichtet Verweis auf Objekt mit Werten 48 und 98

Dynamische Datenstrukturen Grundlage fr den Aufbau dynamischer Datenstrukturen


Klassen enthalten Attribute, die Referenzen auf Objekte der eigenen Klasse darstellen. Diese Attribute schaffen die Mglichkeit, an eine Referenz ein weiteres Objekt der Klasse zu binden. Die einzelnen Objekte sind in der Lage, gemeinsam eine komplexe Struktur durch aufeinander verweisende Referenzen zu bilden.

527

528

Allgemeines zu Listen
Listen definieren eine Reihenfolge von Elementen, die gem dieser Reihenfolge miteinander verknpft sind. Typische Zugriffsmethoden:

Kapitel 17.1
Listen

Einfgen am Anfang Einfgen an bestimmter Stelle Anfgen (d.h. Einfgen am Ende) Ermittlung der Lnge Prfen auf Leere Prfen, ob Element in Liste vorkommt Ermittlung der Position eines Elements Ermittlung des ersten Elements Liefern der Liste ohne erstes Element

Die Verfgbarkeit aller dieser Methoden variiert mit dem Anwendungszweck. Nicht immer sind alle Methoden realisiert, aber man redet dennoch von Listen
530

Bestandteile einer Liste


class Element { Element(int i) { wert = i; weiter = null; } private int wert; private Element weiter; }

Schema der Klasse lineare Liste


class Liste { private Element kopf; Liste() { kopf = null; } Liste(int w) { kopf = new Element(w); } void FgeAn(int an) { ... } void FgeEin(int ein) { ... }

Deklaration einer Klasse Element mit zwei privaten Attributen und einem Konstruktor Ein Objekt vom Typ Element enthlt als Attribute eine ganze Zahl und einen Zeiger auf ein weiteres Objekt des Typs Element Jedes Objekt vom Typ Element besitzt eine Referenz auf ein weiteres Element, man kann sie miteinander verketten Die daraus entstehende Datenstruktur ist eine Lineare Liste

531

532

Erweiterung einer Liste Eine lineare Liste kann auf verschiedene Arten konstruiert werden :
neues Element an den Anfang, in die Mitte oder an das Ende einer bereits bestehenden Liste anhngen Zugriff auf die Liste wird durch eine Referenz realisiert, die auf das erste Element der Liste zeigt Enthlt eine Liste keine Elemente, zeigt die Referenz auf null Besuchen eines Elements innerhalb der Liste erfordert eine Referenz von Element zu Element

Erweiterung einer Liste


void FgeAn(int neuerWert) { Programm: Einfgen am Ende einer Element lauf = this; linearen Liste while (lauf.weiter != null) lauf = lauf.weiter; lauf.weiter = new Element(neuerWert); }

Die Klasse Element wird um die Methode FgeAn ergnzt, die ein neues Element an das Ende einer Liste anhngt, die bereits aus wenigstens einem Element besteht. Die Liste wird durch die lokale Referenz lauf von Element zu Element durchlaufen, bis die Referenz weiter auf null verweist. Nun wird auf das neu erzeugte Objekt der Klasse Element verwiesen. Die Referenz this verweist immer auf das Objekt, fr welches die Methode FgeEin aufgerufen wurde, daher verweist this nie auf den Wert null.
534

533

Initiales Anlegen einer linearen Liste


Anlegen einer linearen Liste:
Mit dem Konstruktor von Element wird ein erstes Objekt geschaffen. Alle weiteren Listenelemente werden durch FgeAn fr das erste Element angefgt.

Rekursives Anfgen
Rekursives Vorgehen:
Programm: Einfgen auf der Basis eines rekursiven Vorgehens

Element kopf; kopf = new Element(25); kopf.FgeAn(22); kopf kopf.FgeAn(28);

void RekFgeAn(int neuerWert) { if (weiter != null) weiter.RekFgeAn(neuerWert); else weiter = new Element(neuerWert); }

25

22

28

null

Beachte:
Die Ausfhrung der Methode RekFgeAn ist aufwendiger, als die bisher vorgestellten Methoden, da alle Aufrufe von RekFgeAn ineinander geschaltet sind und erst dann beendet werden, wenn das neue Element angefgt ist.
535 536

Die Methode FgeAn wird fr das erste Element der Liste aufgerufen. Jetzt wird mit lauf die gesamte Liste bearbeitet.

Konstruktion einer Liste durch weiteres Anfgen


Programm: Methode FgeEin

Konstruktion einer Liste durch Einfgen


kopf 25 22 28 null

void FgeEin(int neuerWert) { Element neuesElement = new Element(wert); neuesElement.weiter = weiter; weiter = neuesElement; wert = neuerWert; } kopf.FgeEin(17) wird nun auf die Liste
kopf 25 22 28 null

zuweisen mit Konstruktor


kopf 25 25 17 25 22 28 null 22 28 null

zuweisen
kopf 17

Alles andere wrde bedeuten, da kopf umgesetzt wird. Das aber wrde bedeuten, da ein Element den Zugriff auf sich abtritt.

angewendet

Das geht nicht, also bleibt nur der Weg ber das Einfgen an der zunchst zweiten Stelle.
537 538

Klasse lineare Liste


Umsetzen von linearen Listen mit der Klasse Element und den Methoden FgeAn und FgeEin : Aufbau einer Liste aus einer leeren Liste:
Da die Methoden FgeAn und FgeEin Bestandteile der Objekte der Klasse Element sind, knnen sie nur dann aufgerufen werden, wenn auch ein solches Element besteht. Daher mu das erste Element einer Liste immer ber einen Konstruktor erzeugt werden, alle weiteren knnen dann ber die Methoden hinzugefgt werden. Innerhalb eines Programms mu daher vor jedem Aufruf von FgeAn oder FgeEin berprft werden, ob die Referenz auf die Liste auf null verweist. bersichtlicher wre es hingegen, in allen Situationen Elemente durch die Methoden FgeAn und FgeEin hinzufgen zu knnen.

Klasse lineare Liste


nderung des ersten Elementes:
Die Implementierung der Methode FgeEin hat gezeigt, da das Hinzufgen eines neuen Objektes als erstes Element der Liste nicht mglich ist; hierfr mu auf entsprechende Zuweisungen zurckgegriffen werden. Ebenso problematisch ist das Lschen des ersten Elementes einer Liste. Insbesondere das letzte Element einer Liste lt sich nicht durch eine Methode der Klasse Element entfernen.

539

540

Klasse lineare Liste

Verbesserungsmglichkeiten
Die Idee, eine Liste mit einer Referenz auf ihr erstes Element gleichzusetzen, wird dem Umgang mit der entstehenden Datenstruktur nicht gerecht. Der Wertebereich einer Klasse, die lineare Listen implementiert, sollte auch die leere Liste beinhalten und fr diese eine korrekte Anwendung der Methoden garantieren. Die Ausfhrung von Methoden sollte durch zustzliche Referenzen auf ausgewhlte Elemente der Liste untersttzt werden. Als Ergebnis entstehen die folgenden, modifizierten Klassen Element und Liste
542

Effizienz der Methode FgeAn:


Die Methode FgeAn erfordert bei jedem Aufruf ein vollstndiges Durchlaufen der Liste. Eine sehr viel effizientere Realisierung dieser Listenoperation wre mglich, wenn neben dem ersten Element auch das letzte Element der Liste unmittelbar erreichbar wre.

541

Klasse Element (verbessert)


class Element { private int wert; private Element weiter; Element(int i) { wert = i; weiter = null; } Element(int i, Element e) { wert = i; weiter = e; } void SetzeWert(int i) { wert = i; } int GibWert() { return wert; } void SetzeWeiter(Element e) { weiter = e; } Element GibWeiter() { return weiter; } }

Klasse lineare Liste (verbessert)


class Liste { private Element kopf, fu; Liste() { kopf = fu = null; } Liste(int w) { kopf = fu = new Element(w); } void FgeAn(int an) { Element neu = new Element(an); if (fu != null) { fu.SetzeWeiter(neu); fu = neu; } else kopf = fu = neu; } void FgeEin(int ein) { kopf = new Element(ein, kopf); if (fu == null) fu = kopf; } }

543

544

Beispiel Anfgen und Einfgen


Liste eineListe = new Liste(); eineListe.FgeAn(15); eineListe.FgeAn(52); eineListe.FgeEin(34) kopf null fu

Beispiel Anfgen und Einfgen


Liste eineListe = new Liste(); eineListe.FgeAn(15); kopf eineListe.FgeAn(52); eineListe.FgeEin(34)

15
ein

52 34

fu null

kopf

15 ein 34

52

fu null

kopf

15

fu null
kopf

15
ein

52 34

fu null

kopf

15

52

fu null

545

546

Anwendungsbeispiel
Einordnen eines Werts in eine bereits aufsteigend geordnete Liste Keine zwei Elemente haben die identische Belegung des Attributs wert Der Algorithmus ist auf natrliche Weise rekursiv

Anwendungsbeispiel

Przisierung des Algorithmus:


Folgende Flle sind zu unterscheiden:
kopf == null: Einen Sonderfall bildet die Situation, da die Liste leer ist, also noch kein Element enthlt. Es mu ein erstes Element angelegt werden, das sicherlich eine geordnete, einelementige Liste bildet. kopf != null: Wir definieren eine private Methode Positioniere, die als Parameter den einzuordnenden Wert und eine Referenz auf den Anfang einer Teilliste bergeben bekommt. Als Ergebnis gibt Positioniere eine Referenz auf Element zurck, die auf die Teilliste verweist, in die x einsortiert ist.
548

Die Idee:
Ist eine ganze Zahl x gegeben, so da x kleiner als das erste Element der Liste ist, so fge man x am Anfang der Liste ein. Mu x in der Mitte der Liste eingefgt werden, so suche man die entsprechende Position, spalte dort die Liste in einen Anfangs- und einen Endteil auf und fge x am Anfang des Listenrestes ein. Schlielich verbinde man das Ende des Anfangsteils der Liste mit der so entstandenen neuen Liste. Ist x grer als das letzte Element der Liste, so bildet das neue Element allein den neuen Rest: x wird angefgt.

547

Anwendungsbeispiel
Sei anfang die an Positioniere bergebene Teilliste und gelte:

Anwendungsbeispiel

Beachte:
Keine doppelten Eintrge werden zugelassen. Die Referenz fu verweist auch nach dem Einsortieren auf das letzte Element. Wenn Positioniere die leere Referenz null als Wert fr den Parameter anfang bergeben bekommt, mu fu korrigiert werden und auf das neu eingeordnete letzte Objekt gesetzt werden.

x < anfang.wert:
Erzeuge ein neues Element und fge es am Anfang der bei anfang beginnenden Teilliste ein.

x > anfang.wert:
Fge x in die mit anfang.weiter beginnenden Restliste ein, indem hierfr Positioniere mit den entsprechenden Parametern erneut aufgerufen wird.

549

550

Einordnen mit Hilfe von Positioniere


Programm: Einordnen in eine geordnete Liste

Einordnen mit Hilfe von Positioniere


Programm: Einordnen in eine geordnete Liste

class Liste { private Element kopf, fu; Liste() { kopf = fu = null; } Liste(int w) { kopf = fu = new Element(w); } void OrdneEin(int i) { kopf } = Positioniere(kopf, i);

private Element Positioniere(Element anfang, int i) { if (anfang == null) fu = anfang = new Element(i); else { if (i < anfang.GibWert()) { anfang = new Element(i, anfang); } if (i > anfang.GibWert()) anfang.SetzeWeiter (Positioniere(anfang.GibWeiter(), i)); } return anfang; } }
551 552

Durchlaufen einer Struktur In vielen Anwendungen, die auf dynamischen Datenstrukturen basieren, besteht die Notwendigkeit, alle Elemente der Struktur genau einmal zu besuchen. Dies gilt fr Listen wie fr andere dynamische Strukturen. Dieses mglichst nur einmalige Besuchen aller Elemente nennt man Durchlaufen einer Struktur. Anwendungsbeispiele: Prfen auf Vorhandensein, Einsortieren Konkrete Ausprgungen dieses Problems spielen in der theoretischen Informatik eine wichtige Rolle (Travelling Salesman Problem).
Programm: Rekursive Methode zum Drucken einer verketten Liste
553

Durchlaufen einer Liste


class Liste { void RekDrucke() { RekDrucke(kopf); } private void RekDrucke(Element aktuell) { if (aktuell != null) { System.out.println(aktuell.GibWert()); RekDrucke(aktuell.GibWeiter()); } } Programm: Rekursive Methode zum Drucken }
einer linearen Liste 554

Durchlaufen einer Liste

Durchlaufen einer Liste

Durchlauf einer Liste in umgekehrter Reihenfolge:


Referenz fu verweist zwar auf das letzte Element einer Liste, kann jedoch nicht von dort zum vorletzten Element gelangen. Fr eine umgekehrte Ausgabe mssen alle Listenelemente gemerkt werden, whrend die Liste vom Anfang zum Ende durchluft. Erst nach einmaligem Durchlaufen kann vom letzten bis zum ersten Element gedruckt werden.

void IterDrucke() { Element aktuell = kopf; while (aktuell != null) { System.out.println(aktuell.GibWert()); aktuell = aktuell.GibWeiter(); } }
Programm: Iterative Methode zum Drucken einer linearen Liste
555

556

Durchlaufen einer Liste

Doppelt verkettete Listen Ist der Durchlauf vom Ende einer Liste zu ihrem Anfang hufig bentigt, dann ist die lineare Verkettung von vorne nach hinten nicht der ideale Navigationspfad. Besser wre es dann auch eine Rckwrtsverkettung zu haben. Auf Grund dieser berlegung kommt man zu doppelt verketteten Liste (einmal von vorne nach hinten, einmal umgekehrt).

void

ReversivDrucke() {

ReversivDrucke(kopf); } private void ReversivDrucke(Element aktuell) { if (aktuell != null) { ReversivDrucke(aktuell.GibWeiter()); System.out.println(aktuell.GibWert()); } }


Programm: Ausgabe einer Liste in umgekehrter Reihenfolge

557

558

Doppelt verkettete Listen Die lokale Klasse Element enthlt eine zweite Referenz voran, die genau entgegengesetzt zu weiter gerichtet ist und somit fr jedes Element innerhalb der Liste auf seinen direkten Vorgnger verweist. Mit doppelt verketteten Listen kann in beide Richtungen einer Liste navigiert werden und deshalb komplexe Operationen auf einer Liste untersttzen. In Java: LinkedList (Unterklasse von AbstractSequentialList in java.util)
559

Doppelt verkettete Listen


class DElement { // die bekannten Deklarationen der linearen Liste private DElement voran, weiter; void SetzeVoran(DElement e) { voran = e; } Element GibVoran() { return voran; } } class DListe { // die bekannten Deklarationen der linearen Liste void FgeAn(int an) { DElement neu; neu = new DElement(an); if (fu != null) { fu.SetzeWeiter(neu); neu.SetzeVoran(fu); fu = neu; } else kopf = fu = neu; } void OrdneEin(int i) { kopf = Positioniere(kopf, i); }
560

Doppelt verkettete Listen


private DElement Positioniere(DElement anfang, int i) { if (anfang == null) anfang = new DElement(i); anfang.SetzeVoran(fu); fu = anfang; else { if (i < anfang.GibWert()) { DElement neu = new DElement(i, anfang); neu.SetzeVoran(anfang.GibVoran()); anfang.SetzeVoran(neu); if (neu.GibVoran != null) neu.GibVoran().SetzeWeiter(neu); anfang = neu; } if (i > anfang.GibWert()) anfang.SetzeWeiter (Positioniere(anfang.GibWeiter(), i)); } return anfang; }
561

Doppelt verkettete Listen

void ReversivDrucke() { DElement aktuell = fu; while (aktuell != null) { System.out.println(aktuell.GibWert()); aktuell = aktuell.GibVoran(); } } }

562

Exkurs: java.util - Hilfsklassen Umfat Interfaces und Klassen, um unterschiedliche Datenstrukturen zu realisieren, insbesondere: Interfaces:
Enumeration fr Objekte, die mehrere Elemente generieren Set fr Mengen ohne doppelte Elemente

java.util.Vector
Klasse java.util.Vector
public Object[] toArray()
Wandelt Vector in ein Array vom Basistyp Object

public int size()


Gibt Anzahl der enthaltenen Komponenten zurck

public boolean contains(Object elem)


Prft, ob ein Objekt enthalten ist. Gleichheit wird mit equals() berprft.

Klassen:
Vector: Mehr Flexibilitt als []-Arrays Stack: Stapel fr allgemeine Objekte, abgeleitet von Vector LinkedList: fr doppelt verkettete Listen StringTokenizer: Einfaches Zerlegen von Strings Random: Zufallsgenerator (fr Kryptographie: java.security.SecureRandom)
563

public int indexOf(Object elem)


Gibt Index eines Objektes zurck. Gleichheit wird mit equals() berprft.

public Object elementAt(int index)


Gibt Element an entsprechender Position zurck

public void insertElementAt(Object obj, int index) public void removeElementAt(int index)
Fgt Objekt an Position ein, bzw. entfernt Objekt
564

Verschiedene Kalender und Datumsklassen

java.util.Vector
Zugriff auf Elemente mit einem Index (analog zu Arrays) Abarbeiten der Liste mit einem Enumeration - Objekt

Das Interface Enumeration


Methode elements() von Vector liefert ein Enumeration-Objekt

Vector v = new Vector(); Person p1 = new Person(Urs,Mller,Hauptstr. 1,12345,Berlin); Person p2 = new Person(Max,Muster,Sdwall 1,44332,Dortmund); v.addElement(p1); v.addElement(p2); for (Enumeration el = v.elements(); el.hasMoreElements(); ) { Person p = (Person) el.nextElement(); String inhaber = p.toString(); Bildschirm.gibAus(inhaber); Explizites Typcasting durch } vorangestellte runde Klammern: Person p = (Person) el.nextElement();

public interface Enumeration { // liefert true, falls noch Elemente vorhanden sind public abstract boolean hasMoreElements(); // liefert das nchste Objekt der Aufzhlung public abstract Object nextElement(); }

565

566

Methoden der Klasse LinkedList


add (int index, Object element) addFirst (Object element) addLast (Object element) get (int index) remove (int index) remove (Object o) lscht das erste Auftreten des Elementes o getFirst() getLast() size() gibt die Anzahl der Elemente zurck

Kapitel 17.2
Bume

567

Allgemeines zu Bumen Bume sind hierarchische Strukturen. Man kommt von einer Wurzel zu inneren Knoten und letztlich zu Blttern. Es gibt keine Zyklen zwischen Mengen von Knoten. Bume sind damit auch verkettete Strukturen, die dynamisch wachsen und schrumpfen knnen. Binre Bume sind Bume, in denen jeder Knoten maximal zwei Shne hat (zur Definition siehe vorne). Ein Beispiel fr die ntzliche Anwendung binrer Bume ist das Heapsort von weiter vorne. Eine andere Anwendung binrer Bume sind die binren Suchbume.
569

Allgemeines zu Bumen Typische Zugriffsmethoden


einfgen einer Wurzel einfgen eines inneren Knotens entfernen der Wurzel entfernen eines inneren Knotens suchen nach links/rechts navigieren

570

Binre Suchbume

Binre Suchbume

Die Grundidee
Ein vorgelegtes Element x wird in einer geordneten Menge gesucht, es wird rekursiv vorgegangen.
Man beschaffe sich das mittlere Element der geordneten Menge und vergleiche es mit dem vorgelegten Element x. Stimmt das mittlere Element mit x berein, so ist man fertig; ist x kleiner, so wende man diese Idee auf alle Elemente an, die kleiner als das mittlere Element sind; ist x grer, wende man die Idee auf alle Elemente an, die grer als das mittlere Element sind. So kommt man durch fortgesetztes Halbieren sehr schnell zu der Entscheidung, ob x in der vorgegebenen Menge liegt oder nicht.
571

Definition:
Sei B ein binrer Baum, dessen Knoten mit ganzen Zahlen beschriftet sind. B heit binrer Suchbaum, falls gilt:

B ist leer oder


der linke und der rechte Unterbaum von B sind binre Suchbume, ist w die Beschriftung der Wurzel, so sind alle Elemente im linken Unterbaum kleiner als w, alle Elemente im rechten Unterbaum grer als w.

572

Binre Suchbume

Binre Suchbume Der Aufbau eines binren Suchbaums erfolgt durch wiederholtes Einfgen in einen leeren Baum. Die Reihenfolge der Werte, die in einen binren Suchbaum eingefgt werden, bestimmt die Gestalt des Baumes. Eine Menge von Werten kann bei unterschiedlichen Eingabereihenfolgen zu verschiedenen Reprsentationen als Baum fhren.

Beispiel fr einen binren Suchbaum:

16

10 9 13 14 15 18

24

573

574

Binre Suchbume

Binre Suchbume - die Klasse Knoten


class Knoten {

Beispiele:
1 2
Eingabefolge 1 2 3

3 2 1
Eingabefolge 3 2 1

private int wert; private Knoten links, rechts; Knoten(int i) { wert = i; links = rechts = null; } void SetzeWert(int i) { wert = i; } int GibWert() { return wert; } void SetzeLinks(Knoten k) { links = k; } Knoten GibLinks() { return links; }

3 3 1
Eingabefolge 3 1 2

2 1 3

void SetzeRechts(Knoten k) { rechts = k; } Knoten GibRechts() { return rechts; } };

Eingabefolge 2 1 3 oder 2 3 1
575 576

Binre Suchbume Algorithmus fr das Einfgen von Knoten


Gegeben seien ein binrer Suchbaum B und eine ganze Zahl k, die in B eingefgt werden soll. Es knnen vier Flle auftreten:

Die Klasse Binary Search Tree (BST)


class BST { private Knoten wurzel; BST() { wurzel = null; } void FgeEin(int i) { wurzel = FgeEin(wurzel, i);

B ist leer: Erzeuge einen neuen Knoten, weise ihn B zu und setze B.wert auf k. B ist nicht leer und B.wert = k: Dann ist nichts zu tun, da keine doppelten Eintrge vorgenommen werden sollen. B ist nicht leer und B.wert < k: Fge k in den rechten Unterbaum von B ein. B ist nicht leer und B.wert > k: Fge k in den linken Unterbaum von B ein.

577

578

Die Klasse Binary Search Tree (BST) - Einfgen


private Knoten FgeEin(Knoten aktuell, int ein) { if (aktuell == null) aktuell = new Knoten(ein); else { if (ein < aktuell.GibWert()) aktuell.SetzeLinks (FgeEin(aktuell.GibLinks(), ein)); if (ein > aktuell.GibWert()) aktuell.SetzeRechts (FgeEin(aktuell.GibRechts(), ein)); } return aktuell; } }
579

Binre Suchbume Algorithmus fr die Suche von Konten


Der am Beginn dieses Kapitels skizzierte Algorithmus fr das binre Suchen lt sich nun mit der durch die Methode FgeEin aufgebauten Datenstruktur recht einfach realisieren. Gegeben sind ein binrer Suchbaum B und eine Zahl k, die in dem Baum B gesucht werden soll:
B ist leer: k kann nicht im Baum sein. B ist nicht leer, so betrachtet man die Flle
B.wert = k: B.wert < k: B.wert > k: k ist gefunden, d.h. bereits in dem Baum B vorhanden. Suche im rechten Unterbaum von B. Suche im linken Unterbaum von B.

580

Die Klasse Binary Search Tree (BST) - Suchen


class BST { ... boolean Suche(int i) { return Suche(wurzel, i); } private boolean Suche(Knoten aktuell, int i) { boolean gefunden = false; if (aktuell != null) { gefunden = (aktuell.GibWert() == i) ; if (aktuell.GibWert() < i) gefunden = Suche(aktuell.GibRechts(), i); if (aktuell.GibWert() > i) gefunden = Suche(aktuell.GibLinks(), i); } return gefunden; } ... }
581

Suchen in binren Suchbumen

Definition:
Ist B ein binrer Baum, so definiert man die Hhe h(B) von B rekursiv durch:

0, h(B):= 1 + max {h(B ), h(B )}, 1 2

falls B leer ist falls B1 und B2 linker bzw. rechter Unterbaum von B sind

Ist B ein binrer Suchbaum mit h(B)=n, so enthlt B mindestens n und hchstens 2n-1 Knoten, nmlich n, wenn der Baum zur Liste degeneriert ist, und 2n-1, wenn jeder von 2n-1-1 inneren Knoten genau zwei Shne und jedes von 2n-1 Blttern keine Shne hat.

582

Suchen in binren Suchbumen


Behauptung: In einem beliebigen binren Suchbaum B, braucht man fr eine erfolglose Suche maximal h(B) Vergleiche Beweis: durch vollstndige Induktion nach dem Aufbau von B. Induktionsanfang: Ist B leer, also h(B)=0, so ist kein Vergleich ntig. Induktionsschritt: Wenn fr zwei Bume B1 und B2 mit der Hhe n gilt, da in jedem eine erfolglose Suche in maximal n Vergleichen mglich ist, so gilt fr den binren Suchbaum mit einer neuen Wurzel und deren Unterbume B1, B2, dass maximal n+1 Vergleiche ntig sind. Beweis des Induktionsschrittes: Durch Wurzelvergleich (ein Vergleich) wird ermittelt, ob im linken oder rechten Teilbaum weitergesucht werden mu. Die maximale Zahl der Vergleiche in einem Teilbaum ist n. Also, braucht man insgesamt maximal n+1 Vergleiche. In einem Baum der Hhe n+1 braucht man also maximal n+1 Vergleiche.
583

Suchen in binren Suchbumen


Daraus ergibt sich: Bei einer erfolglosen Suche in einem binren Suchbaum mit n Elementen sind mindestens log n (Basis 2) und hchstens n Vergleiche notwendig. Der gnstige Fall (log n Vergleiche) gilt in einem minimal ungleichgewichtigen Baum. Der ungnstige (n Vergleiche) gilt in einem vollstndig degenerierten Baum, der beispielsweise immer dann entsteht, wenn die Elemente in sortierter Reihenfolge eintreffen. Um diese Unsicherheit auszurumen (und somit eine Laufzeit auf der Basis von log n Vergleichen sicherzustellen), werden balancierte, binre Suchbume benutzt.

584

Suchen in binren Suchbumen


Eine Art balancierter, binrer Suchbume sind die AVL-Bume (nach ihren Erfindern Adelson, Velskii, Landis). Def.: Ein AVL-Baum ist ein binrer Suchbaum, in dem sich fr jeden Knoten die Hhen seiner zwei Teilbume um hchstens 1 unterscheiden. Einfge- und Entferne-Operationen werden dann etwas aufwendiger, aber dafr ist die Suche auch in ungnstigen Fllen effizienter (mehr dazu in der Vorlesung Datenstrukturen).

Schema der vollstndigen Induktion ber Bumen


Spezifikation der Behauptung S(T), wobei T ein Baum ist. Beweis, da S(T) gilt fr Bume, die nur einen Knoten haben. Aufsetzen des Induktionsannahme, T ist ein Baum mit Wurzel w und k 1 Unterbume, T1, ..., Tk. Annahme, da S(Ti) gilt fr i 1,2, ..., k Beweis, da S(T) unter der Induktionsannahme gilt.

585

586

Entfernen der Wurzel aus einem binren Suchbaum Algorithmus fr das Entfernen
Entfernen der Wurzel fhrt zur Konstruktion eines neuen binren Suchbaums. Darum: Finden eines Knotens, der an die Stelle der Wurzel gesetzt wird und die Kriterien fr einen neuen binren Suchbaum erfllt. Der Knoten mu grer als die Wurzel des linken Unterbaumes sein und kleiner als die Wurzel des rechten Unterbaumes.

Entfernen der Wurzel - Beispiel

16

15

10 9 13 14 15 18

24 9

10 14 13 18

24

Kandidaten

Situation vor dem Lschen


587

Situation nach dem Lschen


588

Entfernen der Wurzel aus einem binren Suchbaum Algorithmus fr das Entfernen
Es wird der Knoten mit der grten Beschriftung im linken Unterbaum genommen. Dieser Knoten wird entfernt und als Wurzel eingesetzt. Ist der linke Unterbaum einer Wurzel leer, nimmt man analog zur vorgestellten Methode das kleinste Element der rechten Wurzel. Ist der Unterbaum einer Wurzel leer, kann auch auf eine Umgestaltung des Baumes verzichtet werden: Wird die Wurzel entfernt, bildet der verbleibende Unterbaum wieder einen binren Baum.

Entfernen eines Knotens aus einem binren Suchbaum Wird ein innerer Knoten aus einem binren Suchbaum entfernt, stellt dieser Knoten die Wurzel eines Unterbaumes dar und diese Wurzel wird dann entfernt.

589

590

Durchlaufstrategien fr binre Suchbume Tiefendurchlauf: Hier wird von einem Knoten aus in die Tiefe gegangen, indem einer der Shne besucht wird und dann dessen Shne usw. Erst wenn man die Bltter erreicht hat, beginnt der Wiederaufstieg.
Preorder-Durchlauf Inorder-Durchlauf Postorder-Durchlauf

Dynamische Datenstrukturen

Binre Suchbume

Tiefendurchlauf / Preorder
void PreOrder() {PreOrder(wurzel); } private void PreOrder(Knoten aktuell) { if (aktuell != null) { System.out.println(aktuell.GibWert()); PreOrder(aktuell.GibLinks()); PreOrder(aktuell.GibRechts()); 10 } 14 9 }
13 Reihenfolge der besuchten Knoten: 16, 10, 9, 14, 13, 15, 24, 18
591 592

16

24 18 15

Breitendurchlauf: Mit dem Besuch eines Knotens werden auch seine Nachbarn besucht. Schichtweises Abtragen

Tiefendurchlauf / Inorder
void InOrder() { InOrder(wurzel); } private void InOrder(Knoten aktuell) { if (aktuell != null) { InOrder(aktuell.GibLinks()); System.out.println(aktuell.GibWert()); InOrder(aktuell.GibRechts()); } }
9 13 Reihenfolge der besuchten Knoten: 9, 10, 13, 14, 15, 16, 18, 24
593

Tiefendurchlauf / Postorder
void PostOrder() { PostOrder(wurzel); } private void PostOrder(Knoten aktuell) { if (aktuell != null) { PostOrder(aktuell.GibLinks()); PostOrder(aktuell.GibRechts()); System.out.println(aktuell.GibWert()); } 16 }
24 14 15 18 Reihenfolge der besuchten Knoten: 9, 13, 15, 14, 10, 18, 24, 16 9 13 10 14 15
594

16

10

24 18

Breitendurchlauf

Idee zur Realisierung des Breitendurchlaufs


Noch nicht besuchte Knoten werden in einer verketteten Liste gespeichert, so da der Knoten, der als nchster besucht wird, am Anfang der Liste steht. Wird ein Knoten besucht, so wird er aus der Liste entfernt und sein linker und sein rechter Sohn werden, falls vorhanden, in dieser Reihenfolge ans Ende der Liste angefgt. Dies geschieht solange, bis die Liste leer ist. Die Liste wird mit der Wurzel des Baumes initialisiert. Insgesamt wird also durch die Liste eine Warteschlange von Knoten aufgebaut: Der Knoten am Anfang der Warteschlange wird als nchster ausgedruckt. Der Knoten am Ende der Warteschlange ist als letzter hinzugefgt worden.
596

16

10 9 13 14 15 18

24

Reihenfolge der besuchten Knoten: 16, 10, 24, 9, 14, 18, 13, 15

595

Dynamische Datenstrukturen
16

Binre Suchbume

Breitendurchlauf durch einen binren Suchbaum


class BST { ... void Breitendurchlauf() {

Warteschlange fr die Breitensuche


24 nach Besuch des Knotens 10 16

10 9 13
ws

SohnListe ws = new SohnListe(); Knoten aktuell; ws.FgeAn(wurzel); while ((aktuell = ws.Entferne()) != null) { System.out.println(aktuell.GibWert());

14 15

18

null

10 9 13 15 14 18

24

if (aktuell.GibLinks() != null) ws.FgeAn(aktuell.GibLinks()); if (aktuell.GibRechts() != null) ws.FgeAn(aktuell.GibRechts()); }

nach Besuch des Knotens 16, vor Besuch des Knotens 10

ws

null

} ... }
598

597

Die Klasse SohnElem

Die Klasse SohnListe


class SohnListe { private SohnElem kopf, fu; SohnListe() { kopf = fu = null; } void FgeAn(Knoten an) { SohnElem neu = new SohnElem(an); if (fu != null) { fu.SetzeWeiter(neu); fu = neu; } else kopf = fu = neu; }

class SohnElem { private Knoten wert; private SohnElem weiter; SohnElem(Knoten k) { wert = k; weiter = null; } void SetzeWert(Knoten k) { wert = k; } Knoten GibWert() { return wert; } void SetzeWeiter(SohnElem s) { weiter = s; } SohnElem GibWeiter() { return weiter; } }
599

600

Die Klasse SohnListe


Knoten Entferne() { Knoten erster = null; if (kopf != null) { erster = kopf.GibWert(); kopf = kopf.GibWeiter(); if (kopf == null) fu = null; } return erster; } }

Kapitel 17.3
Graphen

601

Allgemeines zu Graphen Listen stellen eindimensionale Verkettungen von Informationen dar: Jeder Knoten einer Liste hat einen oder keinen Nachfolger. Binre Bume stellen eine zweidimdensionale Informationsverkettung dar: Jeder Knoten ist mit hchstens zwei Shnen verbunden. Graphen stellen fr jeden Knoten dar, in welcher Weise dieser mit anderen Knoten gerichtet verbunden ist.

Allgemeines zu Graphen Eine der originren Anwendungen ist die Darstellung rumlicher Beziehungen, Bume reichen hier nicht aus, weil es Beziehungen zwischen allen Knoten geben kann. Oft ist es so, da den Kanten zwischen zwei Knoten auch noch Attribute zugeordnet werden (Kosten, Entfernungen, etc.). Wenn die Beziehung zwischen zwei Knoten unabhngig von der Richtung ist (Erreichbarkeit zwischen Orten), dann reichen ungerichtete Kanten. Wenn die Beziehung von der Richtung abhngt (eine Stellung im Schach lt sich per Zug aus einer anderen erreichen), dann braucht man gerichtete Kanten.
604

Programm: Die Klasse SohnListe

603

Allgemeines zu Graphen

Definition Graph

Typische Methoden:
das Erzeugen eines neuen Graphen das Einfgen oder Lschen eines Knotens das Einfgen oder Lschen einer Kante den Test, ob ein Knoten vorhanden ist den Test, ob eine Kante vorhanden ist

G = (V, E) heit gerichteter Graph mit Knotenmenge V und Kantenmenge E, falls gilt: V (englisch: vertex, vertices) ist eine endliche Menge und E (englisch: edges) V V

Programm: Die Klasse SohnListe

605

606

Beispiel eines gerichteten Graphen


1 2 6 4

Definition Pfad Sei G = (V, E) ein gerichteter Graph, so besteht ein Pfad aus Knoten (p0, p1,, pk) von p0 nach pk fr k > 0 aus Knoten p0, , pk V, so da jedes Paar aufeinanderfolgender Knoten (pi, pi+1) eine Kante bildet. Dies gilt fr 0 i k-1. Ein Zyklus ist ein Pfad von einem Knoten zu sich selbst.

8 9

607

608

Definition Zusammenhang

Definition Zusammenhang Ein Teilgraph heit Zusammenhangskomponente, wenn er bzgl. der Zusammenhangseigenschaft (stark oder schwach) maximal ist, d.h. der Teilgraph kann nicht durch einen oder mehrere Knoten und/oder eine oder mehrere Kanten des Graphen erweitert werden, ohne diese Eigenschaft zu verlieren.

Ein gerichteter Graph heit stark zusammenhngend, wenn es zwischen je zwei Knoten des Graphen einen Pfad gibt. Ein gerichteter Graph heit schwach zusammenhngend, wenn es zwischen zwei Knoten immer einen Semiweg gibt. Ein Semiweg ist ein Pfad, wobei von der Richtung der Kanten abgesehen wird.

609

610

Speicherdarstellung von Graphen

Adjazenz von Knoten Ist n V ein Knoten im gerichteten Graphen (V, E), so heit {p V; (n, p) E} die Adjazenzliste zum Knoten n.

Graphen werden rechnerintern durch Adjazenzlisten oder Adjazenzmatrizen dargestellt werden.

Eine Alternative zu dieser Darstellung ist die Darstellung ber Boolesche Matrizen: Man definiere eine Matrix (ak,l)k,l V und setze:

ak,l :=((k,l) E)

611

612

Beispiel Adjazenzliste
Knoten Adjazenzliste 5 1, 3 (leer) 2, 8 2, 3, 7, 8 (leer) 7 6
613

Beispiel Adjazenzmatrix
Adjazenzmatrix 1 2 6 4

1 2 6 4

1 2 3 4 5 6 7 8 9

8 9

8 9

614

Adjazenz von Knoten Der Platzverbrauch von Adjazenzmatrizen ist unabhngig von der Zahl der Kanten pro Knoten. Bei n Knoten werden n2 Speicherpltze gebraucht. In Adjazenzmaztrizen lt sich schnell prfen, ob eine Kante vorhanden ist (indizierter Zugriff auf zweidimensionales Array). Adjazenzlisten brauchen Speicherplatz pro Kante. Wenn wenig Kanten vorkommen, dann wird auch wenig Platz gebraucht. Bei vielen Kanten mu man beim Suchen nach einer Kante erst eine ggf. lange Kantenliste durchlaufen.
615

Adjazenz von Knoten Deshalb folgende Daumenregel: Adjazenzlisten sind fr Graphen mit wenig Kanten pro Knoten geeignet. Adjazenzmatrizen sind fr dichte Graphen geeignet.

616

Klassen Knoten, ..., Graph


class Knoten { private int name; private KnotenListe adjazenz; private Knoten nchster; } class KnotenListe { private KnotenElem kopf, fu; } class KnotenElem { Knoten verweis; KnotenElem weiter; }
617

Listendarstellung gerichteter Graphen

class Graph { private Knoten erster; }

erster

1 2

4 3 5 7 8 9
618

Realisierung der Graph-Methoden Das Erzeugen eines neuen Graphen erfolgt durch den Aufruf eine Konstruktors. Das Hinzufgen eines Knotens ist eine Listenoperation auf der Liste der Knoten. Das Entfernen eines Knotens ist eine Listenoperation auf der Liste der Knoten und auf all den Adjazenzlisten, die einen Zeiger auf den zu entfernenden Knoten besitzen.
Aufwand!

Realisierung der Graph-Methoden Das Hinzufgen einer Kante ist eine Operation auf den Adjazenzlisten. Der Test, ob ein Knoten vorhanden ist, stellt eine Operation auf der Liste aller Knoten dar. Der Test, ob eine Kante vorhanden ist, stellt zunchst eine Operation auf der Liste aller Knoten - Ausgangsknoten der Kante finden - und anschlieend auf der entsprechenden Adjazenzliste dar.

619

620

Die Klasse Graph

Durchlaufen mit einmaligem Besuchen Ausdrucken aller Knotennamen Da Graphen keine vergleichbar regulre Struktur haben wie Bume kann man keine vergleichbaren Durchlaufstrategien angeben. Durch Zyklen kann man beispielsweise auf bereits besuchte Knoten kommen. Die Klasse Knoten wird deshalb erweitert um ein Attribut warDa.

class Graph { private Knoten erster; void Graph() { } void FgeKnotenEin(int kno) { } void EntferneKnoten(int kno) { } void FgeKanteEin(int start, int ende) { } boolean IstKnotenDa(int kno) { } boolean IstKanteDa(int kno1, int kno2) { } }

621

622

Ergnzung der Klasse Knoten

Durchlaufen mit einmaligem Besuchen Problem: Was passiert, wenn noch mal ausgedruckt werden soll? Idee: Umdrehen der Werte. Das Einfgen mu dann aber entsprechend arbeiten und die Belegung der warDa-Attribute bercksichtigen. Eine ganz einfache Ausgabestrategie wre das Durchlaufen der Knotenliste, allerdings verliert man dann jeden Aufschluss ber die Graphenstruktur. Deshalb wird oft ein so genannter Tiefendurchlauf bentigt. Hierdurch werden zusammenhngende Teilgraphen auch zusammenhngend ausgegeben.
623 624

class Knoten { private boolean warDa; void SetzeWarDa(boolean wd) { warDa = wd; } boolean GibWarDa() { return warDa; } }

Durchlaufen mit einmaligem Besuchen Erst wenn in einem Teilgraph alle Knoten besucht sind, wird ber nchster der nchste Knoten aufgesucht. Wir versuchen von einem Knoten alle erreichbaren Knoten zu finden. Dabei steigen wir erst hinab und erst wieder hinauf (zum Vorgngerknoten), wenn nichts mehr gefunden wird. Beispiel:

Durchlaufen mit einmaligem Besuchen Das Durchlaufen der Adjazenzlisten wird durch den rekursiven Aufruf von BesucheTeil fr die in der Adjazenzliste vorkommenden Knoten unterbrochen. Die Methoden InitIteration und GeheWeiter sorgen dafr, dass die Adjazenzliste dennoch nicht jedes Mal von vorne durchlaufen werden mu.

625

626

Die Klasse KnotenListe


class KnotenListe { private KnotenElem position = null; Knoten InitIteration() { position = kopf; return position.Gibverweis(); } Knoten GeheWeiter() { position = (position != null? Position.GibWeiter(): null); return position.GibVerweis(); } }
627

Tiefensuche in gerichteten Graphen


class Graph { void Durchlaufe() { Knoten inListe; boolean besucht = !erster.GibWarDa(); inListe = erster; while (inListe != null) { System.out.println(Teilgraph:); if (inListe.GibWarDa() != besucht) BesucheTeil(inListe, besucht); inListe = inListe.GibWeiter(); } }
628

Programm: Die Tiefensuche in einem gerichteten Graphen (1/2)

Tiefensuche in gerichteten Graphen


private void BesucheTeil(Knoten aktuell, boolean besucht) { KnotenListe adjazenz; Knoten inAdjazenz; aktuell.SetzeWarDa(besucht); System.out.println(aktuell.GibWert()); adjazenz = aktuell.GibAdjazenz(); inAdjazenz = adjazenz.InitIteration(); while (inAdjazenz != null) if (inAdjazenez.GibWarDa() == besucht) inAdjazenz = adjazenz.GeheWeiter(); else BesucheTeil(adjazenz.GeheWeiter(), besucht); Programm: Die Tiefensuche in einem gerichteten Graphen (1/2) } 629 }

Kapitel 17.4
Schlangen / Queues

Allgemeines zu Queues
16 16

Allgemeines zu Queues Queues werden realisiert ber Listen, auf die mittels der 10 24 genanten Methoden zugegriffen wird. nach Besuch des Knotens 10 Da nur ber diese Methoden zugegriffen wird, ist sichergestellt, 18 14 9 16 da keine anderen, nicht Queue-kompatiblen Manipulationen 13 stattfinden. 15
ws null

Queues sind wichtig fr die Abarbeitung von Aufgaben in der 10 24 Reihenfolge FIFO (first-in-first-out), wie an der nach Besuch des Knotens 10 Supermarktkasse 18 14 9 16 Typische Methoden:
ws

13 15 Prfen auf Geflltheit (bei beschrnkten Schlangen) 10 Prfen auf Leerheit null Anfgen 15 9 vor Besuch des Knotens 10 Entfernen (am Anfang) 13 14 Liefern des ersten Elementes Ermittlung der Lnge
ws

24 18

10 9 13 15 14 18

24

vor Besuch des Knotens 10

null Programm: Die Klasse SohnListe

ws

null Programm: Die Klasse SohnListe

631

632

Allgemeines zu Stacks Stacks sind ein weiteres Beispiel fr einen abstrakten Datentyp und den Umgang mit verketteten Listen. Stacks basieren auf den Elementen wie sie in linearen Listen verwendet wurden. Das letzte in einem Stack abgelegte Element wird als erstes herausgenommen. Elemente dieser Datenstruktur werden nach dem LIFO-Prinzip (Last In First Out) verwaltet.

Kapitel 17.5
Kellerspeicher / Stapel / Stacks

634

Methoden auf Stacks Initialisieren eines leeren Stacks. Testen, ob der Stack leer ist. Ablegen eines Elements auf dem Stack (push-Operation) Inspektion des obersten Elementes (top-Operation) Entfernen des obersten Elementes des Stacks (pop-Operation)

Darstellung der Stack-Methoden

push 19

19 4 17 9 8

pop push 24

4 17 9 8

pop

24 17 9 8

17 9 8

635

636

Die Klasse Stack


class Stack { private Element derStack; Stack() { derStack = null; } Stack(int i) { derStack = new Element(i); } boolean empty() { return derStack == null; } void push(int i) { derStack = new Element(i, derStack); } int pop() { int topWert = (derStack != null ? derStack.GibWert() : 0); derStack = derStack.GibWeiter(); return topWert; } int top() { return (derStack != null ? derStack.GibWert() : 0); } } 637

java.util.Stack
Klasse java.util.Stack extends java.util.Vector
Stapel auf Objekten basierend mit allen geerbten Funktionalitten von Vector Sehr mchtig und sehr langsam => fr reine Stackfunktionalitt Eigenimplementierung besser public Stack()
Konstruktor fr leeren Stack

public Object push(Object item)


Legt Objekt auf Stapelspitze

public Object pop() throws EmptyStackException


Holt Objekt von Stapelspitze (und entfernt es)

public Object peek() throws EmptyStackException


Gibt Referenz von Objekt auf Stapelspitze, ohne es zu entfernen

public boolean empty()


Testet, ob Stack leer ist
638

java.util.Stack - Beispiel
java.util.Stack stapel = new java.util.Stack(); stapel.push("Text"); stapel.push(new Integer(2)); stapel.push(new Double(1e100)); System.out.println("Gesamt: " + stapel); try { while (!stapel.empty()) System.out.println("Objekt: " + stapel.pop()); } catch (java.util.EmptyStackException e) { }

Kapitel 17.6
Mengen

Ausgabe:
Gesamt: Objekt: Objekt: Objekt: [Text, 2, 1.0E100] 1.0E100 2 Text

639

Allgemeines zu Mengen ist nicht erforderlich, weil jeder Mengen kennt :-) Interessant ist dann nur die Frage, wie Mengen rechnerintern dargestellt werden. Dazu gibt es zwei grundlegende Mglichkeiten:
Charakteristische Vektoren Hashing-Tabellen

Charakteristische Vektoren Fr jedes potentielle Mengenelement wird in einem ArrayEintrag des Typs Boolean festgehalten, ob es in der Menge ist oder nicht. Vorteil: einfache Prfung auf Enthaltensein Vorteil: einfache Durchfhrung von Mengenoperationen Nachteil: enorme Platzverschwendung, gerade bei vielen potentiellen Elementen und kleinen Mengen

641

642

Charakteristische Vektoren Beispiel:


Grundmenge: alle potentiellen 600 Programmierungsstudenten (Erstsemester Informatik, Physik, Mathe) Menge der am Vorlesungsende regelmig teilnehmenden Studierenden, voraussichtlich 300. Studierende seien gegeben durch Name, Fach Wir nehmen an, dass der Name eindeutig ist.

Charakteristische Vektoren Beispiel:


Grundmenge: alle Erstligavereine im DFB, also 18 Vereine seien gegeben durch offiziellen Namen, letzte Meisterschaft, letzter internationaler Wettbewerb, Bundesland Darzustellende Mengen: die in bestimmten Pokalrunden vertretenden Verein die Menge der Meistermannschaften, die Menge der Mannschaften aus NRW, die Meistermannschaften aus NRW mit internationalem Titel.

Das Prfen, ob Studierende nach am Ende von Programmierung und RS noch in der Vorlesung sind, ist dann eine einfach Bitoperation (UND) Schema der aktuellen Teilnehmermenge:
643

644

Hashing Die begrenzte Einsetzbarkeit von charakteristischen Vektoren zeigt sich an sehr groen Mengen. Beispiel:
Grundmenge: Liste aller Wrter im Duden Darzustellende Menge: die Menge aller Wrter auf den Prog-Folien

Hashing Eine Hash-Funktion bildet die darzustellende Menge (=Teilmenge der Grundmenge) auf eine feste Anzahl von Speicherpltzen ab. Da man nicht fr jedes Element der Grundmenge einen Speicherplatz hat, werden mehrere Elemente der Grundmenge auf die gleiche Position abgebildet. Schema einer Hash Table:

Wenn wir nun die Speicherplatzverschwendung begrenzen wollen, dann stellen wir nicht mehr fr jedes potentielle Element der Menge einen Speicherplatz zur Verfgung, sondern nur noch eine kleine Anzahl von Speicherpltzen, auf die die Elemente der darzustellenden Menge abgebildet werden.
645

646

Hashing B sei die Anzahl der Speicherpltze. Eine Hash-Funktion h arbeitet auf den Elementen der Grundmenge und bildet diese auf einen Wert zwischen 0 und B-1 ab. Auf Grund dieser Eigenschaft nennt man HashFunktionen auch Schlsseltransformationen. B wird die Anzahl der Buckets der Hash Table genannt. h(x) ist der Bucket, in dem das Element x der Grundmenge zu finden ist. Wenn die Elemente Integer-Zahlen sind, dann ist h(x) = x mod B eine sinnvolle Hash-Funktion
647

Hashing Wenn die Elemente Strings sind, dann kann man die IntegerWerte der Character addieren, die Summe ganzzahlig durch B teilen und hat damit eine sinnvolle Hash-Funktion

648

Hashing Die Qualitt einer Hash-Funktion hngt davon ab, ob sie die Elemente der Grundmenge gleichmig auf die Speicherpltze verteilt, d.h. fr beliebige darzustellende Teilmengen aus der Grundmenge soll eine gelichmige Verteilung auf die Buckets stattfinden. Konkreter:
Eine Hash-Funktion sollte surjektiv sein, also auf alle Buckets abbilden. Sie sollte die Elemente der Grundmenge gleichmig auf die Buckets verteilen. Sie sollte effizient zu berechnen sein.

Hashing Beispiel:
Grundmenge: Fuballvereine, darzustellende Menge: DFB-Viertelfinal-Teilnehmer, 8 Speicherpltze, Zuordnung ber Bundesland. Das knnte kollisionslos klappen. Das kann aber auch ganz daneben gehen.

Beispiel: Monatsnamen auf 17 Buckets Beispiel: Wrter und ASCII-Summen

649

650

Hashing Der Lastfaktor16 einer Hash Table ergibt sich bei B Speicherpltzen und einer Kardinalitt M der darzustellenden Menge 10 durch M/B. 24
16 Beispiel: Viertelfinalvereine, Monate, Wrter 13 15 10 24
ws

Hashing
16

nach Besuch des Knotens 10

Beim geschlossenen Hashing kann pro Bucket nur eine kleine, 10 24 fest definierte Anzahl von Elementen aufgenommen werden.
nach Besuch des Knotens 10

14

18

ws null Beim offenen Hashing wird zu jedem Bucket eine dynamische 18 15 9 Datenstruktur (typischerweise eine verkettet Liste) benutzt. vor Besuch des Knotens 10

vor Besuch des Knotens 10

Hier braucht man dann rehashing-Verfahren, die16 Fall des im 13 15 berschreitens der Grenze ein freies Pltzchen suchen. Das rehashing kann dabei kaskadieren. 10 24 null Die feste Begrenzung kann dabei zu mhevollem Suchen fhren. 18
9 15 13 14

14

18

13

14

ws

null Programm: Die Klasse SohnListe

ws

null Programm: Die Klasse SohnListe

651

652

Die Klasse java.util.Hashtable


Hilfsklassen

Kartenverwaltung mit Hashtable


import java.util.*;

Hilfsklassen

Kartenverwaltung: Zwei Listen (Kartennummern, PINs), die parallel durchlaufen werden mssen besser: Datenstruktur, die Schlssel und Wert gemeinsam speichert Lsung: java.util.Hashtable

Importieren von Klassen :


public class Kartenverwaltung { private Hashtable karten; ...

* importiert alle Klassen eines Packages

public class Hashtable extends Dictionary ... { ... public boolean contains(Object value) {...}; public boolean containsKey(Object key) {...}; public Enumeration elements() {...}; public Enumeration keys() {...}; public Object put(Object key, Object value) {...}; public Object get(Object key) {...}; public Object remove(Object key) {...}; ... }

public void erfasseWeiteresKonto (String kartennummer, String pin, Girokonto konto) { karten.put(kartennummer, pin); ... } public boolean pinIstGltig (String kartennummer, String pin) { String geheim = (String) karten.get(kartennummer); return (pin.equals(geheim)); } }
653 654

bung: Hashtable
Motivation
Verwenden von Hashtable statt Arrays Schneller Zugriff auf die gespeicherten Daten

Hilfsklassen

bung: Hashtable
import java.util.*; public class Kartenverwaltung { private Hashtable karten; private Hashtable konten; public Kartenverwaltung(){ karten = new Hashtable(); konten = new Hashtable(); }

Hilfsklassen

Aufgabe
Verwenden Sie zur Speicherung der Konten ebenfalls eine Hashtable
berlegen Sie sich dazu, was als Schlssel und was als Eintrag verwendet werden kann

ndern Sie die Klasse Kartenverwaltung Fgen Sie eine Methode hinzu, die zu allen Konten den Inhaber ausgibt Testen Sie die neue Kartenverwaltung Verwenden Sie hierzu die alte Testklasse Erweitern Sie die Testklasse zum Testen der neuen Methode
655

public void erfasseWeiteresKonto (String kartennummer, String pin, Konto einKonto) { karten.put(kartennummer, pin); konten.put(kartennummer, einKonto); }
656

bung: Hashtable

Hilfsklassen

Zusammenfassung

Hilfsklassen

public Konto holeKonto (String kartennummer) throws KontoNichtVorhandenException { Konto k = (Konto) konten.get(kartennummer); if (k == null) throw new KontoNichtVorhandenException(); return (k); } public boolean pinIstGltig (String kartennummer, String pin){ String geheimzahl = (String) karten.get(kartennummer); return (pin.equals(geheimzahl)); } public void listeInhaber() { for (Enumeration el=konten.elements(); el.hasMoreElements(); ) { Konto k = (Konto) el.nextElement(); Bildschirm.gibAus(k.holeInhaber().toString()); } }
657

Dynamische Datenstrukturen sind wesentlich fr fast alle InformatikProbleme. Es gibt eine natrliche Hierarchie dieser Strukturen. Alle dynamischen Strukturen verfgen ber strukturell hnliche Methoden. In Java sind vordefinierte Lsungen fr die grundlegenden dynamischen Strukturen verfgbar, und zwar im Paket java.util
Listen werden mit java.util.Vector realisiert Stapel werden mit java.util.Stack realisiert Realisierung von Tabellen (mit zwei Spalten) mit java.util.Hashtable Durchlauf durch Listen mit java.util.Enumeration

658

java.io
java.applet java.awt java.beans java.io java.lang java.math java.rmi java.security java.sql java.util javax.swing (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.0) (JDK 1.2)

Die Java Klassenbibliotheken


Java-Applets (fr WWW-Browser) AWT-Komponenten Beans-Development Input / Output / Datenstrme Basispackage fr Java Zahlen groer Genauigkeit Remote Method Invocation Sicherheit, Kryptographie JDBC-Paket Verschiedene Hilfsklassen Swing-Komponenten Fr JDK 1.1.x: com.sun.java.swing (JDK 1.2) CORBA-Schnittstelle

Kapitel 18
Ein- und Ausgabe (java.io)

org.omg.CORBA

660

java.io - Ein- und Ausgaben, Streams


Ergebnisse der Durchfhrung von Programmen mssen zuweilen persisten gemacht werden. Von Persistenz eines Objektes spricht man, wenn das Objekt das Ende einer Programmausfhrung berlebt und von einem anderen Programm (oder einer anderen Ausfhrung des gleichen Programms) benutzt werden kann. Persistent werden Objekte, indem man sie speichert. Speicherort kann das Dateisystem sein oder auch eine Datenbank (dazu mehr in der Vorlesung Informationssysteme). Die Beschreibung der Struktur persistenter Objekte wird das Format genannt. Wie lassen sich die Fuballvereine persistent machen?

java.io - Ein- und Ausgaben, Streams


Und wie lassen sich solche persistent gemachten Objekte wieder einlesen? Wie einigen sich Schreiber und Leser auf Formate? Java-Ansatz: Eine Reihe von Formaten wird in Form von Klassen und Interfaces vordefiniert. Hierzu gehrt das eigentliche Format und natrlich auch der schreibende / lesende Zugriff.

661

662

java.io - Ein- und Ausgaben, Streams

java.io - Ein- und Ausgaben, Streams


In diesem Kapitel:
Streams: Merkmale, Klassen, einfache Verwendung Ablegen der Ergebnisse eines binren Suchbaums

Streams
Ein Objekt, aus dem eine Sequenz von Bytes gelesen werden kann, ist ein Eingabe-Stream. Das Schreiben von Bytes erfolgt in Ausgabe-Streams. Die Implementierung erfolgt mit Hilfe der abstrakten Klassen InputStream und OutputStream Character (Unicode) werden analog ber die abstrakten Klassen Reader und Writer behandelt.

663

664

java.io - Ein- und Ausgaben, Streams


Ein- und Ausgaben werden ber Streams realisiert (auer GUI-Komponenten!) Streams (Strme) sind sequentiell organisierte Datenmengen. Streams sind Objekte, in die Daten hineingegeben bzw. aus denen Daten ausgelesen werden knnen. Mittels des Pakets java.io werden unterschiedliche Streams untersttzt, so dass das in vielen Programmiersprachen mhevolle Thema der Dateibehandlung vereinfacht wird. Grob:
InputStream als Superklasse fr Eingabestrme, also Strme, aus denen gelesen wird. OutputStream als Superklasse fr Ausgabestrme, also Strme, in die geschrieben wird.
665

java.io - Ein- und Ausgaben, Streams


Unterschiedliche Formate von Streams fr
Strme von Bytes / Strme von Unicode-Zeichen Schreiben oder Lesen Unterschiedliche Ziele bzw. Quellen: Dateien Standardeingabe und -ausgabe Andere Klassen, wie z.B. Strings Piped-Streams, in denen Schreibe- und Lesestreams gepuffert verbunden sind gefilterte Streams, in denen Inhalte verndert werden knnen Streams fr sicheren Datenaustausch zwischen Threads Objektserialisierung

666

java.io - Ein- und Ausgaben, Streams


Von besonderer Bedeutung: Filter Ein Filter verbirgt den Zugriff auf einen Strom und gruppiert (filtert) die von diesem gelesenen Informationen durch geeignete Methoden. Der Filter DataInputStream stellt beispielsweise Methoden bereit, die als Ergebnis des Lesevorgangs einen Wer eines primitiven Typs liefern. Der Filter FileInputStream liefert einzelne Zeichen. Durch diesen vordefinierten Zugriff wird die Detailkenntnis des Formats entbehrlich! 667

java.io - Ein- und Ausgaben, Streams


In Java wird strikt unterschieden zwischen:
der Manipulation der Inhalte einer Datei und der nderung des organisatorischen Rahmens (Namensnderung, ffnen, Schlieen etc.) Inhaltsnderungen basieren auf Methoden der Klasse

InputStream, OutputStream
nderungen der Rahmenbedingungen basieren auf Methoden der Klasse File Hinweis: Portabilitt!

668

java.io
java.io.OutputStream
abstrakte Klasse Superklasse aller Byte Output Streams

Die Java Klassenbibliotheken

java.io.OutputStream
Abstrakte Klasse java.io.OutputStream:
public abstract void write(int b) throws IOException
Schreibt ein Byte b in den Stream mu von abgeleiteter Klasse berschrieben werden

public void close() public void flush() public void write(byte[] b)

public void write(byte[] b) throws IOException


Schreibt ein Array von Bytes Falls nicht berschrieben, wird write(int b) benutzt

public void write(byte[] b, int off, int len) throws IOException


definiert grundlegende Methoden fr alle Byte Output Stream Klassen close unterbricht die Verbindung zwischen Programm und Datei
Zustzlich lassen sich Anfang und Ende bestimmen

public void flush() throws IOException


Kann berschrieben werden, um eine Entleerung eines Puffers gewhrleisten zu knnen

669

670

java.io
java.io.InputStream
abstrakte Klasse Superklasse aller Byte Input Streams

Die Java Klassenbibliotheken

java.io.InputStream
Abstrakte Klasse java.io.InputStream:
public abstract int read() throws IOException
Liest ein Byte aus dem Stream mu von abgeleiteter Klasse berschrieben werden

public int read(byte[] b) throws IOException


public int available() public void close() public void read(byte[] b) public void reset()
Liest ein Array von Bytes Falls nicht berschrieben, wird read() benutzt

public int read(byte[] b, int off, int len) throws IOException


Zustzlich lassen sich Anfang und Ende bestimmen

public int available() throws IOException


definiert grundlegende Methoden fr alle Byte Input Stream Klassen
Bestimmt Anzahl der noch lesbaren Bytes

public void close() throws IOException


Schliet Stream und lt belegte Systemresourcen frei

671

672

java.io
java.io.Writer

Die Java Klassenbibliotheken

java.io.Writer
Abstrakte Klasse java.io.Writer:
public void write(int c) throws IOException
Schreibt ein Zeichen c in den Stream. Untere 16 Bit werden benutzt.

abstrakte Klasse Superklasse aller Character Output Streams


public void close() public void flush() public void write(char[] c)

public void write(char[] cbuf) throws IOException


Schreibt ein Array von Zeichen

public abstract void write(char[] cbuf, int off, int len) throws IOException
Zustzlich lassen sich Anfang und Ende bestimmen

public void write(String str) throws IOException


definiert grundlegende Methoden fr alle Character Output Stream Klassen
Ausgabe eines Strings

public abstract void flush() throws IOException


Mu berschrieben werden, soll eine Entleerung eines eventuellen Puffers gewhrleisten
673 674

java.io
java.io.Reader

Die Java Klassenbibliotheken

java.io.Reader
Abstrakte Klasse java.io.Reader:
public int read() throws IOException
Liest ein einzelnes Zeichen aus dem Stream -1 wird bei Stream-Ende zurckgegeben

abstrakte Klasse Superklasse aller Character Input Streams


public void close() public void read(char[] c) public void reset()

public int read(char[] cbuf) throws IOException


Liest ein Array von Zeichen Bis Eingabe erhltlich ist, wird gewartet

public abstract int read(char[] cbuf, int off, int len) throws IOException
Zustzlich lassen sich Anfang und Ende bestimmen

public boolean ready() throws IOException


definiert grundlegende Methoden fr alle Character Input Stream Klassen
Fragt ab, ob der Stream fertig ist, um ausgelesen zu werden

public void close() throws IOException


Schliet Stream und lt belegte Systemresourcen frei

675

676

Stream Sorten
Strme von Bytes (z. B. fr Byte[] )
Schreibende Streams sind Unterklassen von OutputStream Lesende Streams sind Unterklassen von InputStream

InputStream Hierarchy

java.io

InputStream ByteArray InputStream File InputStream Filter InputStream Piped InputStream Sequence InputStream StringBuffer InputStream

Strme von Unicode-Zeichen (z. B. fr String)


Schreibende Streams sind Unterklassen von Writer Lesende Streams sind Unterklassen von Reader

Abgeleitete Klassen fr spezifische Zwecke sollten Namen haben, die auf Reader, Writer, InputStream oder OutputStream enden
=> Sie sind so einfach in die richtige Kategorie einzuordnen

677

678

Filter InputStream Hierarchy


Filter InputStream

java.io

Output Stream Hierarchy

java.io

Bufferd InputStream Digest InputStream

Data InputStream

OutputStream

Checked InputStream

LineNumber InputStream Inflater InputStream Pushback InputStream ByteArray OutputStream File OutputStream Filter OutputStream Piped OutputStream

GZIP InputStream

ZIP InputStream
679

680

Filter OutputStream Hierarchy


Bufferd OutputStream Filter Output Stream

java.io

Benutzung eines I/O Stream


Ein FileInputStream ist ein I/O stream, der an eine Datei gekoppelt ist:
FileInputStream f = new FileInputStream("myfile.dat"); byte b = f.read();

Data OutputStream

Checked OutputStream Deflater OutputStream Digest OutputStream

PrintStream

Ein DataInputStream verfgt ber Methoden, um numerische Typen zu lesen:


DataInputStream d = irgendwas; double a = d.readDouble();

GZIP OutputStream

ZIP OutputStream
681

682

Kombination von Stream-Filtern


FileInputStream kann keine Zahlen lesen, DataInputStream knnen nicht auf Dateien operieren
FileInputStream f = new FileInputStream("myfile.dat"); DataInputStream d = new DataInputStream(f); double a = d.readDouble();

Eigenschaften von Streams


read() und write() werden selten direkt benutzt. read() und write()(direkt oder indirekt benutzt) blockieren Threads. available() wird benutzt, um Blockierungen durch read() zu vermeiden.

Streams sollten mit close beendet werden. Streams knnen mit flush geleert werden.

Diese Kombination ist in den meisten I/O-Anwendungen ntig.

683

684

Unicode Streams
Unicode Streams benutzen Klassen, die von Reader und Writer abgeleitet sind.

Reader hierarchy
Reader Buffered Reader

java.io

StringReader CharArray Reader FilterReader PipedReader InputStream Reader

Reader
public abstract int read() throws IOException

Writer
public abstract void write(int b) throws IOException
LineNumber Reader Pushback Reader

FileReader

685

686

Writer hierarchy
Writer Buffered Writer CharArray Writer FilterWriter OutputStream Writer

java.io

Schreiben von Text


Benutzung eines PrintWriter
PrintWriter out = new PrintWriter (new FileWriter("myfile.txt"));

StringWriter

PrintWriter PipedWriter

out.println("Hello world");

Die Methoden print() und println() werden durch Instanzen von PrintWriter implementiert.
FileWriter

687

688

Lesen von Text


Verwendet BufferedReader Klasse Liest Zeile fr Zeile und parsed diese.
BufferedReader in = new BufferedReader( new FileReader("myfile.txt")); String s; while ((s = in.readLine()) != null) {

java.io
java.io.File

Die Java Klassenbibliotheken

Objekte werden erzeugt, um Dateien erzeugen, ffnen und schlieen zu knnen

public void erzeugeDatei { File datei = new File(Test.txt); System.out.println(Dateiname: + datei.getName()); }

Ausgabe:
Dateiname: Test.txt

process s;
}

689

690

java.io.File
Klasse java.io.File
Objekte werden erzeugt, um Dateien zu Erzeugen, zu ffnen und zu schlieen. Dateisystem kann dem SecurityManager unterliegen

java.io.File
Filesystem-Handhabung:
public boolean delete() Lscht Datei oder Verzeichnis public void deleteOnExit() Lscht bei Beendigung der Virtual Machine Flag wird gesetzt, welches nicht zurckgenommen werden kann public boolean mkdir() Erstellt Verzeichnis public boolean mkdirs() Erstellt Verzeichnis und eventuell bentigte, nicht existierende Mutterverzeichnisse

Konstruktor: public File(String pathname)throws NullPointerException


Erzeugt Objekt ber Pfadnamen

Prfung von Eigenschaften: public boolean exists() public boolean canRead() public boolean canWrite() public boolean isFile() public boolean isDirectory() public boolean isHidden() public long length()

691

692

FileWriter
Klasse java.io.FileWriter
Indirekt abgeleitet von java.io.Writer Konstruktoren: public FileWriter(File file) throws IOException public FileWriter(String fileName, boolean append) throws IOException
append == true: Daten sollen angehngt werden

FileReader
Klasse java.io.FileReader
Indirekt abgeleitet von java.io.Reader Konstruktoren: public FileReader(File file) throws IOException public FileReader(String fileName) throws IOException

public FileWriter(String fileName) throws IOException

693

694

FileOutputStream
Klasse java.io.FileOutputStream
Abgeleitet von java.io.OutputStream Konstruktoren:

FileInputStream
Klasse java.io.FileInputStream
Abgeleitet von java.io.InputStream Konstruktoren:

public FileOutputStream(File file) throws IOException public FileOutputStream(String fileName, boolean append) throws IOException
append == true: Daten sollen angehngt werden

public FileInputStream(File file) throws IOException public FileInputStream(String fileName) throws IOException

public FileOutputStream(String fileName) throws IOException

695

696

Beispiel FileWriter
try { FileWriter out = new FileWriter("Datei.txt"); out.write("Erste Zeile\n"); out.write("Zweite Zeile\n"); out.close(); } catch (IOException e) { System.out.println("Fehler: " + e); }

Beispiel FileReader / StringWriter


try { FileReader in = new FileReader("Datei.txt"); StringWriter sout = new StringWriter(); int c; while ((c = in.read()) != -1) // Solange Ende nicht erreicht sout.write(c); System.out.println(sout); // gesamter Inhalt in string // gewandelt, inklusive der // Zeilenumbrche } catch (IOException e) { System.out.println("Fehler: " + e); }

Es entsteht eine Datei mit entsprechendem Inhalt

Ausgabe:
697

Erste Zeile Zweite Zeile

698

Unterschiedliche Streams
Andere Sorten von Streams funktionieren hnlich: Zeichen- Streams Hauptspeicher Pipe File Byte Streams

Beispiel: Zhlen von Zeichen in Dateien


Typische Struktur des Programms:
Identifikation der Datei und berprfung ihrer Existenz implizites ffnen durch den Aufruf eines Konstruktors fr einen Strom Bearbeiten des Inhalts und Schlieen (hier implizit am Programmende)
import java.io.*;

CharArrayReader ByteArrayInputStream CharArrayWriter ByteArrayOutputStream StringReader StringWriter PipedReader PipedWriter FileReader FileWriter StringBufferInputStream PipedInputStream PipedOutputStream FileInputStream FileOutputStream

class Auswertung { public static void main(String[] args) throws IOException { InputStream eingabedatei = null; StringBuffer dateiname = new StringBuffer();
699 700

Beispiel: Zhlen von Zeichen in Dateien


// Datei bestimmen if (args.length == 0) { while (dateiname.length() == 0) { System.out.println("Bitte Dateinamen angeben: "); char zeichen; boolean wortende = false; do { zeichen = (char)System.in.read(); wortende = (zeichen == ' ' || zeichen == '\n'); if (!wortende) dateiname.append(zeichen); } while (!wortende); } } else dateiname.append(args[0]);

Beispiel: Zhlen von Zeichen in Dateien


try { eingabedatei = new FileInputStream(dateiname.toString()); } catch (FileNotFoundException f) { System.out.println("Datei " + dateiname + " nicht vorhanden!"); System.exit(1); }

701

702

Beispiel: Zhlen von Zeichen in Dateien


// Datei auswerten int nchstesZeichen; int zeilen = 0, andereZeichen = 0, leerzeichen = 0; while ((nchstesZeichen = eingabedatei.read()) != -1) { switch ((char)nchstesZeichen) { case '\n': zeilen++; break; case ' ': leerzeichen++; break; default: andereZeichen++; } } // Auswertung ausgeben System.out.println("Auswertung der Datei " + dateiname); System.out.println("Zeilen: " + zeilen); System.out.println("Leerzeichen: " + leerzeichen); System.out.println("andere Zeichen: " + andereZeichen); } }
703

Erluterungen zur Klasse Auswertung


Die Referenz eingabedatei verwaltet bei der Ausfhrung des Programms die zu analysierende Datei, der variable Text StringBuffer dateiname ihren Namen. Parameter, die beim Aufruf eines Programms angegeben werden, werden durch den Parameter args (Feld von Texten) an die Methode main bergeben.

704

Erluterungen zur Klasse Auswertung


Falls kein Parameter bergeben wurde, wird der Dateiname zeichenweise eingelesen. Innerhalb des Paketes java.lang steht eine Klasse System zur Verfgung, die ein ffentliches, statisches Attribut mit dem Namen out hat. out ist eine Referenz auf ein Objekt der Klasse PrintStream, die eine Unterklasse von FilterOutputStream ist.

Klasse PrintStream
PrintStream ist (indirekt) von OutputStream abgeleitet Es werden print- und println-Methoden fr Objekte und smtliche simple Datentypen zur Verfgung gestellt.
println-Methode hngt im Gegensatz zur print-Methode ein Zeilenumbruch bei jedem Aufruf an.

Im Package System sind statische Attribute definiert:


public static final PrintStream out public static final PrintStream err public static final InputStream in //Standard-Out //Standard-Error //Standard-In

Aus diesem Grunde geschieht Ausgabe mit System.out.println(...)


705 706

Objektserialisierung
Serialisierung bedeutet, Objekte in einen Stream zu schreiben und Objekte aus einem Stream zu lesen Schreiben geschieht mit java.io.ObjectOutputStream
Unterklasse von java.io.OutputStream

Konstruktoren fr Object-Streams
Konstruktoren fr ObjectOutputStream / ObjectInputStream:
public ObjectOutputStream(OutputStream out) throws IOException public ObjectInputStream(InputStream in) throws IOException, StreamCorruptedException

Lesen geschieht mit java.io.ObjectInputStream


Unterklasse von java.io.InputStream

=> Objekte knnen durch beliebige InputStreams und OutputStreams geschickt werden Um Objekte in Dateien zu speichern, wird FileOutputStream und FileInputStream benutzt
707 708

Interface Serializable

Kontrolle ber Serialisierung (Teil 1)


Von Objekten werden alle serialisierbaren Attribute mit serialisiert
Bei komplexen Datenstrukturen, wie Bumen oder Listen mu nur das Basisobjekt serialisiert werden, weil automatisch alle referenzierten Objekte mit bercksichtigt werden.

Klassen, deren Objekte serialisierbar sein sollen, mssen das Interface java.io.Serializable implementieren Interface java.io.Serializable ist leer, hat also keine Methoden oder Attribute
=> Interface wird nur als Markierung benutzt

Viele Klassen in den Standardbibliotheken sind serialisierbar (Achtung, nicht alle)

Statische Attribute werden nicht serialisiert Attribute, die nicht zum persistenten Teil von Objekten gehren, knnen bei Deklaration mit transient gekennzeichnet werden. Als transient werden die abgeleiteten Attribute gekennzeichnet.
709 710

Methoden der Object-Streams


ObjectOutputStream:
public final void writeObject(Object obj) throws IOException
Schreibt serialisierbares Objekt in den Stream

Beispiel
try { FileOutputStream out = new FileOutputStream("Persistenz.txt"); ObjectOutputStream objout = new ObjectOutputStream(out); objout.writeObject("Text"); objout.writeInt(200); objout.flush(); out.close(); FileInputStream in = new FileInputStream("Persistenz.txt"); ObjectInputStream objin = new ObjectInputStream(in); String zeichen = (String)objin.readObject(); int zahl = objin.readInt(); in.close();

public void writeDouble(double d) throws IOException public void writeLong(long l) throws IOException
Viele andere primitive Datentypen knnen geschrieben werden

ObjectInputStream:
public final Object readObject() throws OptionalDataException, ClassNotFoundException, IOException public double readDouble() throws IOException
viele andere primitive Datentypen knnen gelesen werden
711

Ausgabe:
System.out.println(zeichen + "\n" + zahl); } catch (IOException e) { } catch (ClassNotFoundException e) { } Text 200
712

Kontrolle ber Serialisierung (Fortsetzung)


Es gibt fr Klassen, die serialisiert werden sollen, die Mglichkeit, den Vorgang selbst zu bestimmen da
Zusatzinformationen mit serialisiert werden sollen, um Konsistenz mit Umgebung sicherzustellen (z. B. statische Attribute)
Hier kann Standardserialisierung erweitert werden Mit wenig Aufwand mglich

Kontrolle ber Serialisierung


Kontrolle von ObjectOutputStream:
In der Klasse des zu serialisierenden Objektes mu die Methode private void writeObject(ObjectOutputStream s) throws IOException mit exakt dieser Signatur definiert sein. Statt der Standard-Serialisierung wird diese Methode aufgerufen Der Outputstream (s) wird bergeben, daher kann die Serialisierung von Hand vorgenommen werden Mit s.defaultWriteObject(); kann die Standard-Serialisierung aufgerufen werden, die ggf. noch ergnzt wird Soll dem ObjectOutputStream die Serialisierung verweigert werden, kann NotSerializableException geworfen werden.
Der ObjectOutputStream fngt diese Exception ab und wertet sie aus.

Informationen ber transiente under nicht serialisierbare Attribute bentigt werden


Objektkonsistenz ist bei Existenz von transienten Attributen nicht immer trivial

Ein Objekt selbst situationsabhngig bestimmen mchte, ob es serialisierbar ist

713

714

Kontrolle ber Deserialisierung


Kontrolle von ObjectInputStream:
In der Klasse des zu deserialisierenden Objektes mu die Methode private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException

Interface Externalizable
Die strkste Kontrolle ber Serialisierung wird durch Implementierung des Interfaces Externalizable erreicht
package java.io; public interface Externalizable extends Serializable { public void writeExternal(ObjectOutput out) throws IOException; public void readExternal(ObjectInput in) throws IOException, java.lang.ClassNotFoundException; }

mit exakt dieser Signatur definiert sein. Statt der Standard-Deserialisierung wird diese Methode aufgerufen Der Inputstream (s) wird bergeben, daher kann die Serialisierung von Hand vorgenommen werden Mit s.defaultReadObject(); kann die Standard-Serialisierung aufgerufen werden, die ggf. noch ergnzt wird. Soll dem ObjectInputStream die Serialisierung verweigert werden, kann NotSerializableException geworfen werden.
Der ObjectInputStream fngt diese Exception ab und wertet sie aus.

Die Methoden writeExternal und readExternal mssen berschrieben werden Die Klasse ist selbst fr das Lesen und Schreiben verantwortlich und mu das auch fr die Oberklassen gewhrleisten Methoden writeExternal und readExternal sind public => Gefahr des berschreibens
716

715

Beispiel: Ablegen von binren Suchbumen


Ziel: binre Suchbume werden persistent gemacht, sie knnen nach Beendigung eines Programms wieder geladen werden. Dazu werden die Methoden Sichere und Lade in die Klasse BST eingefgt.
Sichere arbeitet rekursiv (Preorder) und verwendet die private Methode PreSichere. Lade arbeitet iterativ.

Beispiel: Ablegen von binren Suchbumen


import java.io.*; class BST { private Knoten wurzel; BST() { wurzel = null; } void Sichere(String dateiname) throws IOException { DataOutputStream ausStrom = new DataOutputStream( new FileOutputStream(dateiname); PreSichere(ausStrom, wurzel); } private void PreSichere(DataOutputStream aus, Knoten aktuell) throws IOException { if (aktuell != null) { aus.writeInt(aktuell.GibWert()); PreSichere(aus, aktuell.GibLinks()); PreSichere(aus, aktuell.GibRechts()); } 718 }

717

Beispiel: Ablegen von binren Suchbumen


void Lade(String dateiname) throws IOException { DataInputStream inStrom = new DataInputStream( new FileInputStream(dateiname); try { while (true) FgeEin(inStrom.readInt()); } catch (EOFException eof) {};

Beispiel: Ablegen von binren Suchbumen


Etwas trickreich ist die Konstruktion:
new DataOutputStream( new FileOutputStream(dateiname);

Von innen nach auen: zunchst wird ein Objekt der Klasse FileOutputStream erzeugt, das auf einer Datei arbeitet, deren Name durch dateiname gegeben ist, das erzeugte Objekt der Klasse FileOutputStream wird an den Konstruktor der Klasse DataOutputStream bergeben, der es so verkapselt, da die komfortable Schnittstelle von DataOutputStream genutzt werden kann
719 720

javax.swing
java.applet java.awt java.beans java.io java.lang java.math java.rmi java.security java.sql java.util javax.swing (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.0) (JDK 1.2)

Die Java Klassenbibliotheken


Java-Applets (fr WWW-Browser) AWT-Komponenten Beans-Development Input / Output / Datenstrme Basispackage fr Java Zahlen groer Genauigkeit Remote Method Invocation Sicherheit, Kryptographie JDBC-Paket Verschiedene Hilfsklassen Swing-Komponenten Fr JDK 1.1.x: com.sun.java.swing (JDK 1.2) CORBA-Schnittstelle

Kapitel 19
Graphische Oberflchen (java.awt, java.swing)

org.omg.CORBA

722

1 Motivation, Historie Java und Guis, AWT, SWING, JFC 2 Einfaches Bildschirmfenster mit elementaren Komponenten 3 Komponenten zusammenfassen in Containern (bersicht) JPanel alle Container erben von Container alle Komponenten erben von JComponent 4 Layout von Containern (Komponenten-Anordnung, -Gre) FlowLayout, GridLayout, BoxLayout, CardLayout, BorderLayout, GridBagLayout 5 Pluggable Look&Feel (inkl. Vorfhrung/Demo Swing-Set zur Prsentation GUI-Elemente) 6 Allgemeine Betrachtung: Interaktion, MVC-Konzept, Ereignisse, 7 Behandlung von Benutzer-Ereignissen (Mausklicks, ...) 8 Mens fr Funktionsauswahl

Graphische Benutzungsoberflchen
Ziel: Erstellen einer GUI (z.B. fr Bankautomaten)
Men's Eingabebereiche fr Text Schaltknpfe Behandlung von Benutzereingaben (Mausklicks,...)

Container fr mehrere zusammengehrende Komponenten Anzeigefelder (Label)

Applets
723 724

GUI-Bibliotheken in Java: JFC


Java Foundation Classes (JFC)
Swing Komponentenbibliothek (oftmals ungenauerweise synonym zu JFC verwendet) Untersttzung fr frei whlbares Look&Feel API fr Dialoghilfen (Accessibility) API fr Einbinden von 2D-Grafik, Text, Bildern Untersttzung fr Drag&Drop

GUI-Bibliotheken in Java: Swing, AWT


Erweiterbare Komponenten fr Java-Benutzerschnittstellen
sichtbare (J-Klassen) und unsichtbare Klassen
JButton, JTextField vs. Modell-Klassen, Event-Klassen

Swing 1.1 (javax.swing)


ist im JDK 1.2 enthalten com.sun.java.swing in der Version 1.0.3 fr JDK 1.1.x

AWT (bereits im JDK 1.0 definiert)


wird weiterhin untersttzt Button und JButton wird vor allem fr anspruchslose Anwendungen eingesetzt

725

726

Unterschied AWT - Swing

GUI und Ereignisse

Entwicklungsziele
Implementierung in Java (lightweight components) Ausfhrung ist plattformunabhngig frei whlbaren Look&Feels Darstellung ist plattformunabhngig Modell-basierter Programmierung MVC Komponenten als JavaBeans verpackt Kompatibilitt zu AWT

AWT - Klassen (Abstract Window Toolkit) Plattformabhngige Darstellung (Peer Klassen) (schwergewichtig) plattformabhngige Behandlung von Benutzereingaben rechteckige Zeichenflche, nicht berlappend AWT umfat Schnittmenge aller Plattformen Swing - Klassen Plattformunabhngige Darstellung in Java geschrieben (leichtgewichtig), bauen auf AWT auf nicht nur rechteckige Formen Swing umfat Konjunktion der Plattformen

nein!
728

727

Aufbau der Swing-API


Insgesamt 15 ffentliche Pakete, z.B.
javax.swing javax.swing.event javax.swing.text ... (frher com.sun.java.swing)

GUI und Ereignisse

Vererbungshierarchie Bezug AWT - Swing AWT-Swing


java.lang.Object

Elementare GUI-Komponenten Ereignisbehandlung von Swing Textdaten anzeigen, editieren

java.awt
(java.applet)

java.awt.Component java.awt.Container java.awt.Window java.awt.Panel

Benutzen eines Paketes:


import javax.swing.*; import javax.swing.event.*;

java.awt.Frame JFrame

java.awt.Dialog java.awt.Window java.applet.Applet JDialog JWindow JApplet JComponent

javax.swing

729

730

Aufbau von Swing 1.1


15 ffentliche Pakete:
javax.swing GUI-Komponenten javax.swing.event Ereignisbehandlung von Swing javax.swing.border Rahmen fr GUI-Komponenten javax.swing.table Tabellendaten anzeigen javax.swing.tree Hierachische Daten anzeigen javax.swing.text Textdaten anzeigen, editieren javax.swing.text.html, javax.swing.text.html.parser ... In HTML javax.swing.colorchooser Farbe auswhlen-Dialog javax.swing.filechooser Datei auswhlen-Dialog javax.swing.undo Rckgngig bei GUI-Komp. javax.swing.plaf, javax.swing.plaf.basic Frei whlbares Look&Feel javax.swing.plaf.metal, javax.swing.plaf.multi javax.accessibility Dialoghilfen fr Ein-/Ausgabe

1 Motivation, Historie Java und Guis, AWT, SWING, JFC 2 Einfaches Bildschirmfenster mit elementaren Komponenten 3 Komponenten zusammenfassen in Containern (bersicht) JPanel alle Container erben von Container alle Komponenten erben von JComponent 4 Layout von Containern (Komponenten-Anordnung, -Gre) FlowLayout, GridLayout, BoxLayout, CardLayout, BorderLayout, GridBagLayout 5 Pluggable Look&Feel (inkl. Vorfhrung/Demo Swing-Set zur Prsentation GUI-Elemente) 6 Allgemeine Betrachtung: Interaktion, MVC-Konzept, Ereignisse, 7 Behandlung von Benutzer-Ereignissen (Mausklicks, ...) 8 Mens fr Funktionsauswahl

731

732

Fenster-Objekt: JFrame
Bildschirm-Fenster mit Rahmen, Titel mit Buttons und Menzeile kann minimiert, verschoben, geschlossen und vergrert werden Erzeugen
JFrame f= new JFrame();

GUI und Ereignisse

GUI-Komponenten (1/3)

GUI und Ereignisse

Auf der Zeichenflche knnen Komponenten angelegt werden! wichtige Komponenten: JButton Knopf, beim Drcken wird eine Aktion ausgefhrt
JButton b= new JButton(); b.setText("Drck' mich!"); getContentPane().add(b);

JFrame hat einen Container "ContentPane". enthlt alle Komponenten, die auf der Zeichenflche gezeichnet werden:
Container c= f.getContentPane(); Hinzufgen von Komponenten zu einem JFrame f.getContentPane().add(...);

733

734

GUI-Komponenten (2/3)
JTextField Eingeben eines einzeiligen Textes
JTextField t = new JTextField(); String eingabetext = t.getText();

GUI und Ereignisse

GUI-Komponenten
In der Zeichenflche knnen Komponenten gezeichnet werden. Die wichtigsten Komponenten: JButton
Knopf, beim Drcken wird eine Aktion ausgefhrt
JButton b= new JButton() b.setText("Drck' mich!")

JTextArea Eingeben eines lngereren Textes JLabel einzeiliger Text, auch fr Icon-Anzeige verwendbar
JLabel l=new JLabel(); l.setText("Eine Menge Buchstaben...");

JCheckBox
Boolesche Anzeige: "wahr"/"falsch"

JRadioButton
exklusive Wahl aus Alternativen

735

736

GUI-Komponenten
JList JComboBox
Einstellung eines Wertes (oben) mit vorgegebenen Alternativen

GUI-Komponenten
damit kann man ein oder mehrere Element aus einer Liste auswhlen lassen
String[] data = {January", February",...}; JList dataList = new JList(data);

Holen der markierten Zellen


Object[] objekte=eineListe.getSelectedValues();

JTree
Darstellung von Hierarchien als Baum Die Baumste knnen an einem Knoten auf- und zugeklappt werden

737

738

GUI-Komponenten
JTable
Darstellen zweidimensionaler Daten in Tabellenform Die dargestellten Daten werden im TableModel gespeichert und verwaltet Man kann einzeln, zeilen- oder spaltenweise Elemente selektieren Erzeugen einer 4x3 Tabelle
JTable tabelle=new JTable(4,3);

Weitere Elemente
JSlider
Schieberegler fr Werteingabe aus Zahlenbereich

Datei-Dialog ffne/Speichere
FileDialog(vaterFenster, Titel, LOAD);

Holen des zugeordneten TableModel


Table Model modell=tabelle.getModel();

Ereignisse z.B. TableColumnModelEvent mit Methoden


columnAdded(), -Moved();

739

740

GUI-Komponenten (3/3)

GUI und Ereignisse

1 Motivation, Historie Java und Guis, AWT, SWING, JFC 2 Einfaches Bildschirmfenster mit elementaren Komponenten 3 Komponenten zusammenfassen in Containern (bersicht) JPanel alle Container erben von Container alle Komponenten erben von JComponent 4 Layout von Containern (Komponenten-Anordnung, -Gre) FlowLayout, GridLayout, BoxLayout, CardLayout, BorderLayout, GridBagLayout 5 Pluggable Look&Feel (inkl. Vorfhrung/Demo Swing-Set zur Prsentation GUI-Elemente) 6 Allgemeine Betrachtung: Interaktion, MVC-Konzept, Ereignisse, 7 Behandlung von Benutzer-Ereignissen (Mausklicks, ...) 8 Mens fr Funktionsauswahl

import javax.swing.*; public class EinfachesGUI extends JFrame { public EinfachesGUI() { getContentPane().setLayout(null); setSize(300,300); JLabel l= new JLabel(); l.setText(Label-Flche"); l.setBounds(0,0,200,50); getContentPane().add(l); JButton b= new JButton(); b.setText("Button-Flche"); b.setBounds(0,100,200,50); getContentPane().add(b); } } public static void main (String args[]){ EinfachesGUI oberflaeche = new EinfachesGUI(); oberflaeche.setVisible(true); } }
741

742

Komponenten-Hierarchien
bersichtlich leicht austauschbar Komponente ist verantwortlich fr ihre "Kinder" (z.B. Anordnung und Gre aller Kinder bestimmen)

GUI und Ereignisse

Strukturieren von Fenstern

Container und Layout

Grundlegende Idee: Komponenten enthalten wiederum Komponenten

Ziel: Fenster aus kleineren Gruppen zusammensetzen bersichtliche Gestaltung Wiederverwendung: Code wird nicht mehrmals geschrieben Lsung: Container (fr Komponenten) Beispiel eines Containers: JPanel Container mit Zeichenflche fat Komponenten zusammen zu einer Einheit ordnet diese in seinem Zeichenbereich an

Beispiel: Komponenten-Baum fr die EinfachesGUI (vereinfacht)

EinfacheGUI ContentPane l (JLabel) b (JButton)

...

743

744

JPanels bei der BankautomatGUI

Container und Layout

Beispiel: JPanel fr PIN-Eingabe


import javax.swing.*; import java.awt.*; public class PINPanel extends JPanel { public PINPanel() { setLayout(null); JLabel pinLabel = new JLabel(); pinLabel.setText("PIN"); pinLabel.setBounds(10,5,50,20); add(pinLabel);

Container und Layout

JPasswordField pinField = new JPasswordField(); pinField.setBounds(100,5,150,20); add(pinField); } }

745

746

Beispiel: JPanel fr PIN-Eingabe


public static void main (String[] args) { JFrame f=new JFrame(); f.setBounds(0,0,300,70); PINPanel p=new PINPanel(); f.getContentPane().add(p); f.setVisible(true); }

Container und Layout

Weitere Container

Container und Layout

Es gibt weitere Container in Swing: Toplevel-Container: JFrame Fenster mit Rahmen, Titelzeile mit Buttons JApplet Fenster fr Darstellung im Web-Browser JDialog kurzzeitig erscheinendes Fenster, um Mitteilungen an den Benutzer und Reaktionen des Benutzers abzufragen Allgemeine Container (Auswahl)

Das JFrame:

JScrollPane
747

JSplitPane

JTabbedPane
748

Container: Dialogfenster
Aufteilung des Dialogfensters
Icon Text-Botschaft Knopf-Leiste abhngig gehrt zu einem Toplevel-Container, der nach Dialogende aktiviert wird Arten von Dialogen: Besttigungs-Dialoge Eingabe-Dialoge Nachricht-Dialoge Auswahl-Dialoge

Container und Layout

Beispiel: Besttigungs-Dialog
//das Fenster, das am Dialogende aktiviert wird JFrame f = new JFrame();

Container und Layout

Frage mit Ja/Nein/Abbruch Text, Eingabefeld und "Ok" Text und "Ok" Text mit frei beschrifteten Knpfen
749

JOptionPane.showConfirmDialog( f, "Mchten Sie wirklich alle Daten lschen?", "Warnung", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE );

750

Vererbung bei Containern


Ziel:

Container und Layout

Container: Vererbungshierarchie
java.lang.Object

Container und Layout

Alle Container sollen dieselben grundlegende Fhigkeiten fr Container-Verwaltung besitzen


java.awt

Lsung:

Benutze Vererbung!

(java.applet)

java.awt.Component java.awt.Container

Alle Container erben von einer Klasse java.awt.Container:


Hinzufgen und Entfernen von Komponenten Anordnen der Komponenten auf der Zeichenflche (Layout-Management)
java.awt.Frame JFrame

java.awt.Window java.awt.Dialog JDialog java.awt.Window JWindow

java.awt.Panel java.applet.Applet JApplet JComponent

com.sun.java.swing

751

752

Vererbung bei Komponenten


Ziel: Lsung:

Container und Layout

javax.swing.JComponent
Mutter (fast) aller GUI-Klassen
Ausnahme: Toplevel-Container

gleiche Fhigkeiten fr alle Swing-Komponenten bereitstellen, dabei Code wiederverwenden Benutze Vererbung!

leichtgewichtig vererbt an alle Komponenten:


(z.B. frei whlbares Look&Feel)

java.lang.Object java.awt.Component java.awt.Container javax.swing.JComponent

Alle Swing-Komponenten erben von einer Klasse JComponent:


Behandlung von Tastatureingaben Rahmen Accessibility, Lokalisation (Datum, Whrung,...), Tooltips

ist ein Container und kann damit andere Komponenten enthalten. in der Enthaltensein-Hierarchie stets unterhalb eines Toplevel-Container (benutzt dessen Zeichenflche)

Analog knnen neue, eigene Klassen von beliebigen Swing-Komponenten erben und diese ebenfalls um neue Fhigkeiten erweitern
753 754

Erweitern von Swing-Komponenten


Ziel: Neue Klassen von bestehenden Swing-Komponenten ableiten und neue Fhigkeiten hinzufgen: z.B. neuer Schaltknopf Lsung: Benutze Vererbung!

Container und Layout


java.lang.Object java.awt.Component java.awt.Container javax.swing.JComponent javax.swing.AbstractButton

1 Motivation, Historie Java und Guis, AWT, SWING, JFC 2 Einfaches Bildschirmfenster mit elementaren Komponenten 3 Komponenten zusammenfassen in Containern (bersicht) JPanel alle Container erben von Container alle Komponenten erben von JComponent 4 Layout von Containern (Komponenten-Anordnung, -Gre) FlowLayout, GridLayout, BoxLayout, CardLayout, BorderLayout, GridBagLayout 5 Pluggable Look&Feel (inkl. Vorfhrung/Demo Swing-Set zur Prsentation GUI-Elemente) 6 Allgemeine Betrachtung: Interaktion, MVC-Konzept, Ereignisse, 7 Behandlung von Benutzer-Ereignissen (Mausklicks, ...) 8 Mens fr Funktionsauswahl

public class MeinEigenerButton extends JButton{ ... } MeinEigenerButton b=new MeinEigenerButton()

javax.swing.JButton MeinEigenerButton

755

756

Layout-Management
Ziel:

Container und Layout

FlowLayout und GridLayout


FlowLayout (Flu) Komponenten von links nach rechts Zeilenumbruch am Zeilenende Default fr JPanel GridLayout (Gitter) Alle Komponenten bekommen gleiche Gre Plazierung durch Angeben von Zeile und Spalte

Container und Layout

Anordnen von Komponenten in einer anderen Komponente (Gre, Position festlegen) Idee 1: Angabe von festen Layout-Koordinaten fr jeden Bestandteil Nachteil: unflexibel, aufwendig, nicht nachtrglich nderbar

Idee 2: Komponente layoutet sich selbst. Es gibt mehrere Layout-Strategien, die Komponenten selbststndig in einer Zeichenflche anordnen: FlowLayout, GridLayout, BoxLayout, CardLayout, BorderLayout, GridBagLayout, Layout-Strategie auswhlen: eineKomponente.setLayout
(new FlowLayout())
757

758

Beispiel: FlowLayout
import java.awt.*; import javax.swing.*; public class FlowWindow extends JFrame { public FlowWindow() { JButton b1= new JButton ("Button 1"); JButton b2= new JButton ("Button 2");
...

Container und Layout

BoxLayout und CardLayout


BoxLayout (Kiste)
Hngt Komponenten in 1 Spalte untereinander

Container und Layout

setLayout(new FlowLayout()); add(b1); add(b2);


...

CardLayout (Spielkarte)
Komponenten liegen als Spielkartenstapel Nur die oberste Karte sichtbar Zugriff auf oberste, unterste, folgende, vorherige Karte

} ... public static void main(String args[]) { FlowWindow w = new FlowWindow(); w.setSize(300,300); w.setVisible(true); }
759

760

BorderLayout und GridBagLayout


BorderLayout (zuerst die Grenzen)
zuerst 4 Komponenten innen an die Kanten fgen, zuletzt die verbliebene Zentralflche mit 1 Komponente ausfllen Orte: Nord, Sd, Ost, West, Center

Container und Layout

Beispiele: Auswahl eines Layout-Managers


Viel Platz fr jede einzelne Komponente
BorderLayout, GridBagLayout im Zentrum liegt grte Komponente

Wenige Komponenten aufgereiht


FlowLayout, BoxLayout

Wenige Komponenten gleicher Gre


Gridlayout

GridBagLayout
in Gitter anordnen, aber Gre fr jede Komponente frei whlbar Plazierung durch Angeben der Zeile und Spalte mehrere Gitterpltze belegbar
761

Viele Komponenten mit komplexem Layout


GridBagLayout

762

Weitere Layout-Mglichkeiten
keinen Layout-Manager benutzen
eineKomponente.setLayout(null)

Container und Layout

1 Motivation, Historie Java und Guis, AWT, SWING, JFC 2 Einfaches Bildschirmfenster mit elementaren Komponenten 3 Komponenten zusammenfassen in Containern (bersicht) JPanel alle Container erben von Container alle Komponenten erben von JComponent 4 Layout von Containern (Komponenten-Anordnung, -Gre) FlowLayout, GridLayout, BoxLayout, CardLayout, BorderLayout, GridBagLayout 5 Pluggable Look&Feel (inkl. Vorfhrung/Demo Swing-Set zur Prsentation GUI-Elemente) 6 Allgemeine Betrachtung: Interaktion, MVC-Konzept, Ereignisse, 7 Behandlung von Benutzer-Ereignissen (Mausklicks, ...) 8 Mens fr Funktionsauswahl

absolute Positionierung durch Angabe der Positions- Koordinaten (x/y) sowie Breite und Hhe fr jede einzelne Komponente
JRadioButton rb = new JRadiuoButton(); rb.setText("zahle aus"); rb.setBounds(5,26,113,26);

// (x,y, breite, hhe)

eigenen Layout-Manager schreiben

763

764

Frei whlbares Look&Feel


Aussehen(Look) und Verhalten(Feel) einer GUI-Schnittstelle Look&Feel-Verwaltung bernimmt das Paket javax.swing.plaf Schaltzentrale UI-Manager
Whlen eines Look&Feel:
...// zuerst das Look&Feel auf CrossPlatform einstellen try { UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName()); } catch (Exception e) { } ...// jetzt erst die GUI aufbauen und anzeigen
765

Die verfgbaren Look&Feels


Java (Metal)

Windows

CDE, OSF/Motif (Common Desktop Environment)

Apple Macintosh
766

Look&Feel Detail
Jede Klasse J... hat in javax.swing.plaf eine Klasse ...UI (Delegate)
z.B. die Klasse JButton duch ButtonUI. Ausnahme: Toplevel-Container (JFrame etc.) haben stets Windows-Look&Feel, weil sie schwergewichtig sind

1 Motivation, Historie Java und Guis, AWT, SWING, JFC 2 Einfaches Bildschirmfenster mit elementaren Komponenten 3 Komponenten zusammenfassen in Containern (bersicht) JPanel alle Container erben von Container alle Komponenten erben von JComponent 4 Layout von Containern (Komponenten-Anordnung, -Gre) FlowLayout, GridLayout, BoxLayout, CardLayout, BorderLayout, GridBagLayout 5 Pluggable Look&Feel (inkl. Vorfhrung/Demo Swing-Set zur Prsentation GUI-Elemente) 6 Allgemeine Betrachtung: Interaktion, MVC-Konzept, Ereignisse, 7 Behandlung von Benutzer-Ereignissen (Mausklicks, ...) 8 Mens fr Funktionsauswahl

Delegate kennt fr alle Look&Feels, in denen die Klasse gezeichnet werden kann, die konkreten APIs
In jedem APIs ist eine Klasse bereitgestellt, mit der die sichtbare Klasse sich zeichnen kann. z.B. MetalButton, WindowsButton, etc.

Zeichnen
Fr ein Objekt holt beim UI-Manager den Delegate. Von diesem Delegate kann fr das aktuell verwendete Look&Feel zu der Klasse verzweigt werden, die fr das Zeichnen in diesem Look&Feel sorgt.

767

768

Das MVC-Modell
Model-View-Controller (MVC) ist eines der bekanntesten Entwurfsmuster
window

MVC-Beispiel

window

window

Ein Entwurfsmuster ist ein bewhrter Lsungsansatz MVC trennt Datenhaltung von Datendarstellung
Modell hlt Daten einer Anwendung View fr graphische Reprsentation der Daten Controller bersetzt Benutzereingaben im View in nderungen am Zustand des Modells

a b c x 60 30 10 y 50 30 20 z 80 10 20

A C A B C B

change notification a=50% b=30% c=20% requests, modifications

769

770

MVC - Model
Das Model enthlt den funktionalen Anwendungskern. Es kapselt die enstprechenden Daten und bietet Operationen an. Diese werden vom Controller aufgerufen. Zustzlich bietet das Model Operationen zum Zugriff auf Daten, die die Views brauchen, um Daten abzufragen. Das Model verwaltet die abhngigen Komponenten. Alle Ansichten und einige Controller (diejenigen, die mit Views zusammenhngen, von denen nderungen veranlat werden) lassen sich beim Model registrieren.

MVC - View
Views prsentieren dem Anwender Informationen. Jede View definiert eine Aktualisierungsoperation, die vom nderungsmechanismus des Models aufgerufen wird. Diese nderungsoperation ermittelt die anzuzeigenden Werte und zeigt sie an. Whrend der Initialisierung werden alle Views mit dem Model assoziiert. Jede View erzeugt eine Controller-Komponente (1:1-Beziehung).

771

772

Das MVC-Modell MVC - Controller


Ein Controller-Objekt akzeptiert Bedieneingaben als Ereignisse. Ereignisse werden in Anforderungen an das Model oder die assoziierte View bersetzt. Wenn das Verhalten eines Controllers vom Zustand des Models abhngt, lt sich der Controller beim Mechanismus zur Benachrichtigung ber nderungen registrieren und implementiert eine Aktualisierungsoperation (z.B. ntig, wenn eine nderung des Models einen Meneintrag aktiviert oder deaktiviert).

Varianten
Vollstndige Entkopplung von Modell und View Einseitige Abkopplung des View
Modell kennt seine Views direkt Views mssen Controller benutzen (dfen Modell nicht direkt manipulieren)

773

774

Das MVC-Modell: Diskussion


Vorteile
View leicht nderbar Wiederverwendung durch Entkopplung Modell mit mehreren Darstellungen Views sind schachtelbar (schwer, wenn Modelldaten und View vermischt sind). Controller (zur Laufzeit) nderbar
Z.B. View abschalten: Controller, der alle Eingabeereignisse ignoriert

Ereignisse
Programme ohne GUI haben klaren Programmablauf Programme mit GUI sind ereignisgesteuert
Aktionen des Benutzers erzeugen Ereignisse (Tastaturanschlge, Mausklicks, Mausbewegungen etc.)

Problem: Idee:

GUI kann nicht vorhersehen, was Benutzer tun wird. GUI wartet auf Aktionen des Benutzers Komponenten erzeugen Ereignisse (Maus, Tastatur,...)

Nachteile
Kleinere, einfache Anwendungen werden unntig aufgeblasen. Die Trennung von Controller und View kann schwierig sein.

775

776

1 Motivation, Historie Java und Guis, AWT, SWING, JFC 2 Einfaches Bildschirmfenster mit elementaren Komponenten 3 Komponenten zusammenfassen in Containern (bersicht) JPanel alle Container erben von Container alle Komponenten erben von JComponent 4 Layout von Containern (Komponenten-Anordnung, -Gre) FlowLayout, GridLayout, BoxLayout, CardLayout, BorderLayout, GridBagLayout 5 Pluggable Look&Feel (inkl. Vorfhrung/Demo Swing-Set zur Prsentation GUI-Elemente) 6 Allgemeine Betrachtung: Interaktion, MVC-Konzept, Ereignisse, 7 Behandlung von Benutzer-Ereignissen (Mausklicks, ...) 8 Mens fr Funktionsauswahl

Benutzer-Ereignisse

GUI und Ereignisse

Problem: GUI kann nicht vorhersehen, was Benutzer tun wird. Idee: GUI wartet auf Aktionen des Benutzers Komponenten erzeugen Ereignisse (Maus, Tastatur,...) Ereignis-Objekte (erben von java.util.EventObject) stellen bestimmte Ereignisse dar (Interaktion des Benutzers) Ereignis-Auslser-Objekte lsen Ereignisse aus (in der Regel graphische Elemente) Ereignis-Lauscher-Objekte (EventListener-Objekte): melden sich bei Auslser-Objekten an, werden bei Ereignissen benachrichtigt stellen fr Behandlung der Ereignisse passende Methoden bereit implementieren EventListener-Schnittstellen bilden die Schnittstelle zur Anwendungsfunktionalitt!
777 778

Beispiel: Mausklicks
Ereignis: Reaktion: Schaltknopf erzeugt Ereignis-Objekt
new java.awt.event.ActionEvent

GUI und Ereignisse

Beispiel (1/2)
Ziel: Button mit wechselnder Aufschrift
import java.awt.event.*; import javax.swing.*; public class Wechselbutton extends JButton { public Wechselbutton (String text){ super(text); } public void wechsle() { if (this.getText().equals("Drck mich!")){ this.setText("Nochmal..."); } else { this.setText("Drck mich!"); } } } public class WechselbuttonFrame extends JFrame { private Wechselbutton b; public WechselbuttonFrame(Hoerer h){ b = new Wechselbutton("Drck mich!"); getContentPane().add(b); b.addActionListener(h); } }

GUI und Ereignisse

Benutzer drckt Maustaste ber einem Schaltknopf

Schaltknopf benachrichtigt alle registrierten Listener und ruft dort die passende Listener-Methode auf: Listener mu Schnittstelle ActionListener implementieren
actionPerformed(ActionEvent e)

Jede zuhrende Klasse kann die Methode beliebig implementieren Jede Klasse hlt Methoden fr alle interessierenden Ereignisarten bereit

779

780

Beispiel (2/2)

GUI und Ereignisse

Ereignis-Objekt
Ein Ereignis ist ein Objekt in java.util.EventObjekt, java.awt.Event oder
javax.swing.event

import javax.swing.*; import java.awt.event.*; public class Hoerer implements ActionListener { public void actionPerformed(ActionEvent e){ Wechselbutton but=(Wechselbutton) e.getSource(); but.wechsle(); } } public class Testumgebung { public static void main(String[] args) { Hoerer h = new Hoerer(); WechselbuttonFrame wbf = new WechselbuttonFrame(h); wbf.setSize(200,50); wbf.setVisible(true); } }
781

enthlt
auslsende Quelle (z.B. Button) Nachricht (z.B. Maustaste 1 wurde gedrckt)

Event-Quelle (Button)

Event

Event Listener Event Listener


782

Arten von Ereignissen


Basis-Ereignisse und semantische Ereignisse
Verwendung Basisereignisse Tastaturereignisse Mausereignisse Komponentenereign. Containerereignisse Fokusereignisse Fensterereignisse Ereignisart KeyEvent MouseEvent ComponentEvent ContainerEvent FocusEvent WindowEvent Schnittstelle KeyListener MouseListener ComponentList. ContainerListener FocusListener WindowListener ActionListener TextListener ItemListener AdjustmentListener

GUI und Ereignisse

Zugehrigkeit von Listener-Interfaces zu Kompon.


Ausschnitt (siehe JDK-Dokumentation und Tutorial)
Komponente Action Listener Change Listener Item Listener Window Listener X X X X X X X X
784

Lauscher-Methoden

JFrame
keyPressed, keyReleased mouseClicked,-Pressed componentHidden, -moved componentAdded, -Removed focusGained, focusLost windowIconified, -Opened actionPerformed textValueChanged itemStateChanged adjustmentValueChanged

JDialog JScrollPane JButton JComboBox JSlider JTextField JFileChooser

X X

Semantische Ereignisse Aktion des Benutzers ActionEvent Textereignisse TextEvent Auswhlen (Checkb.) ItemEvent Wertmanipulation AdjustmentEvent

783

Methoden der Listener-Interfaces:


ComponentListener:
void void void void componentHidden(ComponentEvent e) componentMoved(ComponentEvent e) componentResized(ComponentEvent e) componentShown(ComponentEvent e) void void void void void

Methoden der Listener-Interfaces:


MouseListener:
mouseClicked(MouseEvent e) mouseEntered(MouseEvent e) mouseExited(MouseEvent e) mousePressed(MouseEvent e) mouseReleased(MouseEvent e)

FocusListener:
void focusGained(FocusEvent e) void focusLost(FocusEvent e)

MouseMotionListener:
void mouseDragged(MouseEvent e) void mouseMoved(MouseEvent e)

KeyListener:
keyPressed(KeyEvent e) keyReleased(KeyEvent e) keyTyped(KeyEvent e)
785

ActionListener:
void actionPerformed(ActionEvent e)

786

Methoden der Listener-Interfaces:


ChangeListener:
void stateChanged(ChangeEvent e)

Listener implementieren:
Listener-Interfaces beinhalten Methoden, an die Events weitergeleitet werden.
Beispiel: interface FocusListener { void focusGained(FocusEvent e); void focusLost(FocusEvent e); }

ItemListener:
void itemStateChanged(ItemEvent e)

WindowListener:
void void void void void void void windowActivated(WindowEvent e) windowClosed(WindowEvent e) windowClosing(WindowEvent e) windowDeactivated(WindowEvent e) windowDeiconified(WindowEvent e) windowIconified(WindowEvent e) windowOpened(WindowEvent e)
787

Swing-Komponenten knnen nur Ereignisse an Objekte bestimmte Listener-Interfaces weiterleiten. Entsprechende Objekte werden mit add...Listener() bei der SwingKomponente registriert. Hier: addFocusListener(...);

788

Benutzen von anonymen Klassen


import javax.swing.*; import java.awt.event.*; public class Wechselbutton2 extends JFrame { public Wechselbutton2(){ JButton b=new JButton("Drck mich!"); getContentPane().add(b);

GUI und Ereignisse

Benutzen von Anonymen Klassen


...

GUI und Ereignisse

Wird von Programmier umgebungen generiert!


} }

b.addActionListener( new ActionListener(){ public void actionPerformed(ActionEvent e){ JButton but=(JButton) e.getSource(); if (but.getText().equals("Drck mich!")){ but.setText("Nochmal..."); } else { but.setText("Drck mich!"); } } } );

public static void main(String[] args) { Wechselbutton2 wb2 = new Wechselbutton2(); wb2.setSize(200,50); wb2.setVisible(true); }

789

790

1 Motivation, Historie Java und Guis, AWT, SWING, JFC 2 Einfaches Bildschirmfenster mit elementaren Komponenten 3 Komponenten zusammenfassen in Containern (bersicht) JPanel alle Container erben von Container alle Komponenten erben von JComponent 4 Layout von Containern (Komponenten-Anordnung, -Gre) FlowLayout, GridLayout, BoxLayout, CardLayout, BorderLayout, GridBagLayout 5 Pluggable Look&Feel (inkl. Vorfhrung/Demo Swing-Set zur Prsentation GUI-Elemente) 6 Allgemeine Betrachtung: Interaktion, MVC-Konzept, Ereignisse, 7 Behandlung von Benutzer-Ereignissen (Mausklicks, ...) 8 Mens fr Funktionsauswahl

Mens
Ziel: Mens an Bildschirm-Fenstern

Mens und Applets

- Gruppieren von Funktionen in Mens - Anordnen aller Mens in 1 Menleiste am oberen Fensterrand - Anbinden an Methoden ber Ereignisse (analog Knpfe, etc.)

791

792

Bestandteile eines Mensystems


Menleiste nimmt Mens auf Trennlinien Popup-Men Menu-Elemente Meneintrge Radiobuttons Checkbuttons Kommando-Sammlung (JMenu) (ein bzw. mehrere Kommandos, verschachtelte Mens)

Mens

Vererbungshierarchie fr Mens
Alle Menu-Elemente sind Container und Komponenten

Mens

java.awt.Component java.awt.Container JComponent JMenuBar JPopupMenu JAbstractButton JMenuItem JMenu JCheckBoxMenuItem JRadioButtonMenuItem JSeparator

793

794

Beispiel: Menleiste
public class BankautomatGUI extends JFrame { public BankautomatGUI(String s) { super(s); JMenuBar mbar = new JMenuBar(); setJMenuBar(mbar); JMenu dateiMenu = new JMenu(Datei); mbar.add(dateiMenu); JMenu bearbeitenMenu = new JMenu("Bearbeiten"); mbar.add(bearbeitenMenu); JMenuItem editierenItem = new JMenuItem(); editierenItem.setText("Editieren"); bearbeitenMenu.add(editierenItem); JMenuItem anschauenItem = new JMenuItem(); anschauenItem.setText("Anschauen"); bearbeitenMenu.add(anschauenItem); setJMenuBar(mbar); ...

Mens

Look&Feel Detail
Jede Klasse J... hat in javax.swing.plaf eine Klasse ...UI (Delegate)
z.B. die Klasse JButton duch ButtonUI. Ausnahme: Toplevel-Container (JFrame etc.) haben stets Windows-Look&Feel, weil sie schwergewichtig sind

Delegate kennt fr alle Look&Feels, in denen die Klasse gezeichnet werden kann, die konkreten APIs
In jedem APIs ist eine Klasse bereitgestellt, mit der die sichtbare Klasse sich zeichnen kann. z.B. MetalButton, WindowsButton, etc.

Zeichnen
Fr ein Objekt holt beim UI-Manager den Delegate. Von diesem Delegate kann fr das aktuell verwendete Look&Feel zu der Klasse verzweigt werden, die fr das Zeichnen in diesem Look&Feel sorgt.

795

796

java.applet
java.applet java.awt java.beans java.io java.lang java.math java.rmi java.security java.sql java.util javax.swing (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.0) (JDK 1.2)

Die Java Klassenbibliotheken


Java-Applets (fr WWW-Browser) AWT-Komponenten Beans-Development Input / Output / Datenstrme Basispackage fr Java Zahlen groer Genauigkeit Remote Method Invocation Sicherheit, Kryptographie JDBC-Paket Verschiedene Hilfsklassen Swing-Komponenten Fr JDK 1.1.x: com.sun.java.swing (JDK 1.2) CORBA-Schnittstelle

Kapitel 20
Applets (java.applet)

org.omg.CORBA

798

Application / Applet / Servlet


Application
Java-Programm, welches (in der Regel) alle Systemresourcen nutzen darf Abgrenzung von Applets mit eingeschrnkten Rechten

Applets
Ziel: Applet fr Bankautomat zur Anzeige im Web-Browser bzw. im AppletViewer

Mens und Applets

Applet
Java Programm, welches innerhalb von Web-Browsern lauffhig ist
Netscape Navigator HotJava von Sun Microsystems InternetExplorer von Microsoft

Es gibt eingeschrnkte Rechte, z.B. darf nicht ohne Erlaubnis des Administrators auf lokales Dateisystem zugegriffen werden

Servlet
Serverprogramm, mit dem Applets eine Verbindung aufnehmen knnen Ersetzt CGI-Scripts, die kein "Gedchnis" haben
799 800

Applets
Klasse "com.sun.java.swing.JApplet" Applets:

Mens und Applets

Toplevel-Container:
Konstruktion einer Applet-Klasse
Public class HelloApp extends JApplet...

Applet

Programmcode wird vom Web-Browser angefordert (per URL) Web-Server verschickt Programmcode zum Web-Browser Web-Browser fhrt Programmcode aus (eigene Java Virtual Machine)

Erzeugung eines JApplet


HelloApp applet=new HelloApp();

Festlegen eines Layouts fr das Fenster


applet.setLayout (einLayoutManager);

Lebenszyklus eines Applets:


applet.init() applet.start() applet.stop()

Selbstinitialisierung Starten Beenden

applet.destroy() Lschung

automatisch nach dem Laden aufgerufen automatisch nach dem Initialisieren beim Verlassen der Web-Seite im Browser fr Garbage Collection
801

Anheften einer Menzeile am oberen Fensterrand


applet.setJMenuBar(einJMenubar);

Hinzufgen von darzustellenden JComponents


applet.getContentPane().add(new JButton(Swing!));

802

Das java.applet - Package


Applet
init(); start(); stop(); destroy(); getAppletInfo(); getParameterInfo();

Beispiel: "Hello World" - Applet


import java.awt.*; import com.sun.java.swing.applet.*; public class HelloApp extends JApplet { public void init() { setSize(200,100); JLabel l= new JLabel(); l.setText("Hello World !"); this.getContentPane().add(l); } }

Mens und Applets

AppletContext
Definition von Interaktionsschnittstellen

AppletStub
interne Schnittstelle zur Implementierung eines Appletviewers

AudioClip
803 804

Ausfhren eines Applets


Zwei Mglichkeiten: AppletViewer vom JDK benutzen Aufruf des Applets in Web-Seite einbetten
<APPLET> Tag:
<APPLET CODE=HelloApp.class WIDTH=500 HEIGTH=300 NAME=HelloWorld> </APPLET>

Mens und Applets

Parameterbergabe an Applets
bergabe von der HTML-Seite zum Applet
HTML: <PARAM> Tags Applet: getParameter() - Methode

Lesen aller Parameter innerhalb des <APPLET> Tags mglich Parameter enthlt immer einen Namen und einen Wert
<PARAM name=Name value=MyApplet>

Anzeigen aller einlesbaren Parameter:


String info[][] = getParameterInfo();

Lesen eines Parameters:


String titel = getParameter(Name);

805

806

Sicherheit bei Applets


Verboten

Mens und Applets

(Standard)-Sicherheitsrestriktionen von Applets


Kein berschreiben von Standard-Klassenbibliotheken und Definieren von native Methoden Kein Lesen und Schreiben von Dateien auf dem Host Kein Herstellen von Netzwerkverbindungen
auer zum Host, von dem es geladen wurde

Herstellen von Netzwerkverbindungen (auer zum Host) Lesen und Schreiben von Dateien auf dem Host Starten von Programmen auf dem Host Auslesen von sicheren System-Einstellungen auf dem Client Laden von Klassenbibliotheken Definieren von native Methoden

Erlaubt
Herstellen von Netzwerkverbindungen zum Host Aufruf anderer Webseiten (per URL) Abspielen von Sounds Kommunikation mit weiteren Applets auf dem Client
807

Kein Starten von Programmen auf dem Host Kein Auslesen von sicheren System-Einstellungen Unterschiedliches Aussehen von Applet-Fenstern und Anwendungsfenstern

808

Was knnen Applets?


Aufbau von Netzwerkverbindungen zum Host einfaches Aufrufen anderer Web-Seiten
showDocument(http://www.javasoft.com/index.html);

Applets aus dem lokalen Filesystem unterliegen nicht den Sicherheitsrestriktionen Abspielen von Sounds Kommunikation mit anderen Applets Fr signierte Applets knnen Sicherheitsrestriktionen gelockert werden
809

Kapitel 21
Threads

Multithreading
java.applet java.awt java.beans java.io java.lang java.math java.rmi java.security java.sql java.util javax.swing (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.0) (JDK 1.0) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.1) (JDK 1.0) (JDK 1.2)

Die Java Klassenbibliotheken


Java-Applets (fr WWW-Browser) AWT-Komponenten Beans-Development Input / Output / Datenstrme Basispackage fr Java Zahlen groer Genauigkeit Remote Method Invocation Sicherheit, Kryptographie JDBC-Paket Verschiedene Hilfsklassen Swing-Komponenten Fr JDK 1.1.x: com.sun.java.swing (JDK 1.2) CORBA-Schnittstelle

Threads
Threads knnen auf einer Maschine mit nur einem Prozessor ablaufen und sich dabei auffhren, als ob sie eigene Prozesse wren. Ihr Unterschied zu wirklich eigenstndigen Prozessen ist, da sie aus einem Hauptprogramm erzeugt werden. Ein Thread modelliert Objekte, die innerhalb eines umgebenden Prozesses einen eigenen Kontrollflu haben. Der Zusammenhang mit anderen Threads ergibt sich durch die Nutzung gemeinsamer Ressourcen (Objekte, CPU-Zeit, Zugriff auf Datenbanken).

org.omg.CORBA

811

812

Multithreading
Multithreading bedeutet:
Programmpfad wird in unterschiedliche Richtungen verzweigt, diese laufen parallel. Ein Thread hier ein Programmpfad, wird auch Ausfhrungskontext oder leichtgewichtiger Proze genannt. Multithreading bedeutet nun, dass es mglich ist, mehrere Threads parallel laufen zu lassen (bei nur einem Prozessor ist dies natrlich leine echte Parallelitt).

Multithreading
Probleme:
Konkurrierende Threads benutzen gleiche Ressourcen und Daten => Bei Zugriff auf gemeinsam genutzte Ressourcen mu Schutz eingreifen (nur ein Thread hat den Monitor) Threads, die mehrere Resourcen gleichzeitig bentigen, knnen sich gegenseitig blockieren (Deadlock), indem sie jeweils eine Ressource festhalten und auf die anderen warten. Nicht jede Virtual Machine verteilt CPU-Zeit automatisch gerecht (Es gibt Timeslicing-fhige und -unfhige Systeme) => Laufende Threads sollten auch anderen eine Chance geben Mgliche Zustnde oft schwer verstndlich, da Parellelitt nicht sehr intuitiv verstndlich

813

814

Beispiel
class AddThread extends Thread{ public void run(){ for(int i=0;i<10;i++){ MyThreadExample.count++; System.out.print("Add "); System.out.println (MyThreadExample.count); } } }
815

Beispiel
class SubtractThread extends Thread{ public void run(){ for(int i=0;i<10;i++){ MyThreadExample.count--; System.out.print("Subtract "); System.out.println( MyThreadExample.count); } } }

816

Beispiel
Mgliches Ergebnis
class MyThreadExample{ public static int count=0; public static void main(String args[]){ AddThread a = new AddThread(); SubtractThread b = new subtractThread(); a.start(); b.start(); } }
Add 1 Add 2 Add 3 Add 4 Add 5 Subtract 5 Subtract Add 4 4 Subtract 3 Subtract 4
817

Beispiel

Subtract 2 Subtract Add 1 Add 2 1 Subtract 2 Subtract 1 Subtract Add 0 Add 0 Subtract 0 1
818

Thread / Runnable
Ein Thread wird immer in einer run-Methode gestartet
public void run() Diese Methode mu von einer Klasse implementiert werden, dessen Objekt sich mit einem eigenen Thread ablsen mchte Bei Start des Threads wird die run-Methode vom System automatisch aufgerufen (nicht selbst aufrufen!)

java.lang

Die Java Klassenbibliotheken

Threadfhigkeit einer Klasse kann auf zwei Arten erreicht werden


erben von der Klasse Thread
Thread

MyClass

Ein Threadfhige Klasse kann durch zwei Mglichkeiten definiert werden:


A) Erben von der Klasse Thread, hier mu die run()-Methode der Klasse Thread berschrieben werden B) Implementieren des Interfaces Runnable, hier mu die run()Methode des Interfaces implementiert werden
819

implementieren des Interfaces Runnable


MyClass Runnable

820

java.lang

Die Java Klassenbibliotheken

java.lang

Die Java Klassenbibliotheken

in beiden Fllen wird die Methode run() implementiert


im erbenden Fall wird sie berschrieben
Thread

in beiden Fllen wird die Methode run() implementiert


im Interface Fall wird sie implementiert
MyClass Runnable

MyClass class MyClass extends Thread { public void run() { class MyClass implements Runnable { public void run() {

// hier wird run() berschrieben


} }
821

// hier wird run() implementiert


} }
822

Using the Runnable Interface


class AddThread extends SomeClass implements Runnable{
public void run(){ for(int i=0;i<10;i++) SyncThread.incCount(); } } ... // Where the thread shall be started // a new Thread Object is created AddThread a = new AddThread(); Thread this_is_the_Thread = new Thread(a); this_is_the_Thread.start(); ...

Thread / Runnable
Erzeugen eines Objektes, welches spter einen eigenen Programmpfad bekommen soll:
A) Bei Unterklasse von Thread (z. B. MeinThread extends Thread) kann einfach durch new das startfhige Objekt erzeugt werden (hier: Thread leicht = new MeinThread()) B) Bei Implementierung von Runnable (z. B. MeineKlasse implements Runnable) wird durch MeineKlasse a = new MeineKlasse(); ein Objekt erzeugt und durch new Thread dann das startfhige Objekt erzeugt (hier: Thread leicht = new Thread(a))

Starten des Threads:


Durch die start()-Methode von Thread wird der Thread gestartet: leicht.start();
823 824

Warum zwei Mglichkeiten?


Konstruktoren: Einfache Mglichkeit ist, von Thread abzuleiten => einfacheres Verstndnis Aber:
Java kennt keine Mehrfachvererbung von Klassen, jedoch Mehrfachvererbung von Interfaces Es ist Wnschenswert, auch Unterklassen multithreadingfhig zu machen => Hier bleibt nur die Mglichkeit, Runnable zu implementieren

Methoden von Thread


public Thread()
Mu von abgeleiteter Klasse durch super() aufgerufen werden

public Thread(String name)


Mu von abgeleiteter Klasse durch super(name) aufgerufen werden Dem Thread wird hier ein Name gegeben

public Thread(Runnable target)


Mu direkt aufgerufen werden, um Threads ber das Runnable-Interface zu definieren

Methoden:
public native synchronized void start()
Startet den Thread. Die Virtuelle Maschine startet die run()-Methode in eigenem Programmpfad synchronized ist neues Schlsselwort, spter mehr

825

826

Methoden von Thread


Methoden:
public static native Thread currentThread()
Klassenmethode, um den aktuell laufenden Thread zu ermitteln

Deaktivierung eines Threads


Methoden:
sleep
siehe oben

public static native void yield()


Aufforderung, eventuell andere wartende Threads zum Zuge kommen zu lassen

suspend
Unterbricht die Arbeit eines Prozesses

public static native void sleep(long millis) throws InterruptedException


Thread wartet angegebene Zeit. Andere Threads kommen zum Zuge, sofern sie nicht durch belegte Resourcen blockiert sind

wait
veranlat, da ein Proze eine vorgegebene Zeit wartet von Object ererbt

public final void setPriority(int newPriority)


Legt die Prioritt des Threads fest. Threads hherer Prioritt laufen bevorzugt

public final String getName()


Gibt den Namen des Threads zurck
827 828

Aktivierung eines passiven Threads


Methoden:
resume
Gegenstck zu suspend

Vernichten eines Prozesses


Methoden:
stop
anomale und sofortige Beendigung eines aktiven oder gerade erzeugten Prozesses (mit Aufrumarbeiten)

notify, notifyAll
reaktiviert wartende Prozesse (Gegenstck zu wait) von Object ererbt

destroy
wie stop aber ohne Aufrumarbeiten

829

830

Zustandsbergnge von Threads

Zustandsbergnge von Threads


Ein neuer Thread (Zustand new), der noch nicht ausgefhrt wurde, erfordert vor der ersten Ausfhrung erst mal die Zuweisung von Ressourcen (Speicher). Dann wird er mittels der Methode start() in den Zustand runnable berfhrt. Runnable bedeutet, da der Proze durchgefhrt werden kann (also aktiv werden kann). Allerdings kann nur ein Proze zu jeder Zeit aktiv sein. Die wartenden, schlafenden, unterbrochenen Prozesse sind im Zustand blocked. Wenn der aktive Proze in den Zustand blocked bergeht, dann wird ein runnable Proze aktiviert.
831 832

Zustandsbergnge von Threads


Die JVM whlt aus der Menge der runnable Prozesse den durchzufhrenden aus. Hier gibt es Unterschiede zwischen den JVMs auf verschiedenen Plattformen. Ein Proze verlt den Zustand blocked, wenn die Schlafperiode zu Ende geht, er notifiziert wird (notify), die I/O-Operation, auf die er wartet, terminiert, wenn er per resume fortgesetzt wird.
833

Zustandsbergnge von Threads


Threads gehen in de Zustand dead ber, wenn
seine run()-Methode beendet wird, seine stop()- oder destroy-Methode aufgerufen wird.

Ein dead Thread kann nicht reaktiviert werden.

834

Prioritten
Jeder Thread hat eine Prioritt. Die JVM bevorzugt die Threads mit hohen Prioritten, wenn ein Thread von runnable in aktiv berfhrt werden soll. Threads laufen solange bis:
er die yield()-Methode aufruft, er nicht mehr runnable ist (z.B. weil er auf einen initiierten I/O warten mu), ein Thread mit hherer Prioritt runnable wird.

Egoistische Threads
Ein langlaufender Thread mit hoher Prioritt, der kein I/O veranlat, kann den Prozessor dauerhaft beanspruchen. Das ist kein Problem, wenn die JVM zeitscheiben-fhig ist. Langlaufende Threads sollten regelmig sleep() oder yield() aufrufen, um auch anderen Threads Zugriff zu erlauben.

835

836

Monitore
Sperren sind ein Mittel, um den parallelen Zugriff auf Ressourcen zu reglementieren. Ein kritischer Abschnitt ist ein Speicherbereich, auf den immer nur ein Proze zugreifen darf. Eine typische Art von kritischen Abschnitten sind Variablen, diese drfen nicht beliebig parallel gelesen und geschrieben werden. Es ist mglich, Bereiche zu schtzen, die nur ein Thread zur Zeit abarbeiten darf.

Monitore
Jedes Objekt besitzt genau einen Monitor, ein Thread kann nur in einen geschtzten Bereich eintreten, wenn der entsprechende Monitor frei ist Objekte, die Threads blockieren knnen und die Threads notifizieren, wenn die Bearbeitung weitergehen kann, werden Monitor genannt. Monitore realisieren Sperren. Jedes Objekt mit einer oder mehreren synchronisierten Methoden, wird Monitor genannt. In einer synchronisierten Methode kann ein Thread seine Sperre mittels wait() aufgeben.

837

838

Synchronisation
Wenn ein Objekt zu einer Klasse mit synchronisiserten Methoden gehrt, dann hat es eine Schlange, in der alle Threads verwaltet werden, die die synchronized Methode aufgerufen haben. Aufrufende Threads kommen in diese Schlange, wenn:
sie eine synchronized Methode aufrufen, whrend ein anderer Thread auf das Objekt zugreift, wenn sie in der aufgerufenen, synchronized Methode wait() aufrufen.

Parallelittsregeln
Wenn 2 oder mehr Threads ein Objekt modifizieren, sollten die modifizierenden Methoden als synchronized deklariert werden. Wenn eine Methode einen Thread anhalten mu, um das Objekt selbst zu ndern, dann sollte wait() aufgerufen werden. Wenn eine synchronized Methode ihr Objekt ndert, dann sollten die gerade wartenden Prozesse mit notifyAll() alarmiert werden.

839

840

Monitorkonzept
Es lassen sich sowohl einzelne Blcke, als auch ganze Methoden schtzen:
Eine ganze Methode kann durch Kennzeichnung von synchronized geschtzt werden, z. B.: public synchronized int get() { ... } Ein Block kann durch synchronized(ObjektName) { ... } geschtzt werden. Hierbei wird der Monitor des Objektes ObjektName belegt.

Methoden der Klasse Object


Alle Threads, die den Monitor einer Klasse bekommen wollen, werden in einer Warteliste aufgenommen. Hier greifen dann die bereits oben diskutierte Zustandsbergnge. Sie sind solange blockiert, bis sie geweckt werden:
Die Methode public final void notify() der Klasse Object benachrichtigt einen Thread aus der Warteliste auf den zum Objekt zugehrigen Monitor (willkrliche Auswahl) Die Methode public final void notifyAll() der Klasse Object benachrichtigt alle Threads aus der Warteliste, diese werden um den Monitor konkurrieren

841

842

Methoden der Klasse Object


Monitor vorbergehend freigeben:
Mit der Methode public final void wait() throws InterruptedException wird der Monitor freigegeben und der Thread geht in Wartezustand, bis er von einem anderen Thread durch notify() oder notifyAll() geweckt wird Nach Wecken setzt der Thread seine Arbeit an gleicher Stelle fort Wichtig, um auf nicht freie Resourcen zu warten => andere Threads mssen die Chance bekommen, die Resourcen freizugeben

Beispiel: Handshake-Verfahren
Wenn Daten zwischen Threads ausgetauscht werden sollen, gibt es Synchronisationsprobleme. Tunnel-Klasse soll von einem Thread jeweils ein Paket Daten aufnehmen und an einen anderen Thread weitergeben Alle Synchronisationsprobleme sollen in dieser Klasse gelst werden Erzeuger- und Verbraucherklassen sollen in eigenem Thread laufen

843

844

Handshake-Verfahren: Tunnel
class Tunnel { private int inhalt; private boolean verfgbar = false; public synchronized int nehmen() { while (verfgbar == false) { try { wait(); } catch (InterruptedException e){} } verfgbar = false; notifyAll(); return inhalt; } public synchronized void geben(int wert) { while (verfgbar == true) { try { wait(); } catch (InterruptedException e) {} } inhalt = wert; verfgbar = true; notifyAll(); } }
845

Handshake-Verfahren: Erzeuger
class Erzeuger extends Thread { private Tunnel t;

// List int aus Tunnel

public Erzeuger(Tunnel tunnel) { t = tunnel; } public void run() { for (int i=0; i<5; i++) { t.geben(i); System.out.println("Erzeuger schreibt " + i); try { Thread.sleep((int)(Math.random() * 100)); } catch (InterruptedException e) { } } } }
846

// Schreibt int in Tunnel

Handshake-Verfahren: Verbraucher
class Verbraucher extends Thread { private Tunnel t; public Verbraucher(Tunnel tunnel) { t = tunnel; } public void run() { int wert = 0; for (int i=0; i<5; i++) { wert = t.nehmen(); System.out.println("Verbraucher liest " + wert); } } }

Handshake-Verfahren: StartKlasse
class StartKlasse { public static void main(String[] args) { Tunnel t = new Tunnel(); Erzeuger e = new Erzeuger(t); Verbraucher v = new Verbraucher(t); e.start(); v.start(); } } Ausgabe:
Erzeuger schreibt Verbraucher liest Verbraucher liest Erzeuger schreibt Verbraucher liest Erzeuger schreibt Verbraucher liest Erzeuger schreibt Verbraucher liest Erzeuger schreibt 0 0 1 1 2 2 3 3 4 4
848

847