Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe...

152
Begleittext: Einführung in das Programmieren in Java für Nichtinformatiker Andreas Keese Institut f. Wissenschaftliches Rechnen TU Braunschweig 19. Juni 2017 Der Text, die Abbildungen und Programme wurden mit größter Sorgfalt erarbeitet. Der Autor kann dennoch für möglicherweise verbliebene fehlerhafte Angaben und deren Folgen weder eine juristische Verantwortung noch irgendeine Haftung übernehmen. Die in diesem Text erwähnten Software– und Hardwarebezeichnungen sind in den meisten Fällen auch eingetragene Marken und unterliegen als solche den gesetzlichen Bestimmungen. Copyright 1999, 2000, Andreas Keese. Alle Rechte vorbehalten Inhaltsverzeichnis 1 Einleitung 6 1.1 Lehrbücher zu Java .......................... 6 1.2 Über diesen Text ........................... 7 2 Grundlagen: Wie arbeitet ein Computer ? 8 2.1 Der Aufbau eines Computers .................... 8 2.2 Organisation des Arbeitsspeichers — Bits und Bytes ....... 10 2.3 Die Organisation des Arbeitsspeichers — Adressen ........ 12 2.4 Programmierung eines Computers ................. 13 2.5 Zusammenfassung des Kapitels ................... 15 3 Das Java–Programmiersystem JDK 16 3.1 Bestandteile des JDK ........................ 16 3.2 Übersetzen und Ausführen von Java-Programmen ......... 17 3.3 Zusammenfassung .......................... 20 4 Erste Schritte — die Turtlegraphik 20 4.1 Testen der Turtlegraphik ....................... 20 4.2 Die Bestandteile eines einfachen Java–Programms ......... 21 4.3 Turtlebefehle ............................. 24 1

Transcript of Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe...

Page 1: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Begleittext: Einführung in das Programmieren inJava für Nichtinformatiker

Andreas KeeseInstitut f. Wissenschaftliches Rechnen

TU Braunschweig

19. Juni 2017

Der Text, die Abbildungen und Programme wurden mit größter Sorgfalt erarbeitet. Der Autorkann dennoch für möglicherweise verbliebene fehlerhafte Angaben und deren Folgen weder einejuristische Verantwortung noch irgendeine Haftung übernehmen. Die in diesem Text erwähnten

Software– und Hardwarebezeichnungen sind in den meisten Fällen auch eingetragene Marken undunterliegen als solche den gesetzlichen Bestimmungen.

Copyright 1999, 2000, Andreas Keese. Alle Rechte vorbehalten

Inhaltsverzeichnis1 Einleitung 6

1.1 Lehrbücher zu Java . . . . . . . . . . . . . . . . . . . . . . . . . . 61.2 Über diesen Text . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2 Grundlagen: Wie arbeitet ein Computer ? 82.1 Der Aufbau eines Computers . . . . . . . . . . . . . . . . . . . . 82.2 Organisation des Arbeitsspeichers — Bits und Bytes . . . . . . . 102.3 Die Organisation des Arbeitsspeichers — Adressen . . . . . . . . 122.4 Programmierung eines Computers . . . . . . . . . . . . . . . . . 132.5 Zusammenfassung des Kapitels . . . . . . . . . . . . . . . . . . . 15

3 Das Java–Programmiersystem JDK 163.1 Bestandteile des JDK . . . . . . . . . . . . . . . . . . . . . . . . 163.2 Übersetzen und Ausführen von Java-Programmen . . . . . . . . . 173.3 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . 20

4 Erste Schritte — die Turtlegraphik 204.1 Testen der Turtlegraphik . . . . . . . . . . . . . . . . . . . . . . . 204.2 Die Bestandteile eines einfachen Java–Programms . . . . . . . . . 214.3 Turtlebefehle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

1

Page 2: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

5 Grundlagen der Java-Syntax 285.1 Grundsätzliches zur Syntax von Java–Programmen . . . . . . . . 285.2 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . 32

6 Variablen und Datentypen 336.1 Variablen und ihr Typ . . . . . . . . . . . . . . . . . . . . . . . . 33

6.1.1 Ganze Zahlen . . . . . . . . . . . . . . . . . . . . . . . . . 346.1.2 Fließkommazahlen . . . . . . . . . . . . . . . . . . . . . . 356.1.3 Logischer Datentyp . . . . . . . . . . . . . . . . . . . . . . 356.1.4 Zeichen und Zeichenketten . . . . . . . . . . . . . . . . . 36

7 Ausdrücke 367.1 Was ist ein Ausdruck ? . . . . . . . . . . . . . . . . . . . . . . . . 367.2 Literal–Ausdrücke . . . . . . . . . . . . . . . . . . . . . . . . . . 38

7.2.1 Ganzzahlige Literale . . . . . . . . . . . . . . . . . . . . . 397.2.2 Reellwertige Literale . . . . . . . . . . . . . . . . . . . . . 407.2.3 Litarale vom Typ boolean . . . . . . . . . . . . . . . . . . 417.2.4 Zeichenliterale . . . . . . . . . . . . . . . . . . . . . . . . 427.2.5 Zeichenketten . . . . . . . . . . . . . . . . . . . . . . . . . 43

7.3 Verwendung von Variablen . . . . . . . . . . . . . . . . . . . . . 447.4 Ausdrücke mit Operatoren . . . . . . . . . . . . . . . . . . . . . . 46

7.4.1 Arithmetische Operatoren . . . . . . . . . . . . . . . . . . 497.4.2 Inkrement und Dekrement–Operatoren . . . . . . . . . . . 497.4.3 Relationale Operatoren . . . . . . . . . . . . . . . . . . . 527.4.4 Logische Operatoren . . . . . . . . . . . . . . . . . . . . . 527.4.5 Bitweise Operatoren . . . . . . . . . . . . . . . . . . . . . 537.4.6 Zuweisungsoperatoren . . . . . . . . . . . . . . . . . . . . 537.4.7 Weitere Operatoren . . . . . . . . . . . . . . . . . . . . . 55

7.5 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . 56

8 Typwandlungen 578.1 Automatische Typkonvertierungen . . . . . . . . . . . . . . . . . 578.2 Manuelle Typkonvertierungen . . . . . . . . . . . . . . . . . . . . 608.3 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . 61

9 Anweisungen und Kontrollstrukturen 619.1 Leere Anweisung . . . . . . . . . . . . . . . . . . . . . . . . . . . 629.2 Blockanweisung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 629.3 Variablendefinitionen . . . . . . . . . . . . . . . . . . . . . . . . . 639.4 Ausdrucksanweisungen . . . . . . . . . . . . . . . . . . . . . . . . 649.5 If–Anweisung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659.6 Switch–Anweisung . . . . . . . . . . . . . . . . . . . . . . . . . . 669.7 Schleifen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

2

Page 3: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

9.7.1 Die While–Schleife . . . . . . . . . . . . . . . . . . . . . . 679.7.2 Die Do–Schleife . . . . . . . . . . . . . . . . . . . . . . . . 699.7.3 Die For–Schleife . . . . . . . . . . . . . . . . . . . . . . . 709.7.4 break und continue . . . . . . . . . . . . . . . . . . . . . . 74

9.8 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . 75

10 Objekte in Java 7510.1 Objekte und primitive Datentypen . . . . . . . . . . . . . . . . . 7610.2 Der Lebenszyklus eines Objektes . . . . . . . . . . . . . . . . . . 78

10.2.1 Die Erzeugung von Objekten . . . . . . . . . . . . . . . . 7810.3 Die Identität eines Objektes . . . . . . . . . . . . . . . . . . . . . 8110.4 Die Kommunikation mit Objekten . . . . . . . . . . . . . . . . . 8310.5 Welche Botschaften versteht ein Objekt ? . . . . . . . . . . . . . 8510.6 Die Zerstörung von Objekten . . . . . . . . . . . . . . . . . . . . 8610.7 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . 87

11 Arrays 8811.1 Definition von Arrays . . . . . . . . . . . . . . . . . . . . . . . . 8811.2 Verwendung von Arrays . . . . . . . . . . . . . . . . . . . . . . . 9011.3 Array–Literale . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9111.4 Primitive Arrays und Objektarrays . . . . . . . . . . . . . . . . . 9111.5 Referenztypen am Array-Beispiel . . . . . . . . . . . . . . . . . 9311.6 Mehrdimensionale Arrays . . . . . . . . . . . . . . . . . . . . . . 9311.7 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . 95

12 Klassen in Java 9612.1 Instanz- und Klassenbestandteile . . . . . . . . . . . . . . . . . . 9612.2 Zugriff auf Methoden und Attribute . . . . . . . . . . . . . . . . 9812.3 Die Bestandteile einer Java–Klasse . . . . . . . . . . . . . . . . . 9912.4 Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10112.5 Definition von Methoden . . . . . . . . . . . . . . . . . . . . . . . 10212.6 Mehrere Methoden mit gleichem Namen . . . . . . . . . . . . . . 10612.7 Konstruktoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10812.8 Die Parameterübergabe an eine Methode . . . . . . . . . . . . . 10812.9 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . 109

13 Dokumentieren von Java–Programmen 11013.1 Wie arbeitet javadoc ? . . . . . . . . . . . . . . . . . . . . . . . . 11013.2 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . 111

14 Vererbung — Extensionen von Klassen 11214.1 Ein einführendes Beispiel . . . . . . . . . . . . . . . . . . . . . . 11214.2 Erweitern von Klassen . . . . . . . . . . . . . . . . . . . . . . . . 11414.3 Überschreiben von Methoden . . . . . . . . . . . . . . . . . . . . 115

3

Page 4: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

14.4 Die super–Variable . . . . . . . . . . . . . . . . . . . . . . . . . . 11714.5 Vererbung und Konstruktoren . . . . . . . . . . . . . . . . . . . . 11814.6 Beispiele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11914.7 Die Object-Klasse . . . . . . . . . . . . . . . . . . . . . . . . . . 12114.8 Abstrakte Klassen . . . . . . . . . . . . . . . . . . . . . . . . . . 12114.9 Zuweisung an Variablen und Arrays . . . . . . . . . . . . . . . . 12314.10Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . 125

15 Packages 12615.1 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . 128

16 Exceptions 12816.1 Try–catch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12916.2 Ausnahmen werfen . . . . . . . . . . . . . . . . . . . . . . . . . . 13116.3 Exceptions in Methoden . . . . . . . . . . . . . . . . . . . . . . . 13116.4 Ein paar abschließende Bemerkungen . . . . . . . . . . . . . . . . 13316.5 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . 133

A Anhang: Unix, Editor und CIP-Pool 134A.1 Hinweise zu weiterer Unix-Literatur . . . . . . . . . . . . . . . . 134A.2 Editoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

A.2.1 Der nedit-Editor . . . . . . . . . . . . . . . . . . . . . . . 134A.2.2 Der Emacs-Editor . . . . . . . . . . . . . . . . . . . . . . 135

A.3 Das Hilfe-System . . . . . . . . . . . . . . . . . . . . . . . . . . . 135A.3.1 Der man-Befehl . . . . . . . . . . . . . . . . . . . . . . . . 135A.3.2 Der Apropos-Befehl . . . . . . . . . . . . . . . . . . . . . 136

A.4 Ausgabeumleitung . . . . . . . . . . . . . . . . . . . . . . . . . . 137A.5 Trennung von Rechner und Bildschirm . . . . . . . . . . . . . . . 139

B Anhang: Verwendung von Java unter Unix 140B.1 Java-Compiler und Laufzeitumgebung . . . . . . . . . . . . . . . 140B.2 Kompilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141B.3 Datentypen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142

C Probleme 142C.1 Probleme bei Verwendung von javac . . . . . . . . . . . . . . . . 142C.2 Probleme bei Verwendung von java . . . . . . . . . . . . . . . . . 144

D Goldene Regeln fürs Programmieren 145D.1 Allgemeines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145D.2 Quelldateien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145D.3 Klassen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146D.4 Methoden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146D.5 Variablen, Konstanten und Literale . . . . . . . . . . . . . . . . . 146

4

Page 5: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

D.6 Kontrollstrukturen . . . . . . . . . . . . . . . . . . . . . . . . . . 148

E Installation von Java und Turtle–Graphik 149E.1 Installation von Java . . . . . . . . . . . . . . . . . . . . . . . . . 149E.2 Der CLASSPATH . . . . . . . . . . . . . . . . . . . . . . . . . . 149E.3 Installation der Turtle–Graphik . . . . . . . . . . . . . . . . . . . 150E.4 Erweitern des CLASSPATH . . . . . . . . . . . . . . . . . . . . . . 151

Inhaltsverzeichnis

5

Page 6: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

1 EinleitungIn der Veranstaltung „Einführung in das Programmieren“ wollen wir Sie dabeiunterstützen, das Programmieren in Java1 zu erlernen. Dabei gehen wir davonaus, daß Ihre bisherige Erfahrung im Programmieren vernachlässigbar sind.Bitte beachten Sie:Dieser Begleittext ist im Wintersemester 1999/2000 entstanden und ist auf diedamalige Form dieser Veranstaltung zugeschnitten. Im Sommersemester 2000wurde der Fokus der Veranstaltung etwas verändert.Momentan passen nur die ersten 4 Kapitel sowie die Anhänge zur momentanenForm der Veranstaltung. Es ist nicht sicher, ob wir auch die späteren Kapitelüberarbeiten werden. Unabhängig davon können Sie die ersten 4 Kapitel den-noch mit Gewinn für sich nutzen.

1.1 Lehrbücher zu Java

Es sollte zunächst erwähnt werden, daß Java sehr viele Bestandteile hat. Zumeinen gehört zu Java die Java-Programmiersprache, zum anderen enthält Javaviele Werkzeuge, die es ermöglichen, Fenster und Graphiken auf dem Monitoranzuzeigen. Es gibt Werkzeuge, mit denen der Rechner zur Tonerzeugung ver-wendet werden kann oder mit denen man Programme fürs Internet schreibenkann. Alle Bestandteile von Java zusammen nennt man das JDK: Java Deve-lopment Kit.Die meisten Lehrbücher zu Java versuchen, alles über Java erzählen, und dasgeht dann zu Lasten der Erklärung der Programmiersprache — meistens ist fürdie Grundlagen der Programmierung in diesen Büchern weniger als ein Drittelvorgesehen.Nun wollen wir Ihnen in dieser Veranstaltung aber gerade die Grundlagen desProgrammierens vermitteln. Die Entwicklung von Internet-, Fenster- und Gra-phikanwendungen mag ja sehr interessant sein, aber bevor man derartige Pro-gramme schreibt, sollte man doch die Grundlagen der Programmierung beherr-schen.Ein sich uneingeschränkt eignendes Lehrbuch zu Java für Programmieranfänger,haben wir leider nicht gefunden. Daher haben wir den vorliegenden Text erstellt.Die folgenden Lehrbücher sind bedingt empfehlenswert:

• Computing Concepts with JAVA Essentials Cay S. HorstmannJohn Wiley & Sons, 2000, 89,90,– DMComputing Concepts with JAVA Essentialsßeichnet sich aus durch eine an-fängerorientierte, didaktisch sehr gute Darstellung des Stoffes, die für denStudienanfänger durch die englische Sprache - mit Fachidiom der EDV undProgrammiersprachen - gedämpft wird. Das Buch enthält eine Vielzahl anProgrammbeispielen und stellt alle Konzepte der Sprache weitgehend um-fassend und gut verständlich dar. Rückgriffe auf Rechnerarchitektur undHistorie lockern den Stoff auf.

1http://www.java.sun.com

6

Page 7: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Das Buch ist gut geeignet, die Veranstaltung im Selbststudium zu ergän-zen. Auf der Webseite2 des Authors finden Sie weitere Hinweise zum Buch.

• Go To Java 2Guido KrügerAddison–Wesley, 1999, ISBN 3–8273–1370–8, 89,90,– DMDieses Buch eignet sich sehr gut für Leser mit etwas Programmiererfah-rung. Das Buch ist in einer Online–Version frei erhältlich, welche wir aufunserem Server3 spiegeln.Falls Sie an einem Rechner außerhalb des Netzes der TU Braunschweigarbeiten, können Sie das Buch auf den Seiten des Authors4 lesen.

• Java in 21 TagenLaura Lemay, Charles L. PerkinsMarkt u. Technik, 1999, 89,95,– DM.Dieses Buch eignet sich gut für Programmieranfänger. Es ist im WWW5

frei verfügbar.

• The Java Tutorial Mary Campione, Kathy WalrathAddison Wesley, 1998, 85,- DM„The Java Tutorial“ richtet sich an Personen, die bereits programmierenkönnen. Es beschreibt mit vielen instruktiven Beispielen, wie man in JavaFenster-, Graphik- oder Internetanwendungen programmiert.Dabei ist aufgrund der vielen Querverweise im Buch die Html-Version ver-mutlich besser lesbar als die gedruckte Fassung. Wir spiegeln die Online–Fassung6.Wenn Sie an einem Rechner außerhalb des Netzes der TU Braunschweigarbeiten, können Sie es auf den Seiten von Sun7 lesen.

1.2 Über diesen Text

Aufgrund der Probleme bei der Suche nach einem Lehrbuch haben wir uns ent-schlossen, einen Begleittext zur Veranstaltung zu schreiben. Er soll gemeinsammit den Hausaufgabe als Leitfaden durch die Veranstaltung dienen — wir wer-den Ihnen in den Hausaufgaben mitteilen, wann Sie welche Kapitel lesen sollenoder wann Sie auf Sekundärliteratur zurückgreifen sollen.Es ist empfehlenswert, den Text parallel zu den Hausaufgaben zu verwenden.Sie finden in den Hausaufgabenblöcken Hinweise, welche Teile im Begleittextvor oder während der Bearbeitung gelesen werden sollten.Zum Lesen des Textes noch folgende Hinweise:

• Jedes Kapitel endet mit einer Reihe von Fragen, die Sie nach dem Lesendes Kapitels beantworten können sollten. Sie können diese Fragen verwen-den, um vor dem Lesen des Kapitels einen Eindruck von seinem Inhalt

2http://www.horstmann.com/3http://www.tu-bs.de:82/wir/EIP/gj/cover.html4http://www.gkrueger.com5http://www.mut.de/leseecke/buecher/java2/inhalt.html6http://www.tu-bs.de:82/wir/EIP/tutorial/7http://java.sun.com/docs/books/tutorial/

7

Page 8: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

zu erhalten. Außerdem können Sie anhand der Fragen prüfen, ob Sie dasKapitel verstanden haben.

• Wir präsentieren viele Beispiele. Bitte vollziehen Sie die Programmierbei-spiele und Kommandos am Rechner nach.

• Kommandozeilenbefehle präsentieren, schreiben wir als

> Kommando

Dabei bedeutet das führende Größerzeichen, daß Sie diesen Text auf derKommandozeile eingeben sollen. Es soll nicht mit eingetippt werden.

Beim Erlernen des Programmierens in Java wünschen wir Ihnen viel Erfolg !

2 Grundlagen: Wie arbeitet ein Computer ?Bevor wir auf die Programmierung von Rechnern eingehen, möchten wir sicher-gehen, daß Sie ein Grundverständnis vom Aufbau und von der Funktionsweiseeines Rechners haben. Was es bedeutet, einen Rechner zu programmieren wollenwir Ihnen auch beschreiben.Im weiteren verwenden wir übrigens den deutschen Begriff „Rechner“ und denenglischen Begriff „Computer“ synonym.Wenn Sie bereits eine klare Vorstellung vom Aufbau und der Funktionsweiseeines Computers haben, können Sie diesen Abschnitt überfliegen oder über-springen und Ihr Wissen anhand der Zusammenfassung am Ende des Kapitelsüberprüfen.

2.1 Der Aufbau eines Computers

Es bedarf eigentlich keines Kommentars, daß Computer heutzutage in allenLebensbereichen eingesetzt werden. Computer berechnen, ob geplante Brückenstehenbleiben werden, sie steuern Flugzeuge, erledigen Ihre Steuererklärung undmoderne Filme werden meist komplett im Computer nachbearbeitetet.Es mag vielleicht überraschen — aber es gibt einen Oberbegriff für diese vielfäl-tigen Fähigkeiten von Computern: „Datenverarbeitung“. Egal, was ein Com-puter tut, er verarbeitet immer Daten. Dabei ist ein Computer ziemlich dumm— ob er Musikdaten verarbeitet, für einen Film künstliche Dinosaurier aufer-stehen lässt, ob er Ihre Steuereklärung bearbeitet oder Lara Croft aufregendeAbenteuer bestehen läßt, ist ihm ziemlich egal. Er ist nicht dazu in der Lage,einen Unterschied zwischen all diesen verschiedenen Daten zu bemerken. Fürihn bestehen Daten nur aus Zahlen. Wir Menschen müssen ihm bis ins kleinsteDetail erklären, wie all diese Zahlen verarbeitet und interpretiert werden sollen.Ob aus einer Zahlenkolonne dann ein Lied, ein Film oder eine Steuererklärungwird, wird nur durch die Datenverarbeitungsregeln — durch das Programm— bestimmt.Die wesentlichen Bestandteile eines Computers zeigt die folgende Graphik:

8

Page 9: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Graphik 1 : Aufbau eines Computers

Benutzer−schnittstelle

Zentraleinheit (CPU)

Dateneingabe

Arbeitsspeicher Nicht−flüchtiger Speicher:

ROM RAM Festplatte Diskette

Tastatur Maus Drucker Bildschirm

Speicher

Datenausgabe

Die zu verarbeitenden Daten müssen dem Computer irgendwie übergeben wer-den — jeder Computer benötigt also Dateneingabe-Möglichkeiten. Die wich-tigsten Dateneingabegeräte sind die Tastatur und die Maus.Auch die Regeln, nach denen er diese Daten verarbeiten soll, müssen dem Com-puter irgendwie genannt werden. Da diese Regeln bzw. Programme nichts an-deres als spezielle Daten sind, können sie auf dieselbe Art und Weise in denComputer eingeben werden wie alle anderen Daten auch.Da wir Menschen die vom Computer verarbeiteten Daten irgendwie weiter ver-wenden wollen, besitzen fast alle Computer Möglichkeiten zur Datenausgabewie Monitor, Drucker oder Soundkarte.Die zu verarbeitenden Daten und die Programme muß sich der Computer ir-gendwo merken. Dies geschieht im Speicher des Computers. Wir unterscheidenflüchtigen und nicht-flüchtigen Speicher.Die im flüchtigem Speicher enthaltenen Daten werden bei jedem Ausschaltendes Computers gelöscht. Unter flüchtigem Speicher versteht man vor allem denRAM — Random Access Memory — genannten Teil des Arbeitsspeichers.Wenn man den Computer ausschaltet, gehen alle Inhalte des RAM verloren.Dem RAM kommt eine besondere Bedeutung zu, weil in der Regel alle vomComputer zu verarbeitenden Daten und Programme vor der Verarbeitung hier-her übertragen werden müssen.Die Datenverarbeitung selber geschieht mit Hilfe der CPU (Central ProcessingUnit = Zentraleinheit), welche auch Prozessor genannt wird. Der Prozessor isteigentlich immer beschäftigt — sobald der Computer angeschaltet wird, beginnter damit, im Arbeitsspeicher enthaltene Programme abzuarbeiten und gönntsich dabei (fast) keine Pause, bis man den Computer ausschaltet.Damit die Programme und Daten nicht bei jedem Anschalten des Computersneu eingetippt werden müssen, besitzt heutzutage jeder Computer auch nicht-flüchtigen Speicher, also Speicher dessen Inhalt beim Ausschalten des Computersnicht verloren geht. Als wichtigste Vertreter sind hier die Festplatte, Disketten-laufwerke und CD-Roms zu nennen. Da die Festplatte meist einer der schnellstennicht-flüchtigen Speicher eines Rechners ist, werden häufig benötigten Datendort gespeichert.Ein weiterer wichtiger nicht-flüchtigen Speicher ist dasROM (Read-only Memo-ry). Das ROM ist ein nicht-beschreibbarer Teil des Arbeitsspeichers. Sie selbst

9

Page 10: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

können im ROM Ihres Computers also keine Daten ablegen. Trotzdem könntekein Computer ohne ROM arbeiten. Der Grund hierfür ist, daß ein Computernichts tun kann, das man ihm nicht in allen Einzelheiten erklärt. Er benötigtsogar ein Programm, das ihm erklärt, wie er zu starten hat. Beim Start muß derComputer nämlich alle angeschlossenen Geräte erkennen und in Gang setzen,und wie er das zu tun hat, ist im ROM beschrieben.Außerdem muß der Computer direkt nach dem Anschalten dasBetriebssystemstarten, auch OS (Operating System) oder DOS (Disk Operating System) ge-nannt. Ein Betriebssystem ist ein sehr umfangreiches Programm, welches denComputer durch Menschen benutzbar macht. Das Betriebssystem ermöglichtdem Computer, mit seinen Benutzern zu kommunizieren (wichtige Betriebssy-steme sind MS DOS, MS Windows, das Mac-OS sowie Unix-Betriebssystemewie Linux oder Solaris). Ohne Betriebssystem wüsste der Computer nicht, waser auf dem Bildschirm anzeigen soll, und man könnte ihn weder per Maus nochper Tastatur bedienen.Wie wird das Betriebssystem gestartet ? Beim Anschalten weiß der Computernoch gar nicht, wie er das Betriebssystem von der Festplatte laden und startensoll. Deshalb hat der Hersteller des Computers die hierfür benötigten Program-me im ROM abgelegt. Beim Start befolgt der Computer zunächst das im ROMgespeicherte Startprogramm und startet dabei das Betriebssystem.Die Rechner, an denen Sie im CIP-Pool während des Kurses arbeiten werden,laufen übrigens alle unter einer Variante des Betriebssystems Unix, welche vonder Firma IBM unter dem Namen AIX vertrieben wird. Beim Bearbeiten derersten Hausaufgabe werden Sie einige Dinge über Unix lernen.

2.2 Organisation des Arbeitsspeichers — Bits und Bytes

Alle Daten und Programme müssen vor ihrer Verarbeitung im RAM abgelegtwerden. Auf der physikalischen Ebene ist das RAM aus unzähligen elektrischenKondensatoren und Transistoren aufgebaut. Ein Kondensator kann dabei ineinem von zwei Zuständen sein: entweder trägt er elektrische Ladung oder erist entladen. Zustände, in denen Kondensatoren nur teilweise aufgeladen sind,werden heutzutage nicht berücksichtigt.Eine Speichereinheit, die nur zwei Zustände annehmen kann, nennen wir Bit,und die beiden Zustände eines Bits beziffern wir mit 0 und 1. Zum Beispielkönnte dem durch einen ungeladenen bzw. geladenen Kondensator repräsentier-ten Bit der Wert 0 bzw. 1 zugeordnet werden.Da ein Bit nur sehr kleine Informationsmengen speichern kann, werden mehrereBits zu größeren Einheiten gruppiert.

Beispiel: Sicher haben auch Sie schon Werbeslogans gehört, in welchenfür 32-Bit-Betriebssysteme oder 32-Bit-Prozessoren geworben wird. Ein32-Bit-Prozessor ist in der Lage, immer 32 Bit auf einmal aus dem Speicherzu lesen und als eine Einheit zu verarbeiten.Ein älterer 16-Bit-Prozessor hingegen verarbeitet Daten immer in 16-Bit-Portionen. Da ein 16-Bit-Prozessor nur 16 Bit auf einmal verarbeitenkann, müsste er zweimal auf den Speicher zugreifen, um 32 Bit zu lesen,und er müsste zwei Operationen ausführen, um 32-Bit zu verarbeiten.Die Anzahl von Bits, die ein Prozessor auf einmal aus dem Speicher holen

10

Page 11: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

und verarbeiten kann, nennt man übrigens die Bus-Breite des Prozesso-res (ein Bus ist ein Bündel von Leitungen, über das Daten transportiertwerden).Wenn die zu verarbeitenden Daten in größeren Gruppen als 16 Bit vor-liegen, kann ein 32-Bit-Prozessor also tatsächlich schneller sein als ein16-Bit-Prozessor. Allerdings müssen die benutzten Programme dazu auchwirklich eine Verarbeitung in 32-Bit-Portionen vorsehen.

Bevor wir darauf eingehen, zu was für Gruppen man Bits zusammenfaßt, wollenwir uns überlegen, wie viele Zustände man mit einer vorgegebenen Anzahl vonBits darstellen kann.

Beispiel:Wenn wir ein Bit verwenden, können wir nur die zwei Zustände0 und 1 darstellen.Wenn wir zwei Bits verwenden, können wir die vier Zustände 00, 01, 10,11 darstellen.Drei Bits können die acht Zustände 000,001,010,011,100,101,110,111 dar-stellen.

Es ist sehr leicht zu sehen, daß n Bits genau 2n verschiedene Zustände annehmenkönnen. Will man also N verschiedene Zustände beschreiben, benötigt man eineAnzahl von Bits, die sich durch Aufrunden von log2N ergibt.

Beispiel: Um jede Zahl von 0 bis 15 darstellen zu können, benötigt manlog216 = 4 Bits.Zur Darstellung der Zahlen 0 . . . 100 sind 7 Bits nötig (log2101 = 6, 66).

Die wichtigsten Einheit, zu denen Bits zusammengefaßt werden, sind:

Byte: Ein Byte besteht aus 8 Bit und kann 28 = 256 Zustände annehmen.Word: Die Größe eines Word hängt vom verwendeten Computer ab. Es besteht

in der Regel aus sovielen Bits, wie der Computer zugleich verarbeitenkann. Heutzutage versteht man unter einem Word meist 8 Byte oder64 Bit.

Meist verwendet man die Begriffe Byte oder Word, um einen einzelnen Zah-lenwert zu beschreiben. Jedem Zustand eines Bytes oder Words kann man eineDezimalzahl zuweisen. Dazu fasst man die Zustände der einzelnen Bits als Bin-ärzahl auf.Der Dezimalwert einer Binärzahl berechnet sich wie folgt: Die Bits der Zahlwerden von rechts beginnend und mit der Zahl 0 startend durchnumeriert. An-schließend bildet man eine Summe, in welcher man für jedes an der Position igesetzte Bit die Zahl 2i einsetzt.

Beispiel: Zum Beispiel hat die Binärzahl 010 die Dezimaldarstellung21 = 2.Die Zahl 010100100 die Dezimaldarstellung 22 + 25 + 27 = 164.

11

Page 12: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Beispiel: Ein weiteres Beispiel: Computer verwenden meist Byte-Werte,um Buchstaben und andere Zeichen zu beschreiben. Dabei wird jedemZeichen ein anderer Zahlenwert zugewiesen. Auf meinem Rechner seheneinige Beispiele für diese Zuordnung so aus:Zeichen Zahlenwert Darstellung in Bits

a 97 01100001b 98 01100010c 99 01100011A 65 01000001# 35 00100011+ 43 001010111 49 00110001

Prüfen Sie bitte nach, ob die dezimale Darstellung und die Bit-Darstellungzusammenpaßt.

Wir haben nun die Grundeinheiten kennengelernt, mit denen ein Computeroperiert. Diese Einheiten werden Ihnen auch bei der Programmierung mit Javaimmer wieder begegnen, denn auch wenn Sie in Java mit Zahlen rechnen, müssenSie manchmal angeben, in welcher Grundeinheit die Zahlen gespeichert werdensollen.Will man beschreiben, wieviele Daten ein Computer speichern kann, benütztman noch größere Einheiten:

KB, Kilo–Byte: 1 KB (Ein Kilo–Byte) sind 210 = 1024 Byte.MB, Mega–Byte: 1 MB (Ein Mega–Byte) sind 210 Kilo–Byte oder 220 = 1.048.576

Byte.GB, Giga–Byte: 1 GB (Ein Giga–Byte) sind 210 Mega–Byte oder 230 = 1.063.641.824

Byte.TB, Tera–Byte: 1 TB (Ein Tera–Byte) sind 210 Giga–Byte bzw. 240 Byte.

Beispiel: Neue Rechner für den Heimgebrauch oder fürs Büro habenheutzutage in der Regel 128 MB Arbeitsspeicher oder mehr und einigeGB Festplattenspeicher; Höchstleistungsrechner haben mehrere GB Ar-beitsspeicher und mehrere hundert GB Festplattenspeicher.

2.3 Die Organisation des Arbeitsspeichers — Adressen

Sie haben erfahren, daß der Arbeitsspeicher eines Rechners aus vielen Bits be-steht, die zu Bytes oder größeren Gruppierungen zusammengefaßt werden. Ob-wohl Sie dies zur Programmierung mit Java nicht unbedingt wissen müssen,möchten wir Ihnen dennoch ganz kurz erzählen, wie der Prozessor Daten imArbeitsspeicher verwendet.Jedes Byte des Arbeitsspeichers hat eine eindeutige Nummer — die Nummereines Bytes nennt man seine Adresse. Der Prozessor kann über die AdresseDaten im Arbeitsspeicher auslesen und Daten in den Arbeitsspeicher schreiben.

Beispiel: Wir können dem Prozessor befehlen, eine Zahl in dem Bytean der Adresse 100 und eine weitere Zahl in dem an der Adresse 200 be-ginnenden Word zu speichern. Anschließend können wir ihn anweisen, die

12

Page 13: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

beiden Zahlen zu addieren und das Ergebnis an der Adresse 300 abzule-gen. Da hierbei ein Byte und ein Word addiert wird, sollte das Ergebnismindestens Word-Größe haben.

2.4 Programmierung eines Computers

Nachdem Sie nun eine gewisse Vorstellung davon haben, wie ein Computer auf-gebaut ist, folgt nun die Erklärung, wie ein Computer Programme verarbeitet.Es ist hoffentlich bereits klar geworden sein, daß Programme nichts anderessind als Regeln, die einem Computer bis ins allerkleinste Detail erklären, wieer gewisse Daten verarbeiten soll. Es stellt sich nun die Frage, wie man demComputer derartige Regeln mitteilen soll. Vorher stellt sich aber die Frage, wasfür Regeln man einem Computer mitteilen kann.Hier sollten Sie sich merken, daß die Regeln, die man einem Computer angibt,immer eindeutig sein müssen. Regeln, die exakt und eindeutig sagen, was zutun ist, nennt man einen Algorithmus. Ein Computer kann nur Algorithmenverarbeiten.

Beispiel: Die Regeln, nach welchen die Dezimaldarstellung einer Binär-zahl mit den Bits bn, . . . , b0 berechnet werden, könnte umgangssprachlichso beschrieben werden wie im vorigen Kapitel (Seite 2.2):

Der Dezimalwert einer Binärzahl berechnet sich wie folgt: DieBits der Zahl werden von rechts beginnend und mit der Zahl 0startend durchnumeriert. Anschließend bildet man eine Sum-me, in welcher man für jedes an der Position i gesetzte Bit dieZahl 2i einsetzt.

Allerdings kann diese Beschreibung mißverstanden werden. Sie ist auchkein Algorithmus, da sie nicht eindeutig ist. Es ist zum Beispiel nichtfestgelegt, in welcher Reihenfolge die Summe gebildet werden soll.Ein Computer benötigt immer eine Vorgehensvorschrift, in der jedes De-tail genau beschrieben wird. Vor allem darf die Regel nicht den geringstenEntscheidungsspielraum lassen und muß eindeutig sein. Eine Umsetzungder obigen umgangssprachlichen Regel in einen Algorithmus könnte soaussehen:

• Gegeben sei eine Binärzahl mit den Bits bn, . . . , b0.• Setze dezimal := 0• Lasse i jeden Wert zwischen 0 und n aufsteigend durchlaufen und

Setze für jeden Wert von idezimal := dezimal + bi · 2i

• dezimal enthält nun die Dezimaldarstellung der Binärzahl bn, . . . , b0

Da die zweite Umrechenregel des obigen Beispiels eindeutig ist, könnte mansie nun in ein Programm für einen Computer umsetzen. Ein Programm istdie Formulierung eines Algorithmus in einer Programmiersprache. Wie schonerwähnt, ist ein Computer ziemlich dumm — er versteht nur eine ganz spezielle,für Menschen ungeeignete Sprache, dieMaschinensprache. Maschinenspracheist eine Sprache, die nur aus Zahlen besteht.

13

Page 14: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Beispiel: Um Sie von Maschinensprache abzuschrecken, zeigen wir Ihnenein Maschinensprache-Programm. Dabei zeigen wir Ihnen nicht die Zah-len, aus denen das Programm besteht sondern eine textliche Darstellung,in der jeder Zahl ein kurzes Wort wie movl oder imull zugeordnet wurde:

movl 30,12345(%ebp)movl 50,23456(%ebp)movl 3456(%ebp),%eaximull 0xfffffff8(%ebp),%eax

Dieses Programm multipliziert die Zahlen 30 und 50.Dazu legt es in der ersten Zeile mit dem Befehl movl die Zahl 30 an derAdresse 12345 ab. Dann legt es in der zweiten Zeile die Zahl 50 an derAdresse Zahl 23456 ab. In der dritten Zeile merkt es sich, daß das Ergebnisder Rechnung an der Adresse 3456 gespeichert werden soll. Schließlichmultipliziert es in der vierten Zeile durch den imull-Befehl die Zahlenund legt das Ergebnis an Adresse 3456 ab.

Sie sehen an diesem Beispiel, daß in Maschinensprache die einfachsten Dingerecht umfangreich werden. Außerdem hat Maschinensprache einen Riesennach-teil — jeder Prozessor hat eine andere Maschinensprache, und einen PC mitIntel-Prozessor in Maschinensprache zu programmieren, ist etwas ganz anders,als einen Macintosh-Rechner zu programmieren. Wenn Sie Maschinenspracheverwenden wollten, müssten Sie für jeden Rechnertyp, auf dem Ihr Programmlaufen soll, ein völlig anderes Programm erstellen.Daher wird heutzutage eigentlich nur noch in höheren Programmiersprachenwie Pascal, C, Pascal, C++ oder Java programmiert — höhere Programmier-sprachen heißen so, weil Sie einen „höheren“ Abstraktionsgrad vom Prozessorhaben als Maschinensprache. Nur ein paar wenige Freaks, Hacker und Spiele-programmier programmieren heutzutage noch in Maschinensprache.Die höheren Programmiersprachen bieten den großen Vorteil, daß man sich nichtselbst darum kümmern muß, an welcher Adresse der Computer Daten ablegensoll, außerdem entspricht ein einzelner Befehl in einer höheren Programmier-sprachen einer ganzen Reihe von Befehlen in Maschinensprache. Die höherenProgrammiersprachen kommen dabei umgangssprachlichen Formulierungen sehrnahe:

Beispiel: Zum Beispiel könnten die Regeln zur Umwandlung einer Binär-in eine Dezimalzahl in Java so lauten:

/* die Bits der Binärzahl seien in b[0], b[1] ... bis in b[n]* gespeichert*/dezimal = 0;for( i = 0; i < n ; i++ ) {

dezimal = dezimal + b[i] * 2^i;}return dezimal;

Sie sehen, daß diese Regeln fast unserem umgangssprachlichen Algorith-mus entsprechen. In Maschinensprache sähe das sehr viel komplizierteraus.

14

Page 15: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Nun hatten wir vorhin doch erwähnt, daß ein Computer nur Maschinenspra-che versteht — wie kann er dann Programme höherer Programmiersprachenverstehen ? Eigentlich ist die Antwort offensichtlich — immer wenn ein Com-puter etwas tun soll, benötigt er eine Vorgehensvorschrift. Damit ein ComputerProgramme höherer Programmiersprachen verstehen kann, muß ihm ein Pro-gramm geben, das für ihn als Übersetzer arbeitet und den Programmtext inMaschinensprache übersetzt.Ein solches Programm nennt sich Compiler. Für jede Programmiersprache gibtes für jeden Rechnertyp einen speziellen Compiler, der gültige Texte der Pro-grammiersprache zu Maschinencode des jeweiligen Rechners kompiliert (kom-pilieren == übersetzen). Der Compiler dient dem Computer quasi als Dolmet-scher für die von uns Menschen erstellten Textdateien.Um ein Programm zu entwickeln und ablaufen zu lassen, sind also die folgendenSchritte nötig:

1. Es muß analysiert werden, was die Problemstellung genau beinhaltet undwelche Ziele mit der Programmentwicklung verfolgt werden sollen (Ana-lysephase).

2. Es muß geplant werden, wie die Problemstellung in ein Programm umge-setzt werden soll. Insbesondere müssen die Regeln, nach denen das Pro-gramm arbeiten soll, umgangssprachlich formuliert werden. Berechnungs-vorschriften müssen hierbei als Algorithmus formuliert werden (Design–Phase).

3. Dann muß das Programm in einer Programmiersprache programmiert wer-den, man sagt auch: „implementiert werden“ (Programmier–Phase).

4. Dann muß das Programm kompiliert werden und kann kann anschließendgetestet oder verwendet werden.

Graphik 2 : Entwicklung eines Programms

Programmvorhaben in umgangssprachlicher Fassung

Eindeutige umgangssprachliche Formulierung (Algorithmus)

Formulierung in höherer Programmiersprache

Maschinensprache

Programmieren

Analyse und Entwurf

Kompilieren

2.5 Zusammenfassung des Kapitels

Sie sollten nun die folgenden Fragen beantworten können:

15

Page 16: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

B Wie unterscheidet ein Computer Musik-, Graphik- und andere Daten ?B Was sind Dateneingabe, Zentraleinheit, Speicher, Datenausgabe ?B Was sind RAM und ROM ?B Was ist ein Betriebssystem ?B Wie ist das RAM aufgebaut ?B Was sind Bits, Bytes, Words, Kilobytes, Megabytes ?B Warum sind Binärzahlen für Computer wichtig ?B Was zeichnet einen Algorithmus aus ?B Was ist der Unterschied zwischen einem Algorithmus und einem Pro-

gramm ?B Warum programmiert man Computer meistens nicht in Maschinen-

sprache ?B Welche Beziehung besteht zwischen Maschinensprache, höherer Pro-

grammiersprache und Compiler ?

3 Das Java–Programmiersystem JDKIm vorigen Kapitel haben Sie erfahren, daß ein Computer nicht in der Lageist, von Menschen lesbare Programme direkt zu verstehen. Der Computer benö-tigt einen Dolmetscher, der das für Menschen verständliche Programm in seineSprache übersetzt.Zum Java–Programmiersystem gehören sogar zwei solche Dolmetscher — derJava–Compiler und die sogenannte Java–Virtual–Machine. Bevor wir auf dieProgrammierung von Java eingehen, müssen wir Sie mit dem Java–Program-miersystem und speziell mit diesen beiden Dolmetschern vertraut machen.

3.1 Bestandteile des JDK

Schon in der Einleitung wurde erwähnt, daß Java8 nicht nur aus einer Program-miersprache besteht. Alles, was man zur Java-Programmierung benötigt, wurdevon den Schöpfern von Java, der Firma Sun9, in einem Paket zusammenge-schnürt, das sich JDK: Java Development Kit nennt.Das JDK enthält folgende Dinge:

• Eine umfangreiche Sammlung von Programmbausteinen. Im JDK sindbereits sehr viele Programmbausteine, sogenannte Klassen, enthalten.Wenn man diese Bausteine in eigene Programme einbaut, kann man mitJava relativ einfach Internet-, Graphik- oder Fenster-Anwendungen erzeu-gen.Wir werden Ihnen in dieser Veranstaltung nur ganz wenige dieser Pro-grammbausteine vorstellen, da wir zum Programmieren lernen lieber selbsteinfache Programme bauen wollen als komplizierte Programme aus diesenProgrammbausteinen zu erstellen.

8http://www.java.sun.com9http://www.sun.com

16

Page 17: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

• Umfangreiche Dokumentation: Für all diese fertigen Programmbausteine(Klassen) und alle anderen Werkzeuge von Java liegt umfangreiche Do-kumentation von HTML–Dateien vor, welche mit einem WWW–Browserbetrachtet werden kann.Um die von Java bereitgestellten Programmbausteine zu verwenden, mußman viel mit dieser Dokumentation arbeiten. Daher werden wir im Rah-men dieser Veranstaltung ein paar Aufgaben stellen, bei denen Sie sich inder Dokumentation zurechtfinden müssen.

• Einige Werkzeuge, zum Beispiel ein Werkzeug, das Ihre Programme liestund die enthaltene Dokumentation in HTML-Dokumenten zusammen-fasst. Dieses Werkzeug werden Sie hier auch kennenlernen.

• Java–Compiler und Java–Virtual–Machine. Diese Programme sind die Dol-metscher zwischen Ihnen und dem Computer.

3.2 Übersetzen und Ausführen von Java-Programmen

Ein Java–Programm besteht aus einem oder mehreren Programmbausteinen,welche Klassen genannt werden. Jede Klasse ist in der Regel in einer eigenenTextdatei beschrieben und wird mit einem Text-Editor erstellt.Bevor Sie weiterlesen, sollten Sie daher mit einem Text-Editor umgehen können.Sie sollten auch mit der Kommandozeile von Unix umgehen können; Hinweisehierzu finden Sie im Anhang A und in der ersten Hausaufgabe. Wenn Sie un-ter anderen Betriebssystemen als Unix arbeiten wollen, beschaffen Sie sich dieentsprechenden Informationen bitte selbst.

Beispiel: In dem untenstehenden Kasten sehen Sie ein sehr einfachesJava–Programm. Wenn man es startet, gibt es den Text „Hallo, Welt“aus.Bitte tippen Sie das Programm in Ihrem Text–Editor ab und speichernes in einer Datei namens Hallo.java. Beachten Sie hierbei bitte, daß dieZeilennummern nicht zum Programm gehören — wenn wir Beispielpro-gramme abdrucken, numerieren wir die Zeilen durch, um auf die einzelnenProgrammteile eingehen zu können.Außerdem achten Sie beim Abtippen bitte auf die Groß- und Kleinschrei-bung. Für Java besteht zwischen großgeschriebenen und kleingeschriebe-nen Buchstaben überhaupt keine Verbindung — so ist das Wort classfür Java etwas völlig anderes als das Wort Class.

Beispiel: Einfache Java–Klasse

1 class Hallo2 {3 public static void main(String[] args)4 {5 System.out.println("Hallo, Welt");6 }7 }

Da in diesem Kapitel nur der Java–Compiler behandelt werden soll, wollenwir hier auf die Funktionsweise von Java–Programmen noch nicht einge-hen. Sie brauchen noch überhaupt nicht zu verstehen, was die ganzen

17

Page 18: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

kryptischen Symbole in dem Programm bedeuten; im nächsten Kapitelwird das alles viel klarer werden.

Sie sollten nun eine Textdatei namens Hallo.java mit dem Text des vorigenBeispiels in ihrem Arbeitsverzeichnis besitzen. Als nächstes soll aus dieser Text-datei ein vom Computer ausführbares Programm erzeugt werden.Dazu verwendet man den Java-Compiler. In Kapitel 2.4 wurde ja bereits er-läutert, daß ein Compiler ein für Menschen verständliches Programm in ein fürComputer verständliches Programm umwandelt.Bevor Sie den Compiler verwenden können, muß auf Ihrem Computer die Java-Programmierumgebung installiert und laufbereit sein. Falls Sie im CIP-Poolder TU Braunschweig arbeiten, dann ist das kein Problem — hier ist alles schonfertig installiert. Wenn Sie jedoch zuhause arbeiten möchten, müssen Sie selbstdafür sorgen, daß die Java–Umgebung funktioniert. Dabei helfen Ihnen vielleichtunsere im WWW verfügbaren Tips weiter (siehe auch WWW-Seite ? ). Wirgehen im weiteren davon aus, daß Sie eine funktionsfähige Java-Programmier-umgebung haben.Aber nun zum Java–Compiler — dieser ist ein Programm namens javac. Umdurch ihn, die zuvor von Ihnen erstellte Datei Hallo.java übersetzen zu lassen,wechseln Sie bitte auf einer Kommandozeile in das Verzeichnis, in welchem Siedie Datei abgespeichert haben. Dort geben Sie dann bitte ein:

> javac Hallo.java

Der Compiler prüft darauf zunächst, ob die Textdatei Hallo.java ein gültigesJava–Programm enthält. Java–Programme müssen einen ganz bestimmten Auf-bau haben, damit sie vom Compiler übersetzt werden können. Nur wenn dieDatei tatsächlich ein gültiges Programm enthält, übersetzt der Compiler sie ineine dem Computer verständliche Form und dient so als Dolmetscher zwischenuns und dem Computer. Wenn Sie die Klasse korrekt abgetippt haben, solltedas Kompilier–Kommando zu keiner Bildschirmausgabe führen.Der Compiler ist auch kleinsten Tippfehlern gegenüber sehr ungnädig — selbstwenn Sie beim Abtippen des Programms nur kleine Fehler gemacht haben, kannes ihnen passieren, daß der Compiler ihr Programm mit einer Fehlermeldungablehnt. Falls Ihnen das beim Compiler–Aufruf passiert ist, prüfen Sie bitte, obSie das Beispielprogramm exakt abgetippt haben, korrigieren es, speichern dieÄnderungen (!) und probieren dann erneut den Aufruf des Compilers. Wenn dasnicht hilft, lesen Sie bitte unsere Hinweise zu Fehlermeldungen in Anhang C.Wenn Sie auch damit nicht weiterkommen, holen Sie sich bitte einen Hiwi zurHilfe.Wir gehen im folgenden davon aus, daß der Aufruf des Compilers funktionierthat. In diesem Fall hat der Compiler Ihr Programm übersetzt und die übersetzteFassung in einer neuen Datei namens Hallo.class gespeichert. Schauen Siebitte nach, ob diese Datei tatsächlich erzeugt wurde10.Die neu erzeugte Datei Hallo.class enthält die für einen Computer verständ-liche Version unserer Klasse. Wenn Sie diese Datei mit dem cat-Kommando aufden Bildschirm ausgeben, erhalten Sie eine ganz wilde Ausgabe — außerdem

10Wenn Sie nicht wissen, wie das geht, haben Sie vermutlich Anhang A noch nicht gelesen

18

Page 19: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

müssen Sie danach möglicherweise eine neue Kommandozeile öffnen, weil Ihrealte Kommandozeile nur noch komische Zeichen anzeigt. Wir Menschen könnenmit dem Inhalt der erzeugten Datei Hallo.class also nicht viel anfangen.Wir haben Ihnen bisher aber nur die halbe Wahrheit erzählt — es ist zwar tat-sächlich so, daß der Java–Compiler die Textdatei Hallo.java in eine Maschi-nnensprache–Datei Hallo.class umgewandelt hat. Es kann jedoch kein tat-sächlich existierender Computer die vom Java–Compiler benutzte Maschinen-sprache direkt verstehen. Der Java–Compiler übersetzt nämlich jedes Programmin eine künstliche Maschinensprache, den Java–Bytecode.Java–Bytecode ist eine Art Computer–Esperanto. Kein Computer versteht esdirekt, doch es ähnelt den meisten Computermaschinensprachen. Soll ein Com-puter das in einer Java–Bytecode–Datei enthaltene Programm abarbeiten, sobenötigt er einen weiteren Dolmetscher, der den Java–Bytecode für ihn über-setzt. Dieser zweite Dolmetscher nennt sich Bytecode-Interpreter11.Man tut im übrigen so, als wäre Bytecode tatsächlich eine Maschinenspracheund stellt sich gerne vor, daß irgendwo ein Computer existieren könnte, der denBytecode direkt versteht. Da dieser Computer aber nur durch den Bytecode-Dolmetscher existiert, nennt man den Bytecode-Dolmetscher auch Java Vir-tual Machine (JVM) (virtueller Java-Computer).Natürlich können Java-Programme damit nicht so schnell sein wie Programmeanderer Programmiersprachen, welche für den jeweilige Computer direkt ver-ständlichen Programmcode erzeugen. Der Prozessor Ihres Computes führt jakompilierte Java–Programme niemals direkt aus sondern benutzt immer seinenBytecode–Dolmetscher.Der Umweg über den Java–Bytecode ist aber auch ein sehr großer Vorteil undhat den Einsatz von Java im Internet erst ermöglicht — hierdurch werdenJava-Programme nämlich systemunabhängig. In der Theorie läuft jedes Java-Programm auf jeder Hardware und auf jedem Betriebssystem, für das eine vir-tuelle Java–Maschine existiert. Man muß sich also nicht mehr entscheiden, obman ein Programm für Windows, Macintosh, Unix oder sonst ein Betriebssy-stem kompiliert. Wenn die virtuelle Java-Maschine auf diesem Betriebssystemvorhanden ist, läuft hierauf jedes kompilierte Java–Programm.Das Programm, welches die virtuelle Maschine simuliert, heißt java. Um diekompilerte Datei Hallo.class auszuführen, geben Sie bitte auf der Komman-dozeile das Kommando

> java Hallo

ein. Daraufhin führt der Bytecode-Interpreter den in Hallo.class enthaltenenBytecode aus. Es sollte folgende Meldung am Bildschirm erscheinen:

Gratuliere, Ihr erstes Java--Programm funktioniert.

Ein Hinweis noch: Beachten Sie, daß die Endung „.class“ beim Aufruf desBytecode-Interpreters nicht mit angegeben werden darf. Hingegen muß beimAufruf des Compilers javac immer die Endung „.java“ mit angegeben werden.

11Das englische Wort „Interpreter“ heißt auf deutsch „Dolmetscher“

19

Page 20: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

3.3 Zusammenfassung

B Was ist das JDK ?B Warum benötigt man einen Compiler ?B Sie sollten den Java-Compiler aufrufen können.B Was erzeugt der Java-Compiler ?B Was ist ein Bytecode-Interpreter, und warum wird er benötigt ?B Wie unterscheiden sich Java-Compiler und Bytecode-Interpreter be-

züglich der Endung von Dateinamen ?B Überlegen Sie sich, wieso der Bytecode Java so gut für die Verwendung

im Internet geeignet macht — berücksichtigen Sie hierbei, daß fürMenschen verständlicher Programmtext meist als Geschäftsgeheimnisangesehen wird.

4 Erste Schritte — die TurtlegraphikDieses Kapitel soll Sie anhand von einfachen Programmen mit einigen zentralenBegriffen von Java vertraut machen, insbesondere dem Objekt– und Klassenbe-griff.

4.1 Testen der Turtlegraphik

Bei der Einführung dieser Begriffe werden wir uns auf eine von uns erstellteJava–Erweiterung beziehen, auf eine sogenannte Turtlegraphik. Die Idee derTurtlegraphik stammt übrigens aus der Programmiersprache Logo — da dieTurtlegraphik mit sehr einfachen Mitteln die Erstellung ansprechender Graphi-ken ermöglicht und die graphische Ausgabe die Arbeitsweise eines Programmsverdeutlicht, wird sie ein wichtiger Bestandteil dieser Veranstaltung sein.Der Turtlegraphik liegt die Vorstellung zugrunde, auf dem Bildschirm krabbeleein kleines Tierchen herum, z.B. eine Schildkröte (engl. Turtle). Diesem Tierchenkann man befehlen, eine gewisse Anzahl von Schritten vorwärts oder rückwärtsentlang seiner Blickrichtung zu gehen. Man kann ihm auch befehlen, sich nachrechts oder links zu drehen und so seine Blickrichtung zu ändern. Die Turtle trägtmit sich viele verschiedenfarbige Stifte herum, und man kann es dazu auffordern,einen Stift auszuwählen und ihn abzusetzen oder anzuheben. Wenn sich dieTurtle bei abgesetztem Stift bewegt, zeichnet sie eine Linie in der Stiftfarbe.In den CIP–Pools der TU ist die Turtlegraphik bereits installiert. Dennoch müs-sen Sie gewisse Vorbereitungen treffen, um die Turtle zu verwenden (siehe ersteHausaufgabe). Wenn Sie die Hausaufgaben und den Begleittext jedoch zuhausebearbeiten wollen, müssen Sie sie sich dort erst noch installieren. Eine Installa-tionsanleitung finden Sie im Anhang E.Testen Sie bitte zuerst, ob die Turtlegraphik bei Ihnen korrekt installiert ist,indem Sie auf der Kommandozeile

> java eip.TurtleDemo

eingeben. Falls das nicht funktioniert, schauen Sie bitte in den soeben genanntenAnhang.

20

Page 21: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Auf dem Bildschirm sollte sich ein zweigeteiltes Fenster öffnen. Im oberen Be-reich des Fensters sehen Sie eine Schrift sowie ein dreieckiges Symbol, und im un-teren, dunkleren Bereich sehen Sie Knöpfe, welche mit „Step“,„Run Slow“,„Stop“und „Quit“ betitelt sind.Drücken Sie nun einige Male auf den „Step“–Knopf. Sie werden feststellen, daßsich das dreieckige Symbol bei jedem Druck bewegt und dabei Striche malt, wel-che eine Art Baum ergeben. Das dreieckige Symbol werden wir im weiteren eine„Turtle“ nennen — Sie können sich das so vorstellen, daß auf dem Bildschirmeine kleine Schildkröte herumkrabbelt und dabei Striche zieht.Nach einigen Schritten wird das Drücken des Knopfes mühselig — drücken Siedann den „Run Slow“ Knopf. Die Turtle läuft nun selbstständig über den Bild-schirm, ohne auf weitere Knopfdrücke zu warten. Durch einen Druck auf den„Stop“–Knopf können Sie sie jederzeit anhalten.Probieren Sie das und drücken Sie dann den „Run“–Knopf. Nun läuft die Turtleso schnell, daß sie gar nicht mehr zu sehen ist. Auch hier können Sie jederzeitden „Stop“–Knopf drücken. Wenn Sie das Programm verlassen wollen, könnenSie jederzeit den „Quit“–Knopf verwenden.

4.2 Die Bestandteile eines einfachen Java–Programms

Bitte tippen Sie das folgende Beispiel ab und speichern es in einer Datei namensKreuz.java:

Kreuz.javaa

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/KapFirst/Kreuz.java

Anschließend kompilieren Sie es bitte durch

> javac Kreuz.java

und starten es dann mit dem Befehl

> java Kreuz

Sie sehen nun das Fenster, welches Sie bereits kennen, und wenn Sie die Turt-le wie in Abschnitt 4.1 beschrieben laufen lassen, sollte ein Kreuz gezeichnetwerden.Lassen Sie uns die einzelnen Bestandteile dieses Programms Zeile für Zeile unter-suchen — Sie werden sicher nicht alle Erläuterungen verstehen. Lesen Sie bittedie Ausführungen dennoch, um einen ersten Eindruck der Programmierung inJava zu erhalten.

In Zeile 1–3 steht ein durch die Zeichen „/*“ und „*/“ eingeschlossener Text.Dies ist ein Kommentar. Der Java–Compiler ignoriert jeden soumschlossenen Text, auch wenn er aus mehreren Zeilen besteht.Kommentare dienen dazu, Programme lesbarer zu machen — mankann in Kommentare Texte schreiben, welche beim Verständnisder nebenstehenden Programmbefehle helfen.

21

Page 22: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Zeile 4 ist leer. Leerzeilen dienen der besseren Lesbarkeit des Programmesfür Menschen. Für Java haben Leerzeilen gar keine Bedeutung.

In Zeile 5–6 wird Java angewiesen, die Programmbausteine eip.TurtleScreenund eip.Turtle zu importieren.Jedes Java–Programm setzt sich aus kleineren Bausteinen zusam-men, sogenannten Klassen. Einige Klassen sind in Java fest ein-gebaut und müssen Java nicht erst bekannt gemacht werden.Die Klassen TurtleScreen und Turtle sind von uns erstellt wor-den und sind Java normalerweise nicht bekannt. Will man sieverwenden, muß man Java daher zuerst mitteilen, wo sie auf derFestplatte zu finden sind.Dies geschieht durch Angabe eines Verzeichnispfades, gefolgt vomNamen des Programmbausteins. Wenn wir hier den Befehl

import eip.TurtleScreen

verwenden, so sagen wir Java damit: „Wir möchten gerne dieKlasse TurtleScreen verwenden, die im Pfad eip zu finden ist.“Java sucht darauf in gewissen Verzeichnissen12 nach einer DateiTurtleScreen.class und macht den enthaltenen Programmbau-stein für uns nutzbar.

In Zeile 8 sehen Sie den Text class Kreuz {.So teilen wir dem Java–Compiler mit, daß wir nun selbst einenProgrammbaustein, nämlich die Klasse Kreuz, definieren. Javaverlangt, daß der Name einer Programmdatei gleich dem Na-men der enthaltenen Klasse, ergänzt um das Anhängsel .javaist. Die Klasse Kreuz muss also zwingend in einer Datei namensKreuz.java enthalten sein.Eine Klasse (ein Programmbaustein) besteht aus vielen Java–Befehlen. Immer, wenn in Java mehrere Anweisungen zu größerenEinheiten gruppiert werden müssen, benutzt man dazu geschweif-te Klammern.Die geschweifte Klammer in Zeile 8 wird von der geschweiftenKlammer } in Zeile 22 geschlossen. So wird der Text der Zeilen9–21 zusammengefasst. Java interpretiert so allen Text innerhalbdieses Klammerpaares als Bestandteil der Klasse Kreuz.Geschweifte Klammerpaare samt Inhalt nennt man Block. Blöckeenthalten oft andere Blöcke. In unserem Beispiel enthält dieser dieKlasse definierende Block noch einen anderen Block, der sich überdie Zeilen 10–21 erstreckt.

In Zeile 10 sehen Sie den Beginn des Hauptprogramms der Kreuz–Klasse.Jede Klasse besteht aus vielen kleineren Programmstücken. Da-bei übernimmt jedes der kleineren Programmstücke eine spezielleAufgabe innerhalb der Klasse. Diese kleineren Programmstückeheissen in Java übrigens Methoden.

12In welchen Verzeichnissen gesucht wird, müssen Sie hier nicht wissen — falls es Sie inter-essiert, können Sie es im Anhang ?? nachlesen.

22

Page 23: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Will man etwa ein Programm schreiben, welches zwei Kreuzezeichnet, so würde man zuerst ein Programmstück (eine Metho-de) schreiben, welches ein Kreuz zeichnet und dann eine weitereMethode, welche die erste Methode zweimal verwendet. Die Auf-teilung eines Programms in viele kleine Stücke ist eine sehr guteSache, da sie Programme überschaubarer und leichter zu erweiternmacht.Es stellt sich die Frage, welche Methode ablaufen soll, wenn manein Programm von der Kommandozeile startet (etwa durch denBefehl „java Kreuz“). In Java ist das so gelöst, daß immer diesogenannte main–Methode gestartet wird, welche durch den Text

public static void main(String[] args)

gekennzeichnet ist.Eine Methode besteht aus einer Reihe von Anweisungen, welchedurch geschweifte Klammern zusammengefasst werden. Im vorlie-genden Beispiel erkennen Sie ein Klammerpaar, welches in Zeile10 beginnt und in Zeile 21 geschlossen wird. Die main–Methodebesteht daher aus allen Anweisungen in den Zeilen 11 bis 20.

Zeile 11 Zeile 11 ist die erste Zeile des Hauptprogramms der Kreuz–Klasse.Wenn Sie die Kreuz–Klasse von der Kommandozeile starten, be-ginnt hier die Ausführung des Programms.In Zeile 11 wird auf der rechten Seite des Gleichheitszeichens durchden Text new TurtleScreen() ein neuer TurtleScreen erzeugt.Ein TurtleScreen ist ein Fenster, in welchem die Turtle umher-läuft. Der Befehl new TurtleScreen() öffnet hier ein neues Fen-ster auf dem Bildschirm Ihres Computers.Vorher, in Zeile 5, hatten wir Java mitgeteilt, wo es den Pro-grammbaustein TurtleScreen finden kann. Hätten wir das nichtgetan, wüsste Java mit Zeile 11 nichts anzufangen.Damit wir mit Java über den neu angelegten TurtleScreen redenkönnen, müssen wir ihm einen Namen geben. Dies geschieht aufder linken Seite des Gleichheitszeichens, wo wir eine Variable na-mens ts erzeugen.Zeile 11 ist somit die programmtechnische Formulierung des Be-fehls „Öffne ein neues TurtleScreen–Fenster und benenne es mitts“.

Zeile 12 Zeile 12 ähnelt Zeile 11. Durch den Befehl new Turtle(ts) wirdeine neue Turtle angelegt, welche auf den in Zeile 11 angelegtenTurtleScreen gesetzt wird. Diese wird daraufhin als dreieckigesSymbol auf dem Bildschirmfenster angezeigt.Die neue Turtle erhält dabei den Namen t.

In Zeile 14–19 werden der in Zeile 12 erzeugten Turtle Botschaften geschickt.In Zeile 14 steht beispielsweise der Programmbefehl

t.pd();

23

Page 24: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

So schicken wir der Turtle namens t die Botschaft „pd()“ (pdsteht für „pendown“). Die Turtle senkt daraufhin ihren Stift.Jede Botschaft an die Turtle t bewirkt die Ausführung zur Bot-schaft passenden Programmcodes, welcher innerhalb der Turtle–Klasse definiert ist. Auf den Befehl pd() hin merkt sich die Turtle,daß sie ab sofort beim umherlaufen Linien ziehen soll.Ähnlich sind die Anweisungen „t.fd(100);“ bzw. „t.rt(120);“Botschaften an die Turtle t, 100 Einheiten nach vorne zu laufen,bzw. sich um 120 Grad nach rechts zu drehen („fd“ steht für„forward“ und „rt“ steht für „rightturn“).

Nachdem wir nun jede Zeile des Beispielprogramms besprochen haben, solltenSie selbständig kleine Änderungen vornehmen — was passiert, wenn Sie die Be-fehle t.fd(100) durch t.fd(200) ersetzen ? Was passiert, wenn Sie die Befehlet.rt(120) durch t.rt(90) ersetzen ? Können Sie die Turtle dazu bringen, einRechteck zu zeichnen ? (natürlich müssen Sie nach jeder Änderung der Datei dieÄnderungen speichern, den Compiler aufrufen und dann das Programm erneutstarten).Ein Hinweis noch: Ihnen sollte aufgefallen sein, daß die meisten Zeilen des Bei-spielprogrammes mit einem Semikolon enden. In Java müssen die meisten Be-fehle durch Semikoli abgeschlossen werden. Beachten Sie dies beim Ändern desBeispielprogramms.

4.3 Turtlebefehle

Hier stellen wir Ihnen alle Befehle vor, welche die Turtle versteht und zeigenIhnen in einigen Beispielprogrammen, wie diese Befehle zu verwenden sind. Beider Vorstellung der Befehle gehen wir davon aus, daß t eine Turtle bezeichnet.

pu( ) „pen up“ — die Turtle hebt ihren Stift. Beim Bewegen zeichnetdie Turtle nicht.

pd( ) „pen down“ — die Turtle senkt ihren Stift. Beim Bewegen zeich-net die Turtle.

fd( n ) „forward“ — die Turtle bewegt sich n Schritte vorwärts. Dabeiist n eine reelle Zahl.Beispielsweise bewegt sich die Turtle t durch den Befehl

t.fd( 3.5 );

dreieinhalb Schritte vorwärts.bk( n ) „backward“ Die Turtle bewegt sich n Schritte rückwärts. Dabei

ist n eine reelle Zahl.rt( n ) „right turn“ — die Turtle dreht sich um n Grad nach rechts.

Dabei ist n eine reelle Zahl.lt( n ) „left turn“ — die Turtle dreht sich um n Grad nach links. Dabei

ist n eine reelle Zahl.home() Bewegt die Turtle in die Mitte des Zeichenfeldes. Wenn ihr Stift

dabei unten ist, wird eine Linie gezeichnet.x

24

Page 25: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

hide() Macht die Turtle unsichtbar — sie zeichnet dann zwar noch,verdeckt aber nicht mehr Teile der Zeichnung.

show() Macht eine zuvor durch hide() versteckte Turtle wieder sicht-bar.

setpc( color ) Setzt die Farbe, in welcher die Turtle zeichnet. Um diesenBefehl, in einem eigenen Programm zu verwenden, muß zumBeginn des Programms der Befehl

import java.awt.Color;

stehen. Gültige Farben sind:Color.black, Color.blue, Color.cyan, Color.darkGray, Color.gray,Color.green, Color.lightGray, Color.magenta, Color.orange,Color.pink, Color.red, Color.white, Color.yellowSie können auch eigene Farben kreieren: Jede Farbe hat einenRot–, einen Grün– und einen Blauanteil zwischen 0 und 255.Sie können eigene Farben erzeugen, indem Sie die Farbe

new Color( Rotanteil, Gruenanteil, Blauanteil )

Z.B.:

t.setpc( Color.blue ); // Turtle zeichnet in Blaut.setpc( Color.black ); // Turtle zeichnet in Schwarzt.setpc( new Color(255,0,0) ); // zeichnet in Rott.setpc( new Color(100,100,255) ); // zeichnet in Blaugrau

Weiter unten finden Sie ein Beispiel, das die Verwendung vonFarben demonstriert.

clearScreen( color ) Die Zeichenfläche der Turtle wird in der angegebenenFarbe gelöscht. Um diesen Befehl, in einem eigenen Programmzu verwenden, muß zum Beginn des Programms der Befehl

import java.awt.Color;

Wie man Farben verwendet, ist beim Befehl setpc und im untenstehenden Beispiel beschrieben.

Befehle zur Fehlersuche:

debug=true Um Ihnen bei der Fehlersuche in Ihren Programmen zu hel-fen, hat die Turtle einen Debug-Modus (Fehlersuchmodus).Der Debug-Modus wird in einer Turtle t durch den Befehl

t.debug=true;

angestellt. Sobald der Debug-Modus angestellt ist, gibt dieTurtle bei jedem Befehl aus, was sie gerade tut.

debug=false Der Debug-Modus kann durch den Befehl

25

Page 26: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

t.debug=false;

wieder ausgestellt werden.setName( name ) Wenn Sie mit mehreren Turtles arbeiten, macht es Sinn,

jeder einen eigenen Namen zu geben. Dadurch können Sieim Debug–Modus erkennen, welche der Turtles die Debug–Meldung ausgegeben hat.Der Befehl

t.setName("Tina Turtle");

bewirkt, daß die Turtle t jeder Debug–Ausgabe den Namen„Tina Turlte“ voranstellt.

report() Gibt die Position und Blickrichtung der Turtle aus.

Das folgende Beispielprogramm verwendet all die oben genannten Befehle:

Demo1.javaa

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/KapFirst/Demo1.java

26

Page 27: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Verbotene Befehle:

Die folgenden Befehle dürfen Sie in den ersten Hausaufgaben nicht benutzen.Sie durchbrechen den Turtle–Gedanken, der vorsieht, daß die Turtle nur lokal,d.h. in ihrem eigenen Koordinatensytem, arbeitet.

setPosition( x, y) Setzt die Position der Turtle auf dem Zeichenfeld. x undy sind dabei reelle Zahlen. Wenn der Stift unten ist, wird beider Bewegung eine Linie gezeichnet.Beispielsweise bewegt sich die Turtle t durch den Befehl

t.setPosition( 10, 10 );

auf die Position mit den Koordinaten (10,10).double getX() Liefert die horizontale Koordinate der Turtle auf dem Zei-

chenfeld. Das Ergebnis ist eine reelle Zahl:Zum Beispiel speichert

double x = t.getX();

die horizontale Koordinate der Turtle t in der Variablen x.double getY() Liefert die horizontale Koordinate der Turtle auf dem Zei-

chenfeld zurück.setHeading( d ) Setzt die Richtung, in welche die Turtle schaut. Dabei schaut

die Turtle genau nach oben, wenn d == 0 ist. d ist eine reelleZahl.Zum Beispiel läßt der Befehl

t.setHeading(90);

die Turtle genau nach rechts schauen.double getHeading() Ermittelt die Blickrichtung der Turtle.

Zum Beispiel speichert der Befehl

double d = t.getHeading();

die Blickrichtung der Turtle t in der Variable d.boolean isShown() gibt zurück, ob die Turtle momentan angezeigt wird.boolean penIsDown() gibt zurück, ob der Stift der Turtle abgesetzt ist oder

nicht.

Das folgende Programm verwendet einige dieser verbotenen Befehle, um einRechteck zu zeichnen:

Tabu.javaa

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/KapFirst/Tabu.java

27

Page 28: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

5 Grundlagen der Java-SyntaxEs sollen nun einige Grundregeln besprechen, die in jeder Java-Programmdateiberücksichtigt werden müssen.

5.1 Grundsätzliches zur Syntax von Java–Programmen

Zunächst sollten Sie wissen, daß der Compiler sich nicht um die ZeilenstrukturIhres Programms kümmert — für ihn gibt es zwischen Leerzeichen und Zeile-numbrüchen keinen besonderen Unterschied.Wir hätten das Beispiel Kreuz.java aus dem letzten Kapitel auch so schreibenkönnen:

/** Benutzt die Turtle, um ein Kreuz zu zeichnen.*/import

eip.TurtleScreen;import eip.Turtle;class Kreuz {public static void main( String[]args ) {TurtleScreen ts = newTurtleScreen(); Turtle t = new Turtle( ts );

t.pd(); t.fd(200 ); t.bk( 100 ); t.rt( 90);t.fd( 100 );t.bk( 200 );}}

Dem Compiler ist es egal, wie das Programm formatiert ist. Für uns Menschenist aber dieses Programm sehr viel schlechter zu lesen als das ursprüngliche.Da er nicht die Zeilenstruktur des Programmes verwendet, muß der Compilerirgendwie anders erkennen, wann ein Befehl im Programm endet und der nächsteBefehl beginnt. Darum muß in Java jede Anweisung mit einem Semikolon enden.Das gilt aber nicht für die Definition einer Klasse oder Methode.Wenn der Compiler eine Datei bearbeitet, sieht er zunächst nur einen Stromvon Zeichen. Diese Zeichen faßt er zu größeren Einheiten zusammen. Um etwasfür den Compiler verständliches zu programmieren, müssen Sie wissen, was fürEinheiten der Compiler versteht.Java identifiziert in seinem Eingabestrom die folgenden Einheiten:

Schlüsselwörter — Ein Schlüsselwort ist ein Wort, welches innerhalb der Pro-grammiersprache eine genau festgelegte Bedeutung hat. In Java sind fol-gende Wörter als Schlüsselwörter reserviert (das brauchen Sie sich nichtzu merken):

abstract boolean break byte casecatch char class const continuedefault do double else extendsfalse final finally float forgoto if implements import instanceofint interface long native newpackage private protected public returnshort static super switch synchronizedthis true throw throws transienttry void volatile while

28

Page 29: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Jedes dieser Wörter hat für Java eine ganz spezielle Bedeutung. Wannim-mer eines im Programmtext auftaucht, muß es in genau der vorgesehenenArt und Weise benutzt werden.Neben den Schlüsselwörtern kennt Java noch einige Symbole, die beispiels-weise beim Rechnen mit Zahlen benutzt werden:

= > < ! ~ ? :== <= >= != && || ++-- + - * / & |^ % << >> >>> += -=*= /= &= |= ^= %= <<=>>= >>>=

Bezeichner — Bezeichner werden verwendet, um Objekten, Klassen, Attribu-ten, Methoden und anderen Dingen im Java-Programm Namen zu geben.Namen sind sehr wichtig; beispielsweise können Sie ein Objekt nur ver-wenden, wenn Sie das Objekt unter einem gewissen Namen kennen.

Beispiel: In der Beispielklasse Kreuz.java auf Seite ?? wurden dieSchlüsselwörter import, class, public, static, void, public und newverwendet.Es wurden die Bezeichner eip.TurtleScreen, eip.Turtle, Kreuz, main,args, String, TurtleScreen, ts, Turtle, t, pd, fd, bk und rt benutzt.

Bei der Wahl von Bezeichnern dürfen Sie Ihrer Phantasie fast freien Lauflassen. Allerdings sollten Sie dafür sorgen, daß die von Ihnen gewähltenBezeichner aussagekräftig sind und das bezeichnete Objekt gut charakte-risieren. Java ist es egal, ob Sie wir die Turtle mit t oder mit ruebe. Einenmenschlichen Leser würden Sie dadurch aber verwirren.Ein Bezeichner darf beliebig lang werden, und bei der Wahl eines Bezeich-ners werden Sie lediglich durch folgende Bedingungen eingeschränkt:

• Ein Bezeichner darf groß- und kleingeschriebene Buchstaben13, dieZiffern 0-9 und die Sonderzeichen _ und $ enthalten. Dabei solltenSie von der Verwendung des Zeichens $ aber absehen — es ist fürvom Compiler automatisch generierte Bezeichner vorgesehen.

• Ein Bezeichner darf nicht mit einer Ziffer anfangen.• Schlüsselwort dürfen Sie nicht als Bezeichner verwenden.

Wichtig zu bemerken ist noch, daß Java großgeschriebene und kleinge-schriebene Buchstaben streng unterscheidet — für Java sind einBezeichnerund EinBezeichner zwei völlig verschiedene Dinge.Wenn Sie Bezeichner wählen, sollten Sie diese Eigenschaft von Java abernicht mißbrauchen — ein menschlicher Leser Ihres Programm könnte mög-licherweise durcheinanderkommen. Wenn Sie für verschiedene Dinge Be-zeichner verwenden, die sich nur durch die Groß- Kleinschreibung unter-scheiden, wird es einem Menschen sicher schwerfallen, sich zu merken,wofür welcher Bezeichner steht. Vermeiden Sie daher die Verwendung vonBezeichnern, die sich nur durch die Groß- Kleinschreibung unterscheiden.

13Es ist sogar möglich, chinesische oder russische Buchstaben zu verwenden — wie das geht,werden wir Ihnen aber nicht erzählen.

29

Page 30: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Beispiel: Hier eine Liste gültiger Bezeichner:i3 String MAX_VALUE Lupo1234_392i mEiNeKlAsSe meineKlasse mein_segel_boot

Nun folgt eine Liste ungültiger Bezeichner:

1haus Ungültig: beginnt mit Ziffer.class Ungültig: class ist ein Schlüsselwort.ab-c Ungültig, weil ein Minus nicht in einem Bezeichner

enthalten sein darf. Java würde denken, daß Sie hierdas durch c bezeichnete Objekt vom mit ab bezeich-neten Objekt substrahieren wollen.

#bdd Ungültig: enthält ein nicht erlaubtes Sonderzeichen.ein Objekt Ungültig: enthält ein Leerzeichen.

Und schließlich eine Liste von Bezeichnern, die zwar erlaubt sind, dieSie aber dennoch nicht verwenden sollten.Meine$Klasse Das Symbol $ sollten Sie nicht verwenden. Die Java-

Umgebung benutzt es nämlich auf eine ganz spezielleWeise.

Class Java unterscheidet zwischen Groß- und Kleinschrei-bung und wird diesen Bezeichner daher nicht mitdem Schlüsselwort class in Verbindung bringen. Einmenschlicher Leser könnte dadurch aber verwirrt wer-den.

Zahlenkonstanten — Natürlich dürfen in einem Java-Programm auch Zahlenvorkommen. Java kennt ganze oder reelle Zahlen. Wie Zahlen in einemProgramm genau aussehen dürfen, beschreiben wir erst später. Vorerst seigesagt, daß man beim Angeben von Zahlen eigentlich nicht allzuviel falschmachen kann.

Beispiel: Beispiele für ganze Zahlen sind:

10, -30, +1043, 1334, 0123, 0xFF

Bei den letzten Zahlen des Beispiels ist eine Bemerkung angebracht— wenn eine mehrstellige Zahl mit einer Null anfängt, faßt Java Sieals Zahl in oktaler Darstellung auf. Wenn eine Zahl mit den Zeichen0x beginnt, faßt Java sie als hexadezimale Zahl auf. Die oktale Zahl0123 entspricht der dezimalen Zahl 83, und die hexadezimale Zahl0xFF entspricht der dezimalen Zahl 255. Später gehen wir daraufnochmal ein.Beispiele für reelle Zahlen sind:

3.141, 493., .5, -503, 120e-9, 140.5E120

Sie sehen, daß in Java als Dezimalpunkt tatsächlich ein Punkt undnicht ein Komma verwendet wird. Das e bzw. das E in den letztenbeiden Zahlen steht für “Exponent”. Die Zahl 120e − 9 entspricht derZahl 120 · 10−9, und genauso steht die Zahl 140.5E120 für die Zahl120 · 10120. Ob Sie bei dieser Schreibweise lieber ein kleines e oderein großes E verwenden, ist Ihnen überlassen — beide Schreibweisensind erlaubt und haben die gleiche Wirkung.

30

Page 31: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Zeichenketten — Eine Zeichenkette ist ein in doppelten Anführungszeichenstehender Text. In der Zeichenkette ist jedes Zeichen erlaubt. Es gibt al-lerdings einige Zeichen, bei denen man sich etwas anstrengen muß, um Siein eine Zeichenkette aufzunehmen. Darauf wird später noch eingegangen.

Beispiel: Hier ein paar Beispiele für gültige Zeichenketten:

"Dies ist eine Zeichenkette""Sonderzeichen {}!#/-""class""510"

Die mittlere Zeichenkette enthält den Text class. Da der Text in einerZeichenkette steht, hat er für Java nichts mit dem Schlüsselwort classder Sprache Java zu tun.Die letzte Zeichenkette enthält den Text 510. Auch hier gilt: Auf-grund der Anführungszeichen interpretiert Java dies nicht als die Zahl510 sondern als Text.Schließlich noch ein Beispiel für eine ungültige Zeichenkette:

"Sein Name war "Hans". "

Das erste Anführungszeichen beendet die Zeichenkette. Java liest diesals Zeichenkette mit Inhalt “Sein Name war“ gefolgt vom BezeichnerHans gefolgt von der Zeichenkette “. ”. Auf diese Art kann man kei-ne Zeichenkette erzeugen, die ein Anführungszeichen enthält. Spätererfahren Sie, wie das geht.

Kommentare — schließlich können Sie in ein Java-Programm Kommentareaufnehmen. Kommentare dienen dazu, den Programmtext zu kommentie-ren. Dazu gehört insbesondere die Dokumentation der Klassen, ihrer At-tribute und ihrer Methoden. Alles, was in einem Kommentar steht, wirdvom Java-Compiler völlig ignoriert. Sie können in einen Kommentar alsobeliebige Texte schreiben.Java unterscheidet mehrere Arten von Kommentaren. Ein einzeiliger Kom-mentar wird durch das Zeichen // eingeleitet. Wenn diese Zeichen in einerZeile (außerhalb einer Zeichenkette) stehen, ignoriert Java den gesamtenRest der Zeile. Unser kleines Beispielprogramm von vorhin könnten wirmit einzeiligen Kommentaren wie folgt dokumentieren:

class HalloWelt { // gebe den Text "Hallo, Welt" aus.

// diese Methode wird beim ausführen der Klasse ausgeführt:public static void main( String[] args ){

System.out.println("Hallo, Welt //");}

}

Zu Demonstrationszwecken haben wir auch in die Zeichenkette "Hallo, Welt"das Zeichen // eingefügt. An der Stelle bewirkt es keinen Kommentar, daes sich innerhalb einer Zeichenkette befindet.

31

Page 32: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Ein mehrzeiliger Kommentar wird durch /* begonnen und endet mit */.Alles zwischen /* und */ wird vom Compiler ignoriert. Unser Beispielkönnten wir auch so dokumentieren:

/** Die Klasse HalloWelt gibt auf dem Bildschirm den Text* "Hallo, Welt" aus.*/

class HalloWelt {

/************************************************************ diese Methode wird beim ausführen der Klasse ausgeführt:*/

public static void main( String[] args ){

System.out.println("Hallo, Welt //");}

}

Schließlich noch ein Beispiel für einen ungültigen Kommentar:

/* Ein Kommentar /* in einem Kommentar */ ist nicht erlaubt */

Es ist nicht möglich, einen durch /*...*/ begrenzten Kommentar zuschreiben, in welchem ein weiterer solcher Kommentar enthalten ist. DerCompiler würde hier beim ersten */ denken, der Kommentar sei beendet.Es ist jedoch möglich, das //-Zeichen innerhalb eines solchen Kommentarszu verwenden:

/* Ein einzeiliger Kommentar // in einem Kommentar ist erlaubt. */

Sie sollten Kommentare verwenden, um Ihr Programm verständlicher zumachen. Zur Verständlichkeit eines Programms gehört aber nicht nur dieFormulierung hilfreicher Kommentare sondern auch die Verwendung aus-sagekräftiger Bezeichner und das Einhalten einer gut lesbaren Programm-struktur. Wenn Sie aussagekräftige Bezeichner verwenden, können Sie sichso manchen Kommentar sparen.

5.2 Zusammenfassung

Nachdem Sie dies Kapitel gelesen haben, sollten Sie folgende Fragen beantwortenkönnen:

B Welchen Zweck hat die Zeilenstruktur eines Programms ?B Wozu dient ein Semikolon in Java ?B Geben Sie Beispiele für Bezeichner, die zwar erlaubt sind, aber den-

noch nicht benutzt werden sollten !B Was ist eine Zeichenkette ?

32

Page 33: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

6 Variablen und DatentypenDie Programme, die wir bisher gesehen haben, sind ziemlich langweilig — sie ar-beiten eine vorgegebene Folge von Befehlen ab und sind überhaupt nicht flexibel.Für flexible Programme, die bei jedem Aufruf etwas anderes tun, benötigt man„Variablen“, etwas das bei jedem Programmablauf einen anderen Wert habenkann.

6.1 Variablen und ihr Typ

Wir verwenden Variablen, wenn wir Objekten einen Namen geben wollen, oderwenn wir uns etwas merken möchten. Variablen sind Platzhalter für Zahlen,Zeichenketten, Turtles oder sonstirgendwelche Dinge. Auf der Hardwareebeneentspricht jeder Variable ein gewisser Platz im Hauptspeicher des Computers.Jede Variable hat einen Namen, und dieser Name muß den Vorschriften fürBezeichner genügen.

Beispiel: Angenommen, wir wollen in einem Programm einen Brutto-preis berechnen. Wenn wird dies für einen Preis von 10, − DM tun wollen,könnten wir den Bruttopreis als

15% · 10, − + 10, −

berechnen.Der Nachteil der obigen Formel ist, daß sie nur für einen Nettopreis von10,- DM korrekt ist. Wenn wir in unserem Programm auch mit anderenPreisen als 10,- DM rechnen wollen, würden wir daher lieber einen Platz-halter — eine Variable — für den Nettopreis verwenden. Möglicherweisewürden wir schreiben:

bruttopreis = 0.15 * nettopreis + nettopreis

Diese Formel wäre für jeden Preis anwendbar. Dazu müsste der Platzhalternettopreis den jeweils zu verwendenden Nettopreis enthalten. Das Ergeb-nis würden wir dann in einem anderen Platzhalter namens bruttopreisspeichern.

Wir können Variablen überall dort einsetzen, wo wir Werte hinschreiben wür-den. Natürlich müssen wir dabei ein bißchen aufpassen — es wäre sicher nichtsinnvoll, einen Platzhalter, der eine reelle Zahl enthält, an einer Stelle zu ver-wenden, an der nur Zeichenketten hinpassen.Damit man nicht ausversehen eine Variable an einer Stelle verwendet, wo siekeinen Sinn macht, hat in Java jede Variable einen Typ.

Beispiel: Beispielsweise gibt es in Java den Datentyp int. Variablendieses Typs können ganze Zahlen speichern.Variablen des Datentyps double Typs können reelle Zahlen speichern.Wenn Sie eine Variable des Typs double an einer Stelle verwenden, woman nur ganze Zahlen verwenden darf, zeigt der Compiler bei der Über-setzung ihres Programms einen Fehler an.

33

Page 34: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Bevor eine Variable in Java das erste Mal verwendet wird, muß man Java daherInformationen darüber zukommen lassen, welchen Typ diese Variable haben soll.In Java geschieht dies, indem man eine Anweisung des AufbausTYP variablenname;verwendet. Sobald Java eine solche Anweisung gefunden wird, merkt sich Java:Aha, hier ist jetzt eine Variable namens variablenname definiert worden, unddiese Variable darf nur Werte des Typs TYP aufnehmen.

Beispiel:

DemoVars.javaa

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/KapVariablen/DemoVars.java

In Zeile 6 wird eine Variable namens zaehler als int definiert. Von dieserZeile an weiß Java, daß der Bezeichner zaehler für eine Variable stehtund nur ganze Zahlen speichern kann.In Zeile 7 wird der Variable zaehler der Wert 10 zugewiesen. Vorher hattezaehler keinen definierten Wert.In Zeile 8 wird eine weitere Variable namens inversZaehler definiert, diereelle Zahlen speichern kann. Außerdem wird dieser Variable gleich derinverse Wert von zaehler zugewiesen.In Zeile 9 und 10 werden beide Variablen ausgegeben.

6.1.1 Ganze Zahlen

Java kennt mehrere ganzzahlige und mehrere reellwertige Datentypen. Der Grundhierfür ist folgender: Jede Variable belegt einen gewisse Anzahl von Bytes imSpeicher des Computers. Aus Kapitel 2 wissen Sie, daß man mit n Bytes nur28·n verschiedene Werte darstellen kann.Um den Typ einer Variable festzulegen, muß man sich darum vorher Gedankenmachen, wieviele verschiedene Werte sie annehmen können soll und davon aus-gehend, wieviele Bytes man im Computerspeicher dafür verwenden möchte. Daman normalerweise nicht mehr Speicherplatz als nötig verschwenden will, bie-tet Java ganzzahlige und reellwerige Datentypen verschiedener Längen an (dieLänge des Datentyps gibt an, wieviele Bytes seine Variablen belegen).Java kennt die ganzzahligen Datentypen byte, short, int und long. Am häufig-sten verwendet man den Datentyp int.

Typ Länge Wertebereichbyte 1 −27, . . . , 27 − 1short 2 −215, . . . , 215 − 1int 4 −231, . . . , 231 − 1long 8 −263, . . . , 263 − 1

Das folgende Programm demonstriert die Verwendung von ganzen Zahlen:

34

Page 35: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

GanzZahl.javaa

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/KapVariablen/GanzZahl.java

Was passiert, wenn eine Variable einen zu großen oder kleinen Wert enthält ?Um das zu demonstrieren, haben wir ein Programm geschrieben, das eine Zahlvom Benutzer einliest und anschließend ausgibt:

GanzZahlInput.javaa

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/KapVariablen/GanzZahlInput.java

Wenn Sie das Programm kompilieren und starten, werden Sie aufgefordert, eineZahl einzugeben. Die eingegebene Zahl wird dann der int–Variable i zugewie-sen.Probieren Sie es bitte selbst aus ! Wenn Sie die Zahl 231 − 1 eingeben (dasist die Zahl 2147483647), gibt das Programm sie korrekt wieder aus. Wenn Siejedoch größere Zahlen eingeben, kommt es zu komischen Resultaten: statt dervon Ihnen eingegebenen Zahl werden negative Zahlen ausgegeben. Zum Beispielmacht das Programm bei mir aus der Zahl 123456789012 die Zahl −1097262572.Diesen Effekt nennt man Overflow — eine Zahl läuft über, wenn man ihreinen zu großen oder einen zu kleinen Wert zuweist. Der Wert, den die Zahldann enthält, ist nicht brauchbar.Sie müssen also immer darauf achten, daß der ausgewählte Datentyp zu denDaten passt, die Sie verarbeiten wollen.

6.1.2 Fließkommazahlen

Java kennt die beiden reellwertige Datentypen float und double. float–Zahlenbelegen 4 Byte und double–Zahlen belegen 8 Byte im Speicher.Sie sollten vorerst immer double–Variablen verwenden, da hier nicht nur derWertebereich sondern auch die Anzahl der geführten Nachkommastellen größerist als für float–Variablen.Das folgende Programm demonstriert die Verwendung von reellen Zahlen:

ReellZahl.javaa

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/KapVariablen/ReellZahl.java

6.1.3 Logischer Datentyp

Der Datentyp boolean repräsentiert logische Werte. Ein logischer Wert ist ent-weder wahr (true) oder unwahr (false).boolean–Variablen können benutzt werden, um die Resultate von Vergleichen zu

35

Page 36: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

speichern. Sie können auch benutzt werden, wenn eine Variable nur zwei Werteannehmen können soll.Das folgende Beispiel demonstriert die Verwendung von boolean:

DemoBoolean.javaa

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/KapVariablen/DemoBoolean.java

6.1.4 Zeichen und Zeichenketten

Einzelne Zeichen sind in Java vom Typ char. Zeichenketten sind vom Typ String.Um ein Zeichen in einem Java–Programm anzugeben, muß man es in einfa-che Anführungszeichen schreiben. Eine Zeichenkette schreibt man in doppelteAnführungszeichen.Wenn man zwei Zeichenketten mit + verknüpft, so entsteht eine Zeichenkette,die den hintereinander gehängten Text beider Zeichenketten enthält.

Beispiel:

DemoString.javaa

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/KapVariablen/DemoString.java

Auf Zeile 4 wird eine char–Variable namens b definiert, welcher das Zei-chen „z“ zugewiesen wird. Der Inhalt der Variable hat mit dem Namender Variable nichts zu tun.In Zeile 8 wird die Variable name als String definiert. Ihr Inhalt entstehtdurch Hintereinanderhängen anderer Variablen.In Zeile 9 wird die Variable sequenz als String definiert. Wir bilden denInhalt, indem wir hinter den leeren String "" mit Hilfe des +–Operatorsdie drei Zeichenvariablen anfügen. Der Leerstring wird hier dazu benutzt,damit + überhaupt als das Hintereinanderhängen von Zeichenketten in-terpretiert wird.

7 AusdrückeIn diesem Kapitel geben wir Ihnen ergänzende Informationen zu Goto Java 2,Kapitel 5, die Sie ergänzend zu Hausaufgabe 3 lesen sollten.

7.1 Was ist ein Ausdruck ?

Was ein Ausdruck ist, erklären wir Ihnen am einfachsten an einem Beispiel.Schauen Sie sich das folgende Beispielprogramm an:

01 public class JavaDemo {

36

Page 37: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

02 public static void main( String[] args ) {03 int i = 5;04 float f = 5.0f;05 System.out.println( 5 );06 System.out.println("5");07 System.out.println( i );08 System.out.println( f );9 System.out.println( 5 * (i - 3 * f + 1.3 ) );10 }11 }

Das Programm gibt einige Werte auf den Bildschirm aus, wobei wir wieder diebereits bekannte Methode System.out.println verwenden. Auf den ersten Blickscheint dies ein ganz triviales Programm zu sein.Aber beachten Sie, auf wie viele unterschiedliche Arten wir die Ausgaberoutineverwenden: In Zeile 5 geben wir eine Zahl aus. In Zeile 6 geben wir einen Stringaus. In Zeile 7 wird der Inhalt einer int–Variable ausgegeben, während in Zeile 8der Inhalt einer float–Variable ausgegeben wird. Schließlich wird in Zeile 9 nochvor der Ausgabe eine Rechnung durchgeführt und erst dann der berechnete Wertausgegeben.All diese unterschiedlichen Daten müssen von Java auch unterschiedlich behan-delt werden — mit Strings muß ein Computer ganz anders umgehen als mitZahlen, und mit ganzen Zahlen vom Typ int muß der Computer ganz andersumgehen als mit reellen Zahlen vom Typ float. Auch muß die Rechnung in Zeile09 erst vom Computer durchgeführt werden, bevor das Ergebnis ausgegebenwerden kann.Ähnlich wie bei im obigen Beispiel bei der Verwendung von System.out.printlnkann in einem Java–Programm an jeder Stelle, wo irgendein Wert stehen kann,auch eine Rechnung oder eine Variable oder sonstetwas stehen, das man aus-werten kann. Dabei darf die Auswertung nur Werte der jeweils erlaubten Da-tentypen ergeben. AusdruckDefinition: Ausdruck

Ein Ausdruck ist etwas, das man auswerten kann. Die Auswertungeines Ausdruckes ergibt einen Wert. Der Datentyp dieses Wertesergibt sich aus dem Aufbau des Ausdrucks. An jeder Stelle, an der einWert eines gewissen Datentyps stehen darf, darf auch ein Ausdruckdieses Datentyps stehen.

Die System.out.println–Methode darf man auf all die durch uns demonstriertenArten verwenden, da sie sowohl Ausdrücke vom Typ int als auch Ausdrücke vomTyp float als auch Ausdrücke vom Datentyp String verarbeiten kann. Sie kannauch Ausdrücke aller anderen Datentypen verarbeiten und ist damit ziemlicheinzigartig.

Beispiel: Hier ein paar Beispiele für Ausdrücke. Es seien folgende Varia-blen definiert:

int i = 5;float f = 5;String a = "Hallo";

37

Page 38: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

2 Die Zahl 2 ist ein Zahlenliteral. Jedes Literal ist ein Ausdruck,dessen Datentyp gleich dem Datentyp des Literals ist. Das ganz-zahlige Literal 2 ist somit ein Ausdruck mit Wert 2 und Datentypint

“5” Das String–Literal "5" ist ein Ausdruck mit Wert "5" und Da-tentyp String

i Auch jede Variable ist ein Ausdruck, deren Wert sich aus demInhalt der Variable ergibt. Mit den obigen Definitionen ist diesein Ausdruck vom Typ int mit Wert 5.

f Die Variable f ist hier ein Ausdruck vom Typ float mit Wert 5.0.i + 2 In Ausdrücken können Rechnungen vorkommen . Der Wert einer

Rechnung ergibt sich natürlich als Resultat der Rechnung. Da-bei sind die Operanden einer Rechnung selbst wieder Ausdrücke.Der Wert der Rechnung i+2 ergibt sich durch Auswerten desAusdrucks links vom +–Zeichen (int mit Wert 5), durch Auswer-ten des Teils rechts vom +–Zeichen (int mit Wert 2) und durchAddition der so ermittelten Werte.Der Datentyp einer Rechnung ergibt sich aus den an der Rech-nung beteiligten Datentypen (dazu sagen wir im Kapitel überTypwandlungen mehr). Dieser Ausdruck würde zum Wert 7 aus-gewertet und hätte den Typ int, da in der Rechnung nur Aus-drücke vom Typ int vorkommen.

a + “ Welt” Auch dies ist ein Ausdruck. Der String a und der String" Welt" werden zusammengehängt. Ergebnis ist ein Ausdruckvom Typ String mit Inhalt "Hallo Welt".

i=5 Auch die Zuweisung eines Wertes an eine Variable ist ein Aus-druck. Zwar ist der eigentliche Zweck der Zuweisung, der Variableauf der linken Seite des =–Zeichen Variable den Wert des Aus-drucks auf der rechten Seite zuzuweisen. Darüberhinaus ist dieZuweisung in Java aber auch ein Ausdruck, dessen Auswertungden Wert auf der rechten Seite des =–Zeichens ergibt (dazu gleichmehr).Beispielsweise gibt das folgende Java–Programm den Wert 5 aufden Bildschirm aus und weist der Variable i den Wert 5 zu:

public class DemoAssign {public static void main( String[] args ) {

int i = 0;System.out.println( i = 5 );System.out.println( i );

}}

7.2 Literal–Ausdrücke

Die wohl einfachsten Ausdrücke sind Literale. Ein Literal ist eine konkrete Zahloder ein konkreter String, der in einem Programmtext auftaucht. Jedes Literalhat einen eindeutig bestimmten Datentyp.Die nächsten Seiten sollen Ihnen eine gewisse Vorstellung davon vermitteln,wie Literale geschrieben werden und welchen Datentyp Java welchen Literalenzuweist.

38

Page 39: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

7.2.1 Ganzzahlige Literale

Es gibt drei Typen von ganzzahligen Literalen: dezimale, oktale und hexadezi-male. Sie werden zwar in dieser Veranstaltung weder oktale noch hexadezimaleLiterale verwenden, es ist aber wichtig, daß Sie wissen, wie man diese Literaleschreibt. Es ist nämlich sehr leicht möglich, eine Zahl ausversehen als oktalesLiteral zu schreiben. Für diese Zahl könnte sich dann ein unerwarteter Wertergeben. Dezimales

LiteralEin dezimales Literal ist eine Zahl in üblicher dezimaler Darstellung. Ein dezi-males Literal darf mit einem Vorzeichen (+ oder −) beginnen und die Ziffern 0bis 9 enthalten. Der Wert eines dezimalen Literals ist der Wert der angegebenenZahl.

Beispiel: Die folgenden Werte sind dezimale Literale: 1, 2, 3, +4, -5,+100, -984235, +239048

oktales Lite-ralEine ganze Zahl wird in einem Java–Programmtext immer dann als oktales

Literal interpretiert, wenn nach dem optionalen Vorzeichen eine führende Nullsteht. Nach der führenden Null darf ein oktales Literal nur die Ziffern 0 bis 7enthalten. Der Wert eines oktalen Literals ergibt sich, indem die oktale Zahlumgerechnet wird.

Beispiel: Im oktalen Zahlensystem gibt es nicht wie im dezimalen Zah-lensystem 10 sondern nur 8 Ziffern. Wenn man im oktalen Zahlensystemvon 0 bis 16 zählt, sieht das so aus: 00, 01, 02, 03, 04, 05, 06, 07, 010, 011,012, 013, 014, 015, 016, 017, 020Die oktale Zahl 010 entspricht also der dezimalen Zahl 8. Die oktale Zahl0123 entspricht der dezimalen Zahl 83.Weitere Beispiele für oktale Zahlen sind: -033, +071, 01237Da in einer oktalen Zahl keine Ziffern außer 0 bis 7 vorkommen dürfen,ergibt die folgende Zeile einen Fehler beim kompilieren:

int i = 0129; // Fehlerhexadez. Li-teralWenn eine ganze Zahl nach dem optionalen Vorzeichen mit dem Text “0x” oder

“0X” beginnt, wird sie von Java als hexadezimales Literal interpretiert. Einhexadezimales Literal darf die Ziffern 0–9 und die Buchstaben A bis F enthalten(die Buchstaben dürfen dabei klein oder groß geschrieben werden). Der Werteines hexadezimalen Literals ergibt sich durch Umrechnung der hexadezimalenZahl.

Beispiel: Im hexadezimalen Zahlensystem gibt es nicht wie im dezima-len Zahlensystem 10 sondern ganze 16 Ziffern (die Ziffern 0-9 und dieBuchstaben A-F). Wenn man im hexadezimalen Zahlensystem von 0 bis18 zählt, sieht das so aus: 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9,0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x10, 0x11, 0x12Die hexadezimale Zahl 0xB entspricht also der dezimalen Zahl 11. Diehexadezimale 0xff entspricht der dezimalen Zahl 255. Die hexadizimaleZahl 0x100 entspricht der dezimalen Zahl 256.Weitere Beispiele für hexadezimale Zahlen: 0xaf, 0X1AfAF, -0xff, -0xfF

39

Page 40: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

DatentypganzzahligerLiterale

Ein ganzzahliges Literales ist immer vom Typ int, es sei denn, man hängt denBuchstaben L an. In diesem Fall erhält es den Datentyp long.Es stellt sich natürlich die Frage, warum man überhaupt ganzzahlige Literalevom Typ int und Typ long unterscheidet. Der Datentyp long umfaßt doch denDatentyp int, und daher sollte doch eigentlich der Datentyp long ausreichen,um alle ganzen Zahlen zu repräsentieren.Der Grund, warum es dennoch den Datentyp int gibt, wird im nächsten Kapitelüber Typkonvertierungen klar werden. Hier sei nur gesagt, daß Sie dort erfah-ren werden, daß es zwar gestattet ist, einer long–Variable einen Ausdruck vomTyp int zuzuweisen, daß es jedoch nicht gestattet ist, einer int–Variable einenAusdruck des Typs long zuzuweisen. Das folgende Programmfragment enthältdaher auf Zeile 3 und 4 Fehler:

int i = 5;long m = i;int j = 5L; // Fehler !int k = m; // Fehler !

Würde Java nun auch die Zahlen, hinter denen kein “L” steht, als long–Literaleinterpretieren, so wäre auch die erste Zeile des obigen Programmfragmentesungültig, und um dies zu vermeiden, gibt es für ganzzahlige Literale diese Un-terscheidung in die zwei Datentypen int und long.

Beispiel: Beispiele für Literale:

123 Dezimales Literal, Wert 123, Typ int123L Dezimales Literal, Wert 123, Typ long0123 Oktales Literal, Wert 83, Typ int0123L Oktales Literal, Wert 83, Typ long0xFF Hexadezimales Literal, Wert 255, Typ int

7.2.2 Reellwertige Literale

Alle in einem Java–Programm auftretenden Zahlen mit Dezimalpunkt oder Zeh-nerexponenten sind rellwertige Literale.Ein reellwertiges Literal besteht aus dem ganzzahligen Teil vor dem Dezimal-punkt, dem Nachkommateil und einem optionalen Zehnerexponenten. Der Zeh-nerexponent wird durch den Buchstaben “E” oder “e” eingeleitet. Der Exponentdarf negativ sein.Beachten Sie bitte, daß in Java der Dezimalpunkt nicht wie in Deutschlandüblich ein Komma ist, sondern ein Punkt ist.Reelle Zahlen haben in Java normalerweise den Datentyp double. Wenn Siehinter die Zahl den Buchstaben f oder F anhängen, erhält das Literal den Typfloat. Optional dürfen Sie auch ein d oder D anhängen, aber auch dann erhältdie Zahl den Datentyp double.

Beispiel: Beispiele für reellwertige Literale

1. Die Zahl 1.0, Datentyp double

40

Page 41: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

1.f Die Zahl 1.0, Datentyp float.1D Die Zahl 0.1, Datentyp double1.0E0 Die Zahl 1.0, Datentyp double1e5 Die Zahl 1 · 105, Datentyp double1e5f Die Zahl 1 · 105, Datentyp float+3.14159 Die Zahl +3.14159, Datentyp double4.10E-10 Die Zahl 4.10 · 10−10, Datentyp double4.10E-10f Die Zahl 4.10 · 10−10, Datentyp float

Beachten Sie bitte, daß Sie an einer Stelle im Programmtext, wo ein Ausdruckvom Typ double erwartet wird, zwar einen Ausdruck vom Typ float verwendendürfen. Sie dürfen jedoch an einer Stelle, wo ein Ausdruck vom Typ float er-wartet wird, keinen Ausdruck vom Typ double verwenden. Warum das so ist,erklären wir im nächsten Kapitel über Typwandlungen.

Beispiel: Das folgende Programmfragment enthält daher auf Zeilen 3und 4 Fehler.

double d1 = 3.14153; // erlaubt: Zuweisung double an doubledouble d2 = 2.1f; // erlaubt: Zuweisung float an doublefloat f1 = d1; // Fehler: Zuweisung double an floatfloat f2 = 3.14153; // Fehler: Zuweisung double an floatfloat f3 = 3.14153f;// erlaubt: Zuweisung float an float

7.2.3 Litarale vom Typ boolean

Es gibt zwei boolsche Literale, nämlich true und false. Beide haben den Daten-typ boolean.

Beispiel: Ein Beispiel zu Ihrer Verwendung:

public class DemoBoole {public static void main( String[] args ) {

boolean b1 = true;boolean b2 = false;

}}

Das Literal true steht für logisch wahre Werte und das Literal false steht fürlogisch falsche Werte.

Beispiel: Hier ein paar Beispiele für Ausdrucke, die in der Auswertungtrue oder false ergeben:

1 < 2 // Ausdruck vom Typ boolean, Wert : true2 < 1 // Ausdruck vom Typ boolean, Wert : false2 <= 2 // Ausdruck vom Typ boolean, Wert : true2 > 2 // Ausdruck vom Typ boolean, Wert : false

41

Page 42: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

7.2.4 Zeichenliterale

Zeichenliterale bestehen aus einem einzelnen Zeichen in einfachen Hochkomma-ta. Der Datentyp eines Zeichenliterals ist char, und der Wert des Zeichenliteralsist eine Zahl zwischen 0 und 65535, welche sich aus dem Unicode–Zeichensatzergibt.

Beispiel: Beispiele für char–Literale sind ’a’, ’B’, ’#’, ’+’, ’1’.Folgende Texte sind keine gültigen Zeichenliterale, da sie nicht genau einZeichen enthalten: ’’, ’aa’, ’12’.

UnicodeUnicode ist ein Zeichensatz, in dem jedes Zeichen durch eine 16–Bit–Zahl dar-gestellt wird. Es können also maximal 65536 verschiedene Zeichen dargestelltwerden können. Jedem Zeichen wird dabei eine eindeutige Zahl zwischen 0 und65535 zugeordnet. Zum Beispiel ist dem Buchstaben “a” die Zahl 97, dem Buch-staben “A” die Zahl 65 und der Ziffer “1” die Zahl 49 zugeordnet. Zeichen imUnicode–Zeichensatz sind Buchstaben, Zahlen und alle anderen Sonderzeichen,die der Computer darstellen kann sowie einige Zeichen mit besonderer Bedeu-tung wie Tabulator, Zeilenumbruch oder Rückschritt (Backspace). In sind Un-icode auch Buchstaben anderer Länder (etwa japanische Schriftzeichen) odersonstige normalerweise nicht verwendete Zeichen vorgesehen.

Beispiel: Folgendes Programm gibt die Zeichen ’a’, ’B’ und ’#’ und diediesen zugeordneten Zahlenwerte aus.Um die Unicode–Zahlenwerte der Zeichen auszugeben, ist es nötig, die Zei-chen in einen anderen Datentyp als char umzuwandeln (hier int). Die Aus-gaberoutine System.out.println gibt nämlich Werte des Datentyps charnicht als Zahl sondern als Zeichen aus.

public class DemoChar {public static void main( String[] args ) {

char a = ’a’; // ’a’ ist ein char-Literal mit Wert 97char b = ’B’; // ’b’ ist ein char-Literal mit Wert 66char x = ’#’; // ’#’ ist ein char-Literal mit Wert 35int ia = a; // Umwandlung des Datentypsint ib = b;int ix = x;System.out.println( a ); // Ausgabe des ZeichensSystem.out.println( ia );// Ausgabe seines ZahlenwertesSystem.out.println( b );System.out.println( ib );System.out.println( x );System.out.println( ix );

}}

Es gibt einige besondere Zeichen, die man mit der Tastatur nicht so einfach an-geben kann. Dazu gehört beispielsweise der Zeilenumbruch. Diese Sonderzeichenkann man eingeben, indem man eine sogenannte Escape–Sequenz verwendet. Ei-ne Escape–Sequenz wird durch das Zeichen \, den Backslash, eingeleitet. Immerwenn ein Zeichenliteral mit einem Backslash beginnt, werden die auf den Backs-lash folgenden Zeichen interpretiert, um den Wert des Zeichens zu ermitteln.

42

Page 43: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Welche Escape–Sequenzen es gibt, ist in Go To Java 2 in Tabelle 4.2 beschrie-ben. Den Backslash selbst ist durch ’\\’ gegeben.

Beispiel: Die folgenden Ausdrücke sind Zeichenliterale. Obwohl wir zurAngabe des Zeichens mehr als ein Zeichen benötigen, wird das Literalnur als ein Zeichen interpretiert: ’\n’ (Zeilenumbruch), ’\t’ (Tabulator),’\\’ (der Backslash \), ’\u0020’ (Leerzeichen).

Beispiel: Das folgende Programm verwendet Escape–Sequenzen, um dasZeichen “a”, zwei Leerzeilen (eine Leerzeile entsteht durch das Zeichen’\n’ und eine entsteht dadurch, daß die Ausgaberoutine selbst immernoch einen Zeilenumbruch einfügt) und danach den Backslash darzustel-len.

public class DemoEscape {public static void main( String[] args ) {

System.out.println(’a’);System.out.println(’\n’); // zwei LeerzeilenSystem.out.println(’\\’); // Ausgabe des Backslash

}}

7.2.5 Zeichenketten

Als letzte Art von Literalen sind sind schließlich noch die Zeichenketten zuerwähnen. Eine Zeichenkette ist ein Text in doppelten Hochkommata. Eine Zei-chenkette hat den Datentyp String, und ihr Wert ist die Zeichenfolge zwischenden doppelten Hochkommata.Zwischen den doppelten Hochkommata ist jedes Zeichen erlaubt, das auch ineinem Zeichenliteral verwendet werden könnte. Insbesondere können in einerZeichenkette auch die Escape–Sequenzen verwendet werden, die bei Zeichenli-teralen eingesetzt werden konnten.Zeichenketten unterscheiden sich deutlich von allen anderen bisher behandeltenLiteralen. Alle Literale waren bisher einfache Zahlen. Eine Zeichenkette ist abereine Folge von Zahlen.

Beispiel: Einige Beispiele zur Verwendung von Zeichenketten:

public class DemoString1 {public static void main( String[] args ) {

String hacker = "Neo";System.out.println( hacker );System.out.println("Ein Backslash: \\");System.out.println("Neue\nZeile\nund");System.out.println("Ein Anführungszeichen: \"");

}}

Eine Zeichenkette muß in der Zeile beendet werden, in der sie begonnen wur-de. Will man eine Zeichenkette konstruieren, die länger ist, so kann den +–Operator verwenden. Immer wenn zwischen zwei Zeichenketten ein + steht,entsteht durch Aneinanderhängen der beiden ursprünglichen Zeichenketten einelängere Zeichenkette.

43

Page 44: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Beispiel: So kann man eine längere Zeichenkette bauen:

public class DemoString2 {public static void main( String[] args ) {

System.out.println("Hallo, " + "Welt");System.out.println( "Um eine längere Zeichenkette" +

" zu bauen,\n kann man den +-Operator" +" benutzen. Man darf Zeichenketten \n" +" fast beliebig lang machen.");

}}

Beispiel:Dies Programm enthält einen Fehler, da eine Zeichenkette nichtin der Zeile beendet wird, in der sie begonnen wurde:

public class DemoString3 {public static void main( String[] args ) {

System.out.println("Hallo,Welt"); // Fehler !

}}

7.3 Verwendung von Variablen

Nachdem Sie nun die allereinfachste Art von Ausdrücken – nämlich die Literale –kennengelernt haben, soll die nächsteinfache Klasse von Ausdrücken besprochenwerden, nämlich die Variablen.Sie erinnern sich — eine Variable ist ein Platzhalter für irgendeinen Wert. Wenneine Variable in einem Ausdruck auftaucht, wird bei der Auswertung des Aus-drucks für die Variable ihr Inhalt eingesetzt. Selbstredend ist der Datentyp einesVariablen–Ausdrucks der Datentyp der Variable.

Beispiel: Im folgenden Programm wird in Zeile 03 eine Variable definiert,und ihr wird der Wert 1 zugewiesen. In Zeile 04 wird die AusgaberoutineSystem.out.println aufgerufen.Als auszugebender Wert wird ihr der Ausdruck i + 1 übergeben. DieserAusdruck hat den Datentyp int, da hier eine int-Variable zu einem int–Literal addiert wird. Der Wert des Ausdrucks ist der Wert der Variable i(also 1) plus dem Wert des Integerliterals “1”.

01 public class DemoVar1 {02 public static void main( String[] args ) {03 int i = 1;04 System.out.println( i + 1 );05 }06 }

InitialisierungDer erstmaligen Wertzuweisung einer Variable nach ihrer Definition kommt einebesondere Bedeutung zu, und gibt es dafür einen besonderen Namen: Initia-lisierung. Die Bedeutung der Initialisierung liegt darin, daß eine Variable biszur Initialisierung einen unbestimmten Wert enthält.

44

Page 45: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Natürlich enthält eine Variable von dem Moment an, in dem sie definiert wurde,immer irgendeinen Wert. Mit einer Variable ist ja immer ein gewisser Teil desArbeitsspeichers assoziiert, und der Wert der Variablen ergibt aus diesem Teildes Arbeitsspeichers. Man hat aber keinerlei Kontrolle darüber, welchen Wertder Arbeitsspeicher einer neu definierten Variable enthält. Es geht somit nichtaus dem Programmtext hervor, welchen Wert eine Variable bei ihrer Definitionerhält, und daher nennt man Variablen, denen noch keinWert zugewiesen wurde,nicht initialisiert oder sagt, sie hätten einen unbestimmten Wert.Da man einer Variable nur dann einen Wert zuweisen darf, wenn dem Compilerder Datentyp der Variable klar ist, darf man eine Variable nur nach oder währendihrer Definition initialisieren.

Beispiel: Im folgenden Beispiel wird eine Variable als int definiert. Inder nächsten Zeile wird sie zu 2 initialisiert:

int einInt;einInt = 2;

Man kann Definition und Initialisierung auch mit einem Befehl erledigen:

int einInt = 2;

Hingegen ist die folgende Anweisungen kein gültiger Java–Code, da eineVariable nicht vor ihrer Definition initialisiert werden darf:

{einInt = 2;int einInt;

}

Da eine Variable vor ihrer Initialisierung einen undefinierten Wert enthält undda die Verwendung undefinierter Werte normalerweise ein Fehler ist, kontrolliertder Java–Compiler bei jeder Verwendung einer Variable, ob sie bereits initia-lisiert sein kann. Falls der Compiler die Verwendung einer nichtinitialisiertenVariable erkennt, meldet er einen Fehler und schützt so den Programmierer vorder Verwendung undefinierter Werten.

Beispiel: Der Compiler würde im folgenden Programm erkennen, daß beider Initialisierung der Variable ergebnis die uninitialisierte Variable wertverwendet wird. Daher würde er das folgende Programm nicht akzeptieren:

public static void main(String[] args){

int wert;int ergebnis = wert * 3; // Fehler

}

In Go To Java, Kapitel 5.1 ist das genauer ausgeführt.

45

Page 46: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

7.4 Ausdrücke mit Operatoren

Neben der Verwendung von Literalen und Variablen gibt es in einem Java–Programm auch komplexer aufgebaute Ausdrücke — man kann mit Variablenoder Literalen rechnen, Variablen oder Literale miteinander vergleichen. Da sichbei einer solchen Rechnung oder einem Vergleich wieder irgendein Wert ergibt,sind auch Rechnungen und Vergleiche Ausdrücke. Auch Zuweisungen an Varia-blen sind Ausdrücke, da in Java auch die Zuweisung einen Wert ergibt.Jeder komplexe Ausdruck kombiniert mit Hilfe von Rechenoperatoren, Ver-gleichsoperatoren oder Zuweisungsoperatoren andere Ausdrücke zu einem neuenWert. Es gibt Operatoren, die nur auf einen einzigen Ausdruck operieren, es gibtaber auch Operatoren, die zwei Ausdrücke zu einem neuen Resultat verbinden.Es gibt sogar einen Operator, der drei Ausdrücke kombiniert. StelligkeitDie Anzahl der Ausdrücke, auf die ein Operator angewendet wird, um ein Er-gebnis zu liefern, nennt man die Stelligkeit des Operators.

Beispiel: Hier einige Beispiele für 1–stellige Operatoren.Aus der Mathematik kennen Sie den Fakultät–Operator und den Quadrie-rungsoperator — es gibt beide nicht in Java, aber da Sie Ihnen vertrautsind, verwenden wir sie in diesem Beispiel. Beide Operatoren kann an aufeinen einzigen Ausdruck anwenden. Dabei stehen diese Operatoren hinterdem Ausdruck, auf den sie angewendet werden.Die folgenden Ausdrücke sind Beispiele für die Verwendung eines einstel-ligen Operators, der hinter dem Ausdruck steht:5!, 52, (1 + 2)!, (1 + 2!)2

Sie kennen außerdem das 1–stellige Minus, welches das Vorzeichen einesAusdrucks umdreht. Es steht vor dem Ausdruck, auf das es angewandtwird — zum Beispiel−5, −(−3 + 3), −(3 − 2)2

Beispiel: Am häufigsten werden 2–stellige Operatoren verwendet.Zweistellige Operatoren kombinieren zwei Ausdrücke zu einem neuen Wertund stehen normalerweise zwischen den beiden zu verwendenden Aus-drücken.Hier ein paar Beispiele, in denen nur zweistellige Operatoren auftauchen:5 − 3, (3 + 2) · (3 + 1), 2 + 3Beachten Sie, daß es zwei Minus–Operatoren gibt: Das 1–stellige Minus,das den folgenden Ausdruck negiert sowie das 2–stellige Minus, das zweiAusdrücke voneinander substrahiert.

Jeder komplexe Ausdruck mit einem 1–stelligen Operator hat entweder die Form

Ausdruck Operator Derartige Operatoren nennt man auch “Postfix”–Operatoren,da sie hinter dem Ausdruck stehen, auf den sie ange-wandt werden. Beispiele für Einstellige Postfix–Operatorensind der Quadrat–Operator oder der Fakultät–Operator.

Operator Ausdruck Einen Operator, der vor dem Ausdruck steht, auf den erangewendet wird, nennt man auch “Präfix”–Operatoren.Beispiele für 1–stellige Präfix–Operatoren sind das 1–stellige Minus oder der Wurzeloperator.

46

Page 47: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Ausdrücke mit 2–stelligen Operatoren haben immer die Form

Ausdruck1 Operator Ausdruck2 Da hier der Operator zwischen den Aus-drücken steht, nennt man derartige Ope-ratoren auch “Infix”–Operatoren. Beispie-le für zweistellige Infix–Operatoren sind+,−, ∗, /.

Sie kennen nun Ausdrücke, die aus einem Literal bestehen, Ausdrücke, die auseiner Variable bestehen und Ausdrücke, in denen einstellige und zweistelligeOperatoren auftauchen. Durch diese Möglichkeiten, Ausdrücke aufzubauen, sindbereits fast alle erdenklichen Rechnungen in Java formulierbar.Wir haben die Operator–Ausdrücke nämlich rekursiv, das heißt selbstbezüg-lich, definiert. So hat ja ein zweistelliger–Ausdruck die Form

Ausdruck1 Operator Ausdruck2

Die beiden Ausdrücke Ausdruck1 und Ausdruck2 können nun selbst wieder be-liebige Ausdrücke sein. Beispielsweise könnteAusdruck1 ein zweistelliger Operator–Ausdruck mit einem anderen Operator sein, und Ausdruck2 könnte ein einstel-liger Präfix–Ausdruck sein. Wir haben also schon Ausdrücke der Form

(Ausdruck1,1 Operator Ausdruck1,2) Operator Prefix Ausdruck2,1

beschrieben. Analog kann man beliebig komplizierte Rechnungen durch wieder-holtes Anwenden der Operator–Ausdruck–Regeln als Ausdruck beschreiben.

Beispiel: Zum Beispiel kann die Rechnung a+5+6 auf zwei verschiedeneArten als Ausdruck interpretiert werden. Beide Arten der Interpretationlassen sich durch Graphiken interpretieren lassen, die einem auf den Kopfgestellten Baum ähneln:

int−Literal 5 int−Literal 6

+

Variable a

+

Zum einen ist die Rechnung alsAusdruck a + (5 + 6) interpretier-bar, also als Ausdruck, in welchemdurch den Plus–Operator der Aus-druck a und der Ausdruck 5 + 6 ad-diert werden.

Variable a

+

int−Literal 5

+

int−Literal 6

Alternativ könnte sie als Ausdruck(a+5)+6 interpretiert werden, alsoals Ausdruck in welchem durch denPlus–Operator der Ausdruck a + 5und der Ausdruck 6 addiert werden.

Beispiel:

Präfixopt − Postfixopt. !

Operator −

Operator *

Variable bVariable aint−Literal 5

Die Rechnung (−5) ∗ (a! − b) läßtsich nur auf eine Art als Ausdruckinterpretieren. Die graphische Dar-stellung der einzig möglichen Inter-pretation sehen Sie links.

Die obenstehenden Beispiele zeigen, daß man einen Ausdruck manchmal aufmehrere Arten aus kleineren Ausdrücke zusammensetzen kann. Dabei entspricht

47

Page 48: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

jede Art, den Ausdruck zusammenzusetzen, einer unterschiedlichen Klamme-rung. Selbstverständlich entspricht nicht jede Art und Weise, den Ausdruck inkleinere Einheiten aufzubrechen der mathematischen Gewohnheit.

Beispiel: Es macht für die Rechnung zwar keinen Unterschied, ob derAusdruck a + 5 + 6 als a + (5 + 6) oder als (a + 5) + 6 interpretiert wird.Es macht aber sehr wohl einen Unterschied, ob der Ausdruck a ∗ 5 + 6 alsa ∗ (5 + 6) oder als (a ∗ 5) + 6 interpretiert wird. Genauso macht es einenUnterschied, ob der Ausdruck a − 5 + 6 als a − (5 + 6) oder als (a − 5) + 6interpretiert wird.

Um jedem Ausdruck einen eindeutigen Wert zuzuteilen, hat man in der Mathe-matik vereinbart, daß man Ausdrücke von links nach rechts lesen soll — derAusdruck a − 5 − 6 wird als (a − 5) − 6 interpretiert. Außerdem hat man Re-chenregeln wie Punkt– vor Strichrechnung eingeführt. Es ist in der Mathematikauch üblich, daß Einstellige Postfixoperatoren zweistelligen Operatoren vorge-hen — der Ausdruck a+ 5! wird deshalb nicht als (a+ 5)! sondern als a+ (5!)interpretiert.Auch in Java werden die üblichen Rechenregeln beachtet. In Java haben dieeinzelnen Operatoren unterschiedliche Bindungskraft. Wenn in einem Ausdruckein Operator mit höherer Bindungskraft neben einem mit niedrigerer Bindungs-kraft steht, so zieht der Operator mit der höheren Bindungskraft die danebenstehenden Ausdrücke an sich.

Beispiel: Beispielsweise hat der Multiplikationsoperator eine höhere Bin-dungskraft als der Additionsoperator. Daher wird durch Java der Aus-druck a + 5 ∗ 6 nicht als (a + 5) ∗ 6 sondern als a + (5 ∗ 6) interpretiert —auch in Java geht also die Multiplikation der Addition vor.

Generell gilt, daß Einstellige Operatoren eine höhere Bindungskraft haben alszweistellige Operatoren.

Beispiel: Das einstellige Minus hat eine höhere Bindungskraft als derzweistellige Multiplikationsoperator. Daher wird der Ausdruck −2 + 5nicht als −(2 + 5) sondern als (−2) + 5 interpretiert.

Eine Tabelle, in der alle Java–Operatoren nach Bindungskraft geordnet aufge-führt sind, finden Sie in Go To Java in Kapitel 5.8 (Operator–Vorrangregeln). Esempfiehlt sich, diese Tabelle auszudrucken — Sie werden sie in der 4. Hausaufga-be benötigen. Jeder in der Tabelle stehende Operator hat höhere Bindungskraftals die später in der Tabelle stehenden Operatoren.Ein Verständnis der Vorrangsregeln ist sehr wichtig — wenn Sie sich allerdingsirgendwann mal nicht sicher sind, wie die Auswertereihenfolge eines Ausdrucksist, können Sie ganz einfach Klammern verwenden, um die Ausdrücke zusam-menzufassen:

Beispiel: Wenn Sie sich nicht sicher sind, ob die Vergleichsoperatorenhöhreren Vorrang als die Logik–Operatoren haben, könnten Sie statt

boolean w = 1 < 2 && 2 < 3 && 4 < 5;

auch schreiben

boolean w = (1 < 2) && (2 < 3) && (4 < 5);

48

Page 49: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

7.4.1 Arithmetische Operatoren

Die arithmetischen Operatoren Javas sind in Go To Java 2 in Kapitel 5.2 an-geführt. Zu den Operatoren ++ und -- sagen wir gleich mehr, zu den anderenOperatoren in Kapitel 5.2 gibt es nichts hinzuzufügen außer einem Beispiel:

Beispiel: Verwendung der arithmetischen Operatoren:

01 public class DemoArith {02 public static void main( String[] args ) {03 System.out.println( -3 + +5 );04 System.out.println( 2.0 / 5.0 - 3.0 * 7.1 );05 System.out.println("7 / 3 = " + 7 / 3 + ", Rest: " + 7 % 3 );06 System.out.println( 7.2 % 3 );07 }08 }

In Zeile 03 wird das einstellige Minus, das (eigentlich überflüssige) einstel-lige Plus und das zweistellige Minus verwendet.In Zeile 04 werden der Multiplikations und Divisionsoperator verwendet.In Zeile 05 werden zwei Integerzahlen dividiert (7/3 == 2). Dabei bleibtein Rest von 1 übrig. Auch der Rest der Division wird ausgegeben. Der“Rest bei ganzzahliger Division”–Operator heißt %.In Zeile 06 wird demonstriert, daß man den Restwert–Operator in Javaauch auf reelle Zahlen anwenden kann.

7.4.2 Inkrement und Dekrement–Operatoren

Die üblichen Rechenoperatoren wie +,-,*,/,% bedürfen sicher keiner weiterenErläuterung. Hingegen wird auf die Inkrement– und Dekrement–Operatoren vonJava im Text “Go To Java 2” leider nur mangelhaft eingegangen.Der Operator ++ wird Inkrement–Operator, der Operator -- wird Dekrement–Operator genannt. Sie unterscheiden sich deutlich von den anderen arithmeti-schen Operatoren, da sie nicht nur einen Wert berechnen, sondern gleichzeitigals Nebeneffekt auch eine Variable verändern.Sie können den Wert einer Variable um eins erhöhen, indem Sie entweder voroder hinter die Variable den Operator ++ setzen. Analog können Sie durch Ver-wendung des Operators -- den Wert einer Variable um eins verminden.Inkrement– und Dekrement–Operator existieren in jeweils zwei verschiedenenVersionen: einmal als Präfix– und einmal als Postfix–Operator.

• Steht ++ vor einer Variable, wie in

int einInt = 5;++einInt;

so heißt er Präinkrement–Operator

• Steht ++ hinter einer Variable wie in

49

Page 50: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

double einDouble = 5.321948;einDouble++;

so heißt er Postinkrement–Operator

• Analog heisst der -- Operator entwederPrädekrement bzw.Postdekrement–Operator, wenn er vor bzw. hinter einer Variable steht.

Inkrement– und Dekrement–Operatoren verändern den Wert einer Variable,selbst wenn überhaupt keine Zuweisung verwendet wird. Dabei liefern sie wiealle Ausdrücke gleichzeitig einen Wert.Im folgenden reden wir nur noch vom Inkrement–Operator. Für den Dekrement–Operator gilt alles analog.

Beispiel: Zum Beispiel wird in folgendem Beispiel der Wert der VariableeinInt zweimal erhöht, wobei einmal der Postinkrement- und einmal derPräinkrement-Operator verwendet wird. Der Wert der Ausdrücke wirddabei nicht verwendet.

int einInt = 5;einInt++;++einInt;

Der Postinkrement–Operator und der Präinkrement–Operator erhöhen beide dieVariable und liefern als Wert den Wert der Variable zurück. Dabei unterscheidensie sich dadurch, wann die Variable inkrementiert wird.Wird der Postinkrement–Operator verwendet, so wird zuerst der Wert der Va-riable ausgewertet und anschließend die Variable inkrementiert.Wenn hingegen der Präinkrement–Operator benutzt wird, wird zuerst die Varia-ble inkrementiert und anschließend die nun inkrementierte Variable ausgewertet.

Beispiel: Zum Beispiel hat nach Ausführung des folgenden Programm-textes die Variable wert den Wert 7, da sie zweimal inkrementiert wurde.

public class DemoInc1 {public static void main( String[] args ) {

int wert = 5;int ergebnis1 = wert++;int ergebnis2 = ++wert;

}}

Aber welchen Wert haben ergebnis1 und ergebnis2 ? Entscheidend hierfürist, ob zuerst die Zuweisung oder zuerst das Inkrementiern stattfindet.Nach unserer Beschreibung des Prä– und Postinkrementoperators ist dasobige Programm gleichwertig zu folgendem Programmfragment:

public class DemoInc2 {public static void main( String[] args ) {

int wert = 5;int ergebnis1 = wert;

50

Page 51: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

wert = wert + 1; // Ausführung des Postinkrementoperatorswert = wert + 1; // Ausführung des Präinkrementoperatorsint ergebnis2 = wert;

}}

Nach Ausführung des vorigen Beispiels haben also die einzelnen Variablenfolgende Werte:

wert == 5ergebnis1 == 5ergebnis2 == 7

Es sei hier erwähnt, daß Sie die Verwendung der Postinkrement– und Präinkre-mentoperatoren in komplizierten Ausdrücken vermeiden sollten, da die durchsie bewirkten Nebeneffekte oft nur schwer zu verstehen sind.

Beispiel: Erkennen Sie zum Beispiel, welche Werte die Variablen imfolgenden Programm erhalten ?

int i1 = 3;int i2 = 4;int ergebnis = ++i1 + --i2 + i1-- * --i2;

Ich glaube, einfacher zu verstehen ist die äquivalente Fassung:

int i1 = 3;int i2 = 4;i1--;i2--;ergebnis = i1 + i2 + i1 * i2;i1++;i2--;

Die Verwendung der Dekrement– und Inkrementoperatoren empfiehlt sich, wennSie eine Variable dekrementieren oder inkrementieren möchten. Insbesonderewenn Ihre Variablennamen lang sind, sparen Sie sich so Schreibarbeit und Feh-lerquellen und machen Ihr Programm übersichtlicher.

Beispiel: Ich hoffe, Sie stimmen mir zu, daß der Programmtext

einFurchtbarLangerVariablenName++;

besser zu lesen ist, als der Programmtext

einFurchtbarLangerVariablenName=einFurchtbarLangerVariablenName+1;

Schließlich sei noch erwähnt, daß die Inkrement– und Dekrementoperatoren aus-schließlich auf Variablen anwendbar sind. Das sollte eigentlich klar sein, da manauch nur Variablen einen Wert zuweisen kann.

Beispiel: Die folgende Anweisungsfolge ist ungültig:

int a=5;int b=(a*2)++; // Fehler: Zwischenergebnisse kann man nicht verändern

Auch die folgende Anweisungsfolge ist ungültig:

int a=5++; // Fehler: Literale kann man nicht verändern

51

Page 52: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

7.4.3 Relationale Operatoren

Kapitel 5.3 in Go To Java bedarf m.E. keiner weiteren Erklärung — es sei nurgesagt, daß Sie alles, was mit Referenztypen zu tun hat, noch nicht verstehenkönnen und auch nicht verstehen müssen.Relationale Operatoren vergleichen zwei Werte. Ein relationaler Ausdruck hatimmer den Datentyp boolean, liefert als entweder den Wert true oder falsezurück.

Beispiel: Hier ein Beispiel zur Verwendung relationaler Operatoren:

public class DemoRelational {public static void main( String[] args ){

double w1 = 5;double w2 = 6;System.out.println( w1 < w2 ); // ergibt trueSystem.out.println( w1 == w2 ); // ergibt falseSystem.out.println( w1 != w2 ); // ergibt trueSystem.out.println( w1 == w2 - 1); // ergibt trueSystem.out.println( w1 * 5 >= w2 - 1);// ergibt true

}}

7.4.4 Logische Operatoren

Auch zu Kapitel 5.4 über logischen Operatoren ist nicht viel hinzuzufügen.Logische Operatoren kombinieren zwei Ausdrücke vom Typ boolean zu einemneuen Wert des Datentyps boolean. Sie dienen dazu, Wahrheitswerte zu verglei-chen und kombinieren.

Beispiel: Hier noch ein Beispiel zur Verwendung der logischen Operato-ren:

public class DemoLogic1 {public static void main(String[] args){

System.out.println( true && true ); // trueSystem.out.println( false & true ); // falseSystem.out.println( false || true ); // trueSystem.out.println( false | false ); // falseSystem.out.println( ! false ); // trueSystem.out.println( ! true ); // false

}}

Beispiel: Noch ein Beispiel zur Verwendung der logischen Operatoren:

public class DemoLogic2 {public static void main(String[] args){

long a = 3;

52

Page 53: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

long b = 4;boolean w1 = a >= 3 && a < 5; // trueboolean w2 = a == 4 || b == 4; // trueboolean w3 = a >= 3 && ( a==4 || b == 4); // trueboolean w4 = !(a == 3); // false

}}

Normalerweise sollten Sie die Short–Circuit–Operatoren (siehe Go To Java, Kap.5.4) verwenden. Problematisch kann das werden, wenn in einem logischen Aus-druck Nebeneffekte (d.h. Veränderungen von Variablen) auftreten.

Beispiel: Hier ein warnendes Beispiel zur Short–Circuit–Evaluation.

public class DemoShortCircuit {public static void main(String[] args){

long a = 3;System.out.println( a > 4 && a++ < 5 );System.out.println(a);

}}

In der Auswertung a > 4 && a++ < 5 wird der Teil hinter der logischenUnd–Verknüpfung nicht ausgeführt, weil das Ergebnis des gesamten Aus-drucks (false) nach Auswertung von a > 4 klar ist (false && irgendwas istimmer false).Daher wird aber auch der Postinkrement–Operator nicht ausgeführt. DerWert von a ändert sich daher im obigen Beispiel nicht.Üblicherweise verwendet man immer die Short-Circuit–Operatoren. Ge-wöhnen Sie sich daher an, niemals Operatoren mit Nebeneffekten in logi-schen Ausdrücken zu verwenden !

7.4.5 Bitweise Operatoren

Kapitel 5.5 in Go To Java 2 bedarf m.E. keiner weiteren Erläuterung, wenn Siesich mit Binärzahlen auskennen.

7.4.6 Zuweisungsoperatoren

Auch Kapitel 5.6 in Go To Java 2 benötigt m.E. kaum weitere Erläuterungen.Eine Besonderheit von Java ist, daß Zuweisungen einen Wert zurückliefern. DerZuweisungsoperator ist in Java ein Operator, der prinzipiell überall dort einge-setzt werden kann, wo Sie auch eine Addition oder Multiplikation durchführenwürden. Nur haben Zuweisungsoperatoren einen Nebeneffekt, nämlich die Zu-weisung eines Wertes an eine Variable.

Beispiel: Es ist möglich, mehrere Zuweisungen in einem Befehl durch-zuführen. Zum Beispiel wird hier den Variablen a und b der Wert 5 zuge-wiesen:

53

Page 54: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

int a;int b = a = 5;

Das funktioniert so: Der Compiler erkennt, daß der Variable b der Wertzugewiesen wird, der rechts vom ersten Gleichheitszeichen steht. Zunächstwird der Ausdruck daher als

int b = (a = 5);

interpretiert. Dann wertet Java den Ausdruck (a = 5) aus, weist dabeider Variable a den Wert 5 zu und liefert als Ergebnis des Ausdrucks a = 5den Wert 5. Dieser wird dann der Variablen b zugewiesen.

Sie können innerhalb jeder Rechnung Zuweisungen vornehmen. Achten Sie dabeidarauf, daß Ihre Programme lesbar bleiben.

Beispiel: Finden Sie den folgenden Programmtext übersichtlich ?

int a;int b;int c = 5 * (b = 6 - (a = 5) * 20);

Nur, weil diese Anweisungen erlaubt sind, sollten Sie sie nicht verwenden.Übersichtlicher hätte man dieses Programmfragment schreiben können als

int a = 5;int b = 6 - a * 20;int c = 5 * b;

Sehr hilfreich sind die Zuweisungsoperatoren, die bei der Zuweisung noch rech-nen.

Beispiel: Zum Beispiel kann man statt

einRelativLangerVariablenName=einRelativLangerVariablenName+5;

auch schreiben

einRelativLangerVariablenName += 5;

Die zweite Schreibweise ist besser lesbar und weniger fehleranfällig. Analogkönnen Sie die Operatoren *=,-=,/= und die übrigen Zuweisungsoperato-ren verwenden.

Auch die rechnenden Zuweisungsoperatoren können— genau wie die Inkrement–, Dekrement– und Zuweisungsoperatoren in jedem Ausdruck verwendet werden.

Beispiel: Zum Beispiel:

int a = 5;int b = 3;int c = 6 * (a += 5) - (b *= 2);

54

Page 55: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Auch hier gilt: Achten Sie primär auf gute Lesbarkeit Ihres Programmsund nicht auf ausgefallene oder trickreiche Verwendung dieser Operatoren.

Beispiel: Hier noch ein Beispiel, in welchem Zuweisungsoperatoren miß-braucht werden. Dies ist gültiger Java–Code, aber wer derartigen Codeverwendet, disqualifiziert sich als übler Hacker:

int a = 5;int b = 3;int c = 6 * (b += (a -= ((a += 5) - (b *= 2))));

7.4.7 Weitere Operatoren

Zu Kapitel 5.7 von Go To Java: Die Type–Cast–Operatoren hatten wir bereitsim vorigen Kapitel besprochen. Die Ausführungen zu Strings sollten Sie über-fliegen. Die Ausführungen zu Referenzgleichheit und zu den anderen Operatorenbrauchen Sie noch nicht zu verstehen.

55

Page 56: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

7.5 Zusammenfassung

Sie müssten nun die folgenden Fragen beantworten können:

B Was ist ein Ausdruck ?B Welches sind die relevanten Eigenschaften eines Ausdrucks ?B Was für Arten von Ausdrücken kennen Sie ?B Was ist ein Literal ?B Welche ganzzahligen Literale kennen Sie ?B Welchen Wert hat das Zahlenliteral 020 ?B Welchen Wert hat das Zahlenliteral 0x10 ?B Wie kann man ein ganzzahliges long-Literal erzeugen ?B Wie ist ein reellwertiges Literale aufgebaut ?B Wie kann man ein float–Literal erzeugen ?B Welche boolschen Literale gibt es ?B Wie muß ein Zeichenliteral aussehen ?B Beschreiben Sie die Regeln für Zeichenketten–Literale !B Was versteht man unter der Initialisierung einer Variable ?B Warum müssen Variablen vor ihrer Verwendung initialisiert werden ?B Was ist ein Operator ?B Was ist die Stelligkeit eines Operators ?B Geben Sie Beispiele für 1–stellige und 2–stellige Operatoren !B Gibt es in Java 3–stellige Operatoren ?B Was versteht man unter Nebeneffekten ?B Was sind Operator–Vorrangregeln ?B Was verstehen wir unter der “Bindungskraft” eines Operators ?B Warum sind Operatorvorrangregeln wichtig ?B Was sind Inkrement– und Dekrement–Operatoren ?B Wie unterscheiden sich Postinkrement– und Präinkrement–Operator ?B In welchen Fällen sollte man die Inkrement– und Dekrement–

Operatoren vermeiden bzw. verwenden ?B Welche relationalen Operatoren kennen Sie ?B Welche Datentypen sind bei der Verwendung relationaler Operatoren

möglich ?B Welche Gefahren bestehen bei Verwendung von Short–Circuit Logik–

Operatoren ?B Welche Zuweisungsoperatoren gibt es in Java ?B Warum kann man in Java in einem Befehl mehrere Variablenzuwei-

sungen vornehmen ?

56

Page 57: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

8 TypwandlungenHier geben wir Ihnen weitere Informationen zu Goto Java 2, die Sie ergänzendzu Hausaufgabe 3 lesen sollten.Sie sollten für die weiteren Ausführungen zunächst in Go To Java Kapitel 4.6über “Typkonvertierunen” lesen. Dort wird besprochen, welche Typkonvertie-rungen der Java–Compiler automatisch vornehmen kann — leider werden keineBeispiele für Typkonvertierungen gebracht, und es wird auch nicht erwähnt,warum Typkonvertierungen wichtig sind.

8.1 Automatische Typkonvertierungen

Im vorigen Kapitel haben Sie gelernt, daß jeder Ausdruck in einem Java–Programmeinen Datentyp hat. Manchmal ist es notwendig, einen Ausdruck eines gewis-sen Datentyps in einen anderen Datentyp umzuwandeln. Teilweise werden dieseUmwandlungen durch den Java–Compiler automatisch vorgenommen, teilweisemuß man sie explizit befehlen.Warum Typwandlungen überhaupt nötig sind, soll an einem Beispiel demon-striert werden. Es seien die folgenden Variablen definiert:

int i1 = 5;int i2 = 3;float f1 = 3.123f;float f2 = 2.723f;double d1 = 3.1234567890123456;

Jede Rechnung mit diesen verschiedenen Variablen muß irgendwie vom Prozes-sor ausgeführt werden. Besprechen wir das an den Beispielen der Addition undder Multiplikation.Übliche Prozessoren enthalten Funktionen, mit denen zwei Integer addiert odermultipliziert werden können. Sie haben auch Funktionen, mit denen zwei Floatoder zwei sonstige Datentypen addiert oder multipliziert werden können. DasErgebnis dieser Funktionen hat dann normalerweise den gleichen Datentyp wiedie Operanden der Rechnung.

Beispiel: Wenn Sie mit zwei int–Variablen rechnen, kann der Prozessordie Rechnung direkt vornehmen. Das Ergebnis ist dann immer wieder einInteger (überlegen Sie sich, warum das Ergebnis der Division nicht derErwartung entspricht !)

i1 + i2; // Ergebnis: int, 8i1 / i2; // Ergebnis: int, 1i1 * i2; // Ergebnis: int, 25

Genauso ist das Ergebnis beim Rechnen mit float–Variablen immer wie-der ein Float:

f1 + f2; // Ergebnis: float, 5.846f1 / f2; // Ergebnis: float, 1.1468968...f1 * f2; // Erbebnis: float, 8.503929

57

Page 58: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Normalerweise enthalten Prozessoren keine Funktionen, die gleichzeitig mit ver-schiedenen Datentypen rechnen können. Will man also mit zwei Werten ver-schiedener Datentypen miteinander verrechnen, müssen erst beide Datentypenin einen gemeinsamen Datentyp konvertiert werden. Danach kann die Rechnungin diesem Datentyp stattfinden.

Beispiel: Prozessoren sind meist nicht dazu in der Lage, einen Integer-Wert und einen Float oder einen Float und einen Double zu addieren.Wenn Sie die Rechnung

i1 + f1;

durchführen wollen, muß sie also vorher noch aufbereitet werden. DerProzessor kann entweder zwei Integer oder zwei Float addieren. Es bietensich daher zwei Möglichkeiten an, um die Rechnung mit den Funktionendes Prozessors durchzuführen:

• Wandlung der Float-Variable zu einem Integer und Durchführungder Addition als Integer-Addition:

i1 + (int)f1;

Dabei bedeutet der Ausdruck (int)f1: Wandele f1 in einen Integer–Wert um. In der Regel geschieht eine solche Umwandlung durchWegwerfen aller Nachkommastellen.Mit den oben angegebenen Werten würde diese Rechnung wie folgtausgeführt:i1 + (int)f1 == 5 + (int)3.123 == 5 + 3 == 8

• Wandlung des Integers zu einem Float und Durchführung der Addi-tion als Float–Addition:

(float)i1 + f1;

Hier bedeutet der Ausdruck (float)i1: Wandle den Integer i1 ineinen Float–Wert um. Dies geschieht ohne Verlust von Information.Mit den oben angegebenen Werten würde diese Rechnung so ausge-führt:(float)i1 + f1 == (float)5 + 3.123 == 5.0 + 3.123 == 8.123

Die Antwort, welche der beiden Möglichkeiten gewählt wird, fällt leicht:Wenn wir den Float–Wert zu einem Integer wandeln, verschenken wirRechengenauigkeit und kommen zu falschen Ergebnissen. Wenn wir denInteger hingegen in einen Float wandeln, erhalten wir das erwartete Er-gebnis.

Bei Typwandlungen, die der Compiler automatisch vornimmt, wird immer dar-auf geachtet, keine Genauigkeit zu zerstören. Datentypen werden in Rechnungendarum nur zu genaueren Datentypen umgewandelt.Abbildung 4.1 im Kapitel 4.6 von “Go To Java 2” zeigt genau dies — ein short,der ja nur die ganzen Zahlen von −215 bis 215 − 1 darstellen kann, kann au-tomatisch in die umfangreicheren Datentypen int, long oder float umgewandeltwerden. Hingegen wird der Datentyp double niemals automatisch in einen an-deren Datentyp gewandelt, da dies der genaueste und umfangreichste Datentypder Sprache Java ist.

58

Page 59: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Typkonvertierungen treten immer auf, wenn ein Ausdruck eines gewissen Typserwartet wird, aber ein anderer Typ vorliegt. Es kommt des öfteren vor, daß in ei-nem Ausdruck ein niedriger Genauigkeit benötigt wird, der zu benutzende Wertaber eine hohe Genauigkeit hat. In solch einem Fall würde eine TypwandlungGenauigkeit verschenken. Der Java–Compiler würde daher statt eine automati-sche Typwandlung vorzunehmen, das Programm als fehlerhaft bemäkeln.Ein gutes Beispiel für Fälle, in denen eine Typkonvertierung zu ungenaueren Ty-pen nötig ist, bieten die Zuweisungsoperatoren. Der einer Variable zugewieseneWert muß ja immer den Datentyp der Variable haben. Wird nun einer Variableeines “ungenauen” Datentyps ein Wert eines genaueren Datentyps zugewiesen,so erzeugt das einen Kompilationsfehler.

Beispiel: Zum Beispiel sind folgende Anweisungen erlaubt, da eineWandlung zu einem genaueren Typ stattfindet:

f1 = i1; // bei Zuweisung: autom. Wandlung i1 zu floatd1 = i1; // bei Zuweisung: autom. Wandlung i1 zu doubled1 = f1; // bei Zuweisung: autom. Wandlung f1 zu double

Alle oben genannten Zuweisungen sind erlaubt, da hier bei den automa-tischen Typwandlungen keine Genauigkeit verlorengeht.Hingegen sind die folgenden Anweisungen nicht erlaubt:

i1 = f1; // verboten, da float genauer als inti1 = d1; // verboten, da double genauer als intf1 = d1; // verboten, da double genauer als float

In jedem dieser Fälle würde Genauigkeit verlorengehen, und darum wür-de der Compiler mit einer Fehlermeldung gegen jede der Anweisungenprotestieren. Die Fehlermeldung könnte wie folgt aussehen:

Programmname.java:11: Incompatible type for =. Explicit castneeded to convert float to int.

i1 = f1;

Beispiel: Sehr häufig kommen derartige Fehlermeldungen in Program-men vor, in denen man Float–Variablen einen Wert zuweist. Sie haben jaim vorigen Kapitel gelernt, daß reellwertige Zahlenliterale den Datentypdouble erhalten, wenn sie nicht das Anhängsel “f” haben. Die Zuweisungeines double–Literals an eine float–Variable bedingt einen Genauigkeits-verlust und führt daher zu einem Compiler–Fehler:

01 int i;02 i = 1; // erlaubt: Zuweisung int-Literal an int03 i = 1L; // Fehler: long-Literal, aber int erwartet04 i = 3.141; // Fehler: Zuweisung double-Literal an int05 float f;06 f = 1; // erlaubt: Zuweisung int-Literal an float07 f = 3.141f; // erlaubt: Zuweisung float-Literal an float08 f = 3.141; // Fehler: double-Literal, doch float nötig09 double d;10 d = 1l; // erlaubt: Zuweisung long-Literal an float;11 d = 3.141f; // erlaubt: Zuweisung float-Literal an double12 d = 3.141; // erlaubt: Zuweisung double-Literal an double

59

Page 60: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

8.2 Manuelle Typkonvertierungen

Oft will man trotzdem Werte höherer Genauigkeit an Stellen verwenden, andenen eine niedrigere Genauigkeit benötigt wird. Wieder ist die Zuweisung einesWertes an eine Variable das beste Beispiel für derartige Fälle.Wenn wir beispielsweise wissen, daß in einer float–Variable ein Wert ohne Nach-kommastellen enthalten ist, sollten wir in der Lage sein, diesen als Integer auf-zufassen.Oftmals brauchen wir die höhere Genauigkeit auch nicht wirklich. Es ist zumBeispiel üblich, die Zwischenschritte einer Rechnung in einer hohen Genauigkeitdurchzuführen und dann das Endergebnis der Rechnung nur in einer niedrigenGenauigkeit zu verwenden.Java nimmt ohne unser Zutun solche Typwandlungen nicht vor. Wir könnenJava aber befehlen, eine Typwandlung vorzunehmen. Wir verwenden dazu einenTypwandlungsoperator und signalisieren Java damit: An dieser Stelle ist es inOrdnung, Genauigkeit zu verschenken, wir wissen schon was wir tun. Type–castDefinition: Type–cast

Eine manuelle Typwandlung nennt man type–cast.

Um einen Wert explizit in anderen Datentyp zu wandeln, schreibt man denDatentyp, zu dem der Wert gewandelt werden soll, in runde Klammern und denWert dahinter:

(datentyp) wert

Dies ist die Anweisung an den Compiler eine Typwandlung vorzunehmen.

Beispiel: Folgende Zuweisungen sind erlaubt, obwohl bei der WandlungGenauigkeit verloren geht:

i1 = (int)f1;i2 = (int)d1;f1 = (float)d1;

Mit den oben definierten Werten für die einzelnen Variablen ergeben sichhier die folgenden Werte für i1 bis f1:

i1 == (int)f1 == (int)3.123 == 3i2 == (int)d1 == (int)3.1982 == 3f1 == (float)d1 == (float)3.1234567890123456 == 3.1234567

Ein Wert niedrigerer Genauigkeit ergibt sich dabei meist aus einem Werthöherer Genauigkeit durch wegwerfen von Nachkommastellen.

Sie können bei jedem Ausdruck eine Typwandlung vornehmen. Sie dürfen Typ-wandlungen auch an Stellen vornehmen, an denen sie überflüssig sind.

Beispiel: Die folgenden Type–Casts sind zwar erlaubt aber überflüssig,da Java hier einen automatischen Type–Cast vornehmen würde>

60

Page 61: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

f1 = (float)i1;d1 = (double)f1;

Allerdings sind Typwandlungen nur dort gestattet, wo sie Sinn machen.

Beispiel: Beispielsweise kann man Zahlen nur untereinander umwandeln,wobei der Datentyp char auch als Zahl zählt. Folgender Programmtextführt zu einem Fehler:

int i1 = (int)"Ein Text"; // Fehler

Eine wichtige Besonderheit ist bei Typwandlungen noch zu erwähnen: Die ein-zelnen primitiven Datentypen sind nicht nur unterschiedlich genau. Auch derWertebereich unterscheidet sich. Auf diese Problematik wollen wir hier abernicht weiter eingehen — hier nur ein Beispiel dazu:

Beispiel:Wenn Sie einen zu großen Double–Wert in einen Float wandeln,wird der Wert als Infinity dargestellt:

double d = 1.23e300; // ist nicht als float darstellbarfloat f = (float) d; // jetzt enthält f den Wert Infinity

8.3 Zusammenfassung

Sie müssten nun die folgenden Fragen beantworten können:

B Warum sind Typkonvertierungen nötig ?B Welche Arten von Typkonvertierungen führt Java automatisch durch ?B Geben Sie einige Beispiele, in denen Typkonvertierungen automatisch

durchgeführt werden !B Warum führt Java manche Typkonvertierungen nicht automatisch

durch ?B Geben Sie einige Beispiele, in denen statt einer automatischen Typ-

konvertierung ein Fehler ausgegeben wird !B Wie kann man Java dazu zwingen, einen Wert in einen anderen Typ

zu wandeln ?B Nennen Sie einige Beispiele für überflüssige Typwandlungen !

9 Anweisungen und KontrollstrukturenHier beziehen wir uns auf Kapitel 6 von Go To Java 2.Die Steuerung des Programmablaufs geschieht durch sogenannte Anweisungen.Jede Anweisung bewirkt irgendwelche Aktionen des Prozessors. Einige Anwei-sungen haben Sie bereits kennengelernt, so ist z.B. die Verwendung der Ausgabe-routine eine Anweisung. Auch die Definition von Variablen oder die Verwendungvon Ausdrücken sind Anweisungen.Jede Anweisung in einem Java–Programmmuß mit einem Semikolon enden. Diesist nötig, da Zeilenumbrüche für den Java–Compiler keine Bedeutung haben under daher nicht anhand der Zeilenstruktur erkennen kann, wo eine Anweisungzuende ist.

61

Page 62: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

9.1 Leere Anweisung

Siehe auch Kapitel 6.1 in Go To Java.Die einfachste Anweisung in einem Java–Programm ist die leere Anweisung.Sie hat keine Wirkung. Daß die leere Anweisung erlaubt ist, bedeutet im we-sentlichen, daß Sie beliebig viele Semikoli setzen dürfen — auch dort, wo nichtunbedingt eines stehen muß.

Beispiel:

public class DemoEmpty {public static void main( String[] args ){

; // Leere Anweisung;; // Zwei leere Anweisungen

}}

9.2 Blockanweisung

Der Block gruppiert eine Gruppe von Anweisungen zu einer Einheit. Sie hat dieForm

{Anweisung1;Anweisung2;...

}

Sie sollten sich angewöhnen, den Inhalt eines Blockes durch Einrückung der imBlock enthaltenen Zeilen optisch kenntlich zu machen — in allen Beispielpro-grammen machen wir Ihnen das auch so vor.Beachten Sie, daß die Beschreibung der Blockanweisung rekursiv ist — der Blockist eine Anweisung und in einem Block dürfen wieder Anweisungen stehen. Da-her darf in einem Block auch ein weiterer Block enthalten sein.

Beispiel: Dies ist ein gültiges Java–Programm. Im Klassenkörper ist dieMethode main enthalten. In deren Methodenkörper sind zwei ineinanderverschachtelte Blöcke enthalten.Der Klassenkörper wird auch durch geschweifte Klammern abgegrenzt,sieht also genauso aus wie ein Blöcke aus. Er ist aber dennoch kein Anwei-sungsblock, da er keine Anweisungen sondern nur Definitionen enthaltendarf.

public class DemoBlock { // hier startet der Klassenkörperpublic static void main( String[] args ){ // hier startet der Methodenkörper

; // Leere Anweisung{ // hier startet Block 1

{ // und hier startet Block 2System.out.println("Hallo, Welt !");

62

Page 63: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

} // hier endet Block 2} // hier endet Block 1

} // hier endet der Methodenkörper} // hier endet der Klassenkörper

9.3 Variablendefinitionen

Variablendefinitionen haben wir schon oft benutzt. Sie wissen bereits, daß manVariablen nur verwenden kann, nachdem man sie definiert hat.Zu beachten ist, daß eine Variablen Variablendefinition immer nur für den Blockgilt, in welchem sie definiert wurde. Sobald die Programmausführung einenBlock verläßt, haben die in diesem Block definierten Variablen keine Bedeutungmehr. Man sagt auch: Variablendefinitionen gelten nur lokal im enthal-tenden Block.Wenn in einem Block ein weiterer Block enthalten ist, erbt dieser alle Varia-blendefinitionen des äußeren Blockes:

Beispiel: Im folgenden Beispiel wird im Block 2 die Variable i1 definiertund initialisiert. Da Block 3 und Block 4 in Block 2 enthalten sind, kanni1 auch aus Block 3 und 4 verwendet werden.Auch in Block A wird die Variable i1 definiert. Diese Variable i1 hatgar nichts mit der Variable i1 in Block 2 zu tun, da sie außerhalb Block2 definiert wurde. Die Variablendefinitionen von Block 2 und Block Abeeinträchtigen sich überhaupt nicht gegenseitig.In Block 1 ist die Variable i1 nicht bekannt, da sie weder in Block 1 noch ineinem Block 1 umschließenden Block definiert wurde. Die Verwendung derVariable i1 in Block 1 führt daher zu einer Fehlermeldung des Compilers.

public class DemoBlock1 {public static void main( String[] args ){ // Block 1

{ // Block 2int i1 = 5;{ // Block 3

{ // Block 4System.out.println(i1);

}}

}{ // Block A

String i1 = "Hallo, Welt";}System.out.println(i1); // Fehler !

}}

Sie dürfen in einem Block keine Variable zweimal definieren.

Beispiel: Das folgende Programm ist fehlerhaft, da die Variable i1 imgleichen Block zweimal definiert wird:

63

Page 64: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

public class DemoBlock2 {public static void main( String[] args ){

int i = 1;double i = 3.5; //Fehler

}}

Leider dürfen sich in Java Variablen nicht gegenseitig verdecken — sie dürfenVariablen auch dann nicht in einem Block definieren, wenn sie zuvor nur ineinem diesen Block umschließenden Block definiert wurden.

Beispiel: Im folgenden Beispiel wird in Block 1 eine int–Variable defi-niert. Block 2 erbt diese Definition, da er in Block 1 enthalten ist. Daherdarf in Block 2 i nicht nochmal definiert werden.

public class DemoBlock3 {public static void main( String[] args ){ // Block 1

int i = 1;{ // Block 2

int i = -5; // Fehler}

}}

9.4 Ausdrucksanweisungen

Zu den Ausführungen über Ausdrucksanweisunge in Kapitel 6.1 von Go To Java2 braucht nichts hinzuzugefügt zu werden außer einem Beispiel:

Beispiel: Hier ein Beispiel mit verschiedenen Ausdrucksanweisungen.

01 public class DemoVar1 {02 public static void main( String[] args )03 {04 System.out.println("Hallo, Welt !");05 int i = 5; // Variablendefinition und Initialisierung06 i = 6; // Ausdrucksanweisung: Zuweisung07 i++; // Ausdrucksanweisung: Inkrement08 5 + 2; //09 }10 }

In der Ausdrucksanweisung in Zeile 08 wird eine Addition durchgeführt.Die Ausdrucksanweisung hat aber keine weitere Wirkung, da der Wert desAusdrucks weder ausgegeben noch sonstwie verwendet wird.Die Ausdrücke in Zeile 06 und 07 haben dagegen eine Wirkung (näm-lich jeweils eine Veränderung der Variable i), da in ihnen Operatoren mitNebeneffekten verwendet werden.

64

Page 65: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

9.5 If–Anweisung

Kapitel 6.2 von Go To Java 2 sollte so verständlich sein. Nur fehlen mal wiederBeispiele.Sie sehen ja in Go To Java 2, daß eine if –Anweisung in zwei Versionen auftretenkann. Einmal mit und einmal ohne else–Zweig. Beachten Sie bei der Besprechungaller weiteren Anweisungen, daß eine Anweisung auch ein Block sein kann.

Beispiel: Hier ein Beispiel zu if

public class DemoIf1 {public static void main( String[] args ){

int temperatur = 30;if ( temperatur > 25 )

System.out.println("Boah, ganz schön warm");}

}

Beispiel: Hier ein Beispiel, bei welchem die Anweisung ein Block ist:

public class DemoIf2 {public static void main( String[] args ){

int temperatur = 30;if ( temperatur > 25 ) {

System.out.println("Boah, ganz schön warm");System.out.println("Stell doch mal einer die Klimaanlage an");

}}

}

Beispiel: Und hier noch ein Beispiel, in dem es auch einen else–Zweiggibt:

public class DemoIfElse {public static void main( String[] args ){

int temperatur = 30;if ( temperatur > 22 ) {

System.out.println("Boah, ganz schön warm");System.out.println("Stell doch mal einer die Klimaanlage an");

} else {System.out.println("Schön --- zu heiß ist es nicht.");

}}

}

Das in Go To Java erwähnte Dangling else (“hängendes Else”) bedarf noch einerweiteren Diskussion: Sie sollten Dangling else—Strukturen immer vermeiden.Verwenden Sie in Fällen, wo ein Dangling else auftritt, immer Blöcke !

65

Page 66: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Beispiel: Hier tritt ein Dangling else auf — aufgrund der suggestivenEinrückung ist nicht auf den ersten Blick klar, daß die else–Anweisungnicht zur ersten sondern zur zweiten if –Anweisung gehört. Das Programmarbeitet daher nicht so, wie gewünscht.

public class DemoDangling1 {public static void main( String[] args ){

int temperatur = 30;boolean istKlimaanlageAn = true;if ( temperatur < 15 ) // if-Anweisung 1

if ( istKlimaanlageAn ) // if-Anweisung 2System.out.println("Klimaanlage abstellen");

elseSystem.out.println("Schön --- zu kalt ist es nicht.");

}}

Das Problem kann durch Verwendung von Blöcken behoben werden. Siesollten sich angewöhnen, in solchen leicht mißverständlichen Situationenimmer Blöcke zu verwenden !

public class DemoDangling2 {public static void main( String[] args ){

int temperatur = 30;boolean istKlimaanlageAn = true;if ( temperatur < 15 ) {

if ( istKlimaanlageAn )System.out.println("Klimaanlage abstellen");

} elseSystem.out.println("Schön --- zu kalt ist es nicht.");

}}

9.6 Switch–Anweisung

Die Switch–Anweisung ist in Go To Java in Kapitel 6.2.2 beschrieben.Zur switch–Anweisung ist hinzuzufügen, daß hinter jedem case eine Reihe vonAnweisungen steht. Wird ein case angesprungen, so werden auch die darauffolgenden case–Blöcke abgearbeitet, wenn kein break in den Anweisungen steht.

Beispiel: Das folgende Programm gibt die textliche Darstellung einerZahl aus. Dastut es einmal mit einer Folge von if –Anweisungen und einmalmit einer gleichwertigen switch–Anweisung.Tippen Sie das Programm ab und testen Sie, was passiert, wenn Sie einigebreak–Anweisungen entfernen !

public class DemoSwitch {public static void main( String[] args ){

int zahl = 1;if ( zahl == 1) {

66

Page 67: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

System.out.println("Eins");} else if (zahl == 2) {

System.out.println("Zwei");} else if ( zahl == 3) {

System.out.println("Drei");} else if (zahl == 4) {

System.out.println("Vier");} else {

System.out.println("Diese Zahl kenne ich nicht");}

// Äquivalente Lösung per switch:switch(zahl) {case 1:

System.out.println("Eins");break;

case 2:System.out.println("Zwei");break;

case 3:System.out.println("Drei");break;

case 4:System.out.println("Vier");break;

default:System.out.println("Diese Zahl kenne ich nicht-");break;

}}

}

9.7 Schleifen

Zu Kapitel 6.3 ist nicht viel hinzuzufügen außer einigen Beispielen.

9.7.1 Die While–Schleife

Die While–Schleife können Sie immer dann einsetzen, wenn Sie eine oder mehre-re Anweisungen immer wieder ausführen wollen, solange eine gewisse Bedingungerfüllt ist.Sie hat die Form

while( Schleifenbedingung )anweisung;

Der Anweisungsblock einer while–Anweisung wird immer wieder abgearbeitet,während die Schleifenbedingung erfüllt ist.Im Detail wird eine while–Anweisung wie folgt abgearbeitet: Zunächst wird dieSchleifenbedingung ausgewertet, welche ein boolscher Ausdruck sein muß. Fallssich hier der Wert false ergibt, so wird mit der nächsten Anweisung hinter derwhile–Schleife weitergemacht.Falls sich hingegen für die Schleifenbedingung der Wert true ergibt, so wirddie Schleifenanweisung durchgeführt. Beachten Sie, daß diese Anweisung auchein Block sein darf. Nachdem die Schleifenanweisung abgearbeitet ist, wird dieSchleifenbedingung erneut geprüft, wenn sich hier wieder der Wert true ergibt,wird die Schleifenanweisung erneut ausgeführt. Dies geschieht wieder und wie-der, bis die Schleifenbedingung den Wert false ergibt.

67

Page 68: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Beispiel: Die Anweisung in Zeile 05 wird niemals ausgeführt, da dieSchleifenbedingung in Zeile 04 immer false ist.

01 public class DemoWhile1 {02 public static void main( String[] args )03 {04 while( false )05 System.out.println("Hallo, Welt");06 }07 }

Beispiel: Eine Schleife, die immer wieder ausgeführt wird und niemalswieder verlassen wird, nennt man Endlosschleife. Das folgende Pro-gramm ist eine solche, da die Bedingung in Zeile 04 immer true ist.Dieses Programm beendet sich nie, nachdem Sie es gestartet haben. Esgibt wieder und wieder “Hallo, Welt” aus. Sie können es auf die harteTour unterbrechen, indem Sie die Tastenkombination Ctrl+c bzw. Strg+cverwenden.

01 public class DemoWhile2 {02 public static void main( String[] args )03 {04 while( true )05 System.out.println("Hallo, Welt");06 }07 }

Beispiel: Das folgende Programm gibt die Zahlen von 1 bis 10 auf denBildschirm aus. Es verwendet dazu eine Zählervariable. Es demonstriertaußerdem, daß die Schleifenanweisung auch ein Block sein kann.

01 public class DemoWhile3 {02 public static void main( String[] args )03 {04 int i = 1;04 while( i <= 10 ) {05 System.out.println(i);06 i++;07 }07 }08 }

Man könnte das obige Programm auch noch kompakter schreiben, indemman den Inkrement–Operator in den Ausgabe–Befehl schreibt:

01 public class DemoWhile4 {02 public static void main( String[] args )03 {04 int i = 1;04 while( i <= 10 )05 System.out.println(i++);06 }07 }

68

Page 69: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Eine weitere Variante des vorigen Programmes ist lehrreich. Wir könnendie Variable i auch innerhalb der Schleifenbedingung inkrementieren. Da-bei müssen wir aber darauf achten, daß die Schleifenbedingung schon vormersten Durchlauf der Schleife einmal ausgeführt wird.Auch das folgende Programm gibt die Zahlen 1 bis 10 aus. Machen Sie sichdas klar ! Achten Sie vor allem darauf, daß nun in der Schleifenbedingungein echtes kleiner und nicht ein kleiner–gleich–Zeichen steht.

01 public class DemoWhile4 {02 public static void main( String[] args )03 {04 int i = 0;04 while( i++ < 10 )05 System.out.println(i);06 }07 }

9.7.2 Die Do–Schleife

Die do–Schleife arbeitet so ähnlich wie die while–Schleife. Sie hat die Form

doanweisung;

while ( Schleifenbedingung );

Sie unterscheidet sich von der while–Schleife dadurch, daß der Schleifenkörperin jedem Fall mindestens einmal durchlaufen wird.Genau wie bei der while–Schleife wird nach jedem Durchlauf des Schleifenkör-pers die Schleifenbedingung geprüft. Immer wenn die Bedingung true ergibt,wird die Schleife erneut durchlaufen.

Beispiel: Im folgenden Programm wird der Schleifenkörper genau einmaldurchlaufen und dabei “Hallo, Welt” ausgegeben. Da die Schleifenbedin-gung immer false ist, wird die Schleife danach nicht weiter ausgeführt.

01 public class DemoDo1 {02 public static void main( String[] args )03 {04 do05 System.out.println("Hallo, Welt");06 while( false );07 }08 }

Beispiel: Im folgenden Programm wird der Schleifenkörper immer wie-der einmal durchlaufen und dabei “Hallo, Welt” ausgegeben, da Schleifen-bedingung immer true ist. Das Programm unterscheidet sich im Resultatnicht von der vorhin besprochenen while–Endlosschleife.

01 public class DemoDo2 {02 public static void main( String[] args )03 {

69

Page 70: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

04 do05 System.out.println("Hallo, Welt");06 while( true );07 }08 }

Beispiel: Das folgende Programm gibt die Zahlen von 1 bis 10 aus.Beachten Sie den feinen Unterschied zum äquivalenten Programm mitwhile–Schleife (class DemoWhile4) aus dem vorigen Abschnitt. MachenSie sich klar, warum hier nicht mit i=0 sondern mit i=1 begonnen wird.

01 public class DemoWhile4 {02 public static void main( String[] args )03 {04 int i = 1;04 do {05 System.out.println(i);06 } while ( i++ < 10 );07 }07 }

Man kann while– in do–Schleife ineinander umschreiben. Eine do–Schleife derForm

doanweisung;

while( Schleifenbedingung );

kann als while–Schleife äquivalent so geschrieben werden:

anweisung;while ( Schleifenbedingung )

anweisung;

Eine while–Schleife der Form

while ( Schleifenbedingung )anweisung;

kann als äquivalente do–Schleife so geschrieben werden:

if ( Schleifenbedingung ) {do

anweisung;while( Schleifenbedingung);

}

9.7.3 Die For–Schleife

Die For–Schleife ist die wohl am häufigsten verwendete Schleife. Während diewhile– und do–Schleife meist dann eingesetzt werden, wenn man beim Beginn

70

Page 71: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

der Schleifenabarbeitung noch nicht genau sagen kann, wie oft die Schleifedurchlaufen werden soll, setzt man die for–Schleife meist dann ein, wenn manschon vor Beginn der Schleife weiß, wie oft die Schleife durchlaufen werden soll.Meist wird die for–Schleife dazu eingesetzt, eine Variable einen gewissen Wer-tebereich durchlaufen zu lassen.Sie hat die Form

for (init; test; update)anweisung;

In den runden Klammern hinter dem for–Befehl werden drei durch Semikoligetrennte Ausdrücke erwartet.Wie eine for–Schleife arbeitet, wird am besten klar, indem wir sie in eine äqui-valente while–Schleife umschreiben. Die for–Schleife kann man als Abkürzungfür die folgende Schleife interpretieren:

init;while( test) {

anweisung;update;

}

Der erste Teil in den runden Klammern (init) wird vor dem Start der Schleifeausgewertet. Er dient meist dazu, in der Schleife benötigte Variablen zu definie-ren oder zu initialisieren.Folgende Anweisungen und Ausdrücke sind hier erlaubt:

• “init” darf ein Ausdruck sein, wie in folgendem Beispiel:

for( i=0; i < 10; i++)System.out.println(i);

• “init” darf eine Liste von Ausdrücken sein, die dann durch Kommata ge-trennt sein müssen, wie in diesem Beispiel:

for(i=0, j=0 ; i < 10; i++, j+=i ) {System.out.println(i);System.out.println(j);

}

• “init” darf eine Variablendefinition sein:

for(int i=0 ; i < 10; i++)System.out.println(i);

Eine so definierte Variable ist nur innerhalb der for–Anweisung gültig.Daher ist der folgende Programmtext gültiger Java–Code:

for(int i=0 ; i < 10; i++)System.out.println(i);

for(double i=0.5 ; i < 10.5; i++)System.out.println(i);

71

Page 72: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

• “init” darf leer sein:

for( ; false; ) ;

Der zweite Ausdruck (test–Ausdruck) muß boolschen Datentyp haben. Er wirdausgewertet, um zu prüfen, ob die Schleife durchlaufen werden soll. Währendder test–Ausdruck true ergibt, wird die Schleifenanweisung immer wieder aus-geführt.Nach jedem Ausführen der Schleifenanweisung wird der update–Teil in denrunden Klammern ausgewertet. Dabei darf “update” ein Ausdruck oder einedurch Kommata getrennte Liste von Ausdrücken sein (siehe Beispiele oben).Im “update”–Teil werden meist mit Hilfe von Inkrement–Operatoren Variablenverändert. Der update–Ausdruck darf leer sein.

Beispiel: Das folgende Programm gibt die Zahlen von 1 bis 10 aus.

01 public class DemoFor1 {02 public static void main( String[] args )03 {04 int i;05 for(i=1 ; i <= 10 ; i++ )06 System.out.println(i);07 }08 }

Beispiel: Auch das folgende Programm gibt die Zahlen von 1 bis 10 aus.Es empfiehlt sich, die Variablendefinition in die Initialisierungsanweisungzu schreiben.

01 public class DemoFor2 {02 public static void main( String[] args )03 {04 for(int i=10 ; i <= 100 ; i+=10 )05 System.out.println(i / 10 );06 }07 }

Beispiel: Das folgende Programm gibt die Zahlen von 1 bis 10 rückwärtsaus:

01 public class DemoFor3 {02 public static void main( String[] args )03 {04 for(int i=10; i > 0 ; i-- )05 System.out.println(i);06 }07 }

Beispiel: In diesem Programm wird die Anweisung in Zeile 05 niemalsausgeführt, da die Schleifenbedingung in Zeile 04 immer false ist.

72

Page 73: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

01 public class DemoFor4 {02 public static void main( String[] args )03 {04 for( ; false ; )05 System.out.println("Hallo, Welt");06 }07 }

Beispiel: Dies ist eine Endlosschleife, da die Schleifenbedingung immertrue ist — es wird immer wieder der Text “Hallo, Welt” ausgegeben.

01 public class DemoFor5 {02 public static void main( String[] args )03 {04 for( ; true ; )05 System.out.println("Hallo, Welt");06 }07 }

Beispiel: Oft verschachtelt man mehrere Schleifen ineinander. Das fol-gende Programm gibt eine dreieckige Figur aus. Dazu verwenden wir dieMethode “System.out.print”. Diese arbeitet genauso wie die “println”–Methode, beginnt aber nicht nach jeder Ausgabe mit einer neuen Zeilesondern gibt aufeinanderfolgende Ausgaben hintereinander in der gleichenZeile aus.

01 public class DemoFor6 {02 public static void main( String[] args )03 {04 for(int i=1 ; i <= 10 ; i++ ) {05 for(int j = 1; j <= i ; j++ ) {06 System.out.print("*");07 }08 System.out.println(); // neue Zeile beginnen09 }10 }11 }

Beispiel: Sie können in einer for–Schleife beliebige Variablen als Kon-trollvariablen verwenden, nicht nur int–Variablen. Wir demonstrieren hieraußerdem die Verwendung mehrerer Update–Ausdrücke.Das Programm gibt 6–Mal die Zahl 5.0 aus.

public class DemoFor7 {public static void main( String[] args ){

int i = 5;for(double d=0 ; d <= 5 ; d++, i-- ) {

System.out.println(d + i);}

}}

73

Page 74: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

9.7.4 break und continue

Bitte lesen Sie die Ausführungen zu break und Continue in Go To Java, Kapitel6.3 nach.

74

Page 75: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

9.8 Zusammenfassung

Sie müssten nun die folgenden Fragen beantworten können:

B Was ist ein Block ?B Wieso darf man in Java auch mehr als ein Semikolon zum Abschluß

eines Befehls verwenden ?B Was für einfache Anweisungen kennen Sie ?B Erklären Sie, wo eine einmal definierte Variable überall verwendet wer-

den darf — was ist ihr Gültigkeitsbereich ?B Können sich Variablendefinitionen in Java gegenseitig verdecken ?B Nennen Sie Beispiele für Ausdrucksanweisungen !B Welche Beziehung gibt es zwischen Variablendefinitionen und

Blöcken ?B Was ist ein Dangling Else ?B Wie kann man ein Dangling Else vermeiden ?B Welche Schleifen kennen Sie ?B Wie werden do–Schleifen aufgebaut ?B Wodurch unterscheiden sich do und while–Schleife ?B Was ist eine Endlosschleife ?B Wie kann man ein Programm unterbrechen, das in einer Endlosschleife

hängt ?B Geben Sie ein Beispiel für eine Endlosschleife !B Wie kann man eine Do in eine While–Schleife umschreiben ?B Wie kann man eine While– in eine Do–Schleife umschreiben ?B Wie kann man eine for–Schleife in eine while–Schleife umschreiben ?B Wie muß eine For–Schleife aufgebaut sein ?B Wie kann der init–Teil einer For–Schleife aussehen ?B Wenn eine for–Schleife verwendet wird, um eine Variable einen gewis-

sen Zahlenbereich durchlaufen zu lassen — wo sollte diese Variabledefiniert werden ?

B Schreiben Sie ein Programm, das rückwärts von 10 bis 1 zählt – einmalmit einer do–Schleife, einmal mit einer for– und einmal mit einer while–Schleife.

10 Objekte in JavaSie kennen nun die sogenannten imperativen Bestandteile von Java: Variablen,Verzweigungen und Schleifen. Unser nächstes Ziel ist, Ihnen die objektorientier-ten Bestandteile zu vermitteln.In Kapitel ?? wurde unabhängig von Java erläutert, was Klassen und Objektesind. Wenn Ihnen die Inhalte nicht mehr geläufig sind, lesen Sie es bitte nocheinmal.Genau wie in Kapitel ?? beschrieben, ist auch in Java ein Objekt etwas, das einen

75

Page 76: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Zustand, eine Schnittstelle und Verhalten besitzt. Der Zustand eines Objektesergibt sich aus seinen Attributen oder Variablen. Seine Schnittstelle und seinVerhalten ist durch die in seiner Klasse beschriebenen Methoden definiert.In diesem Kapitel soll nur gezeigt werden, wie man Objekte in Java benutzenkann, welchen Lebenszyklus ein Objekt hat und wie sich Objekte von den Ihnenbisher bekannten Datentypen wie int oder float unterscheiden.Um ein Objekt zu erzeugen, muß zunächst seine Klasse definiert sein. Wie maneigene Klassen definiert, soll erst in Kapitel 12 beschrieben werden. Um dasVerhalten von Objekten zu demonstrieren, werden wir in diesem Kapitel einevon Java bereitgestellte Klasse verwenden.

10.1 Objekte und primitive Datentypen

Bisher haben Sie mit den primitiven Datentypen von Java und mit Stringsgearbeitet. Die primitiven Datentypen (sie fangen mit einem kleinen Buchstabenan) sind:

boolean, char, byte, short, int, long long, float, double

Primitive Datentypen sind also die logischen Datentypen, Zeichen sowie allebisher benutzten Zahlen. Primitive Datentypen heißen so, da man als Program-mierer selbst keine primitiven Datentypen definieren kann — alle primitiven Da-tentypen sind von den Java–Schöpfern fest eingebaut worden. Vielleicht kommtdiese Benennung aber auch daher, daß primitive Daten im Vergleich mit Objek-ten so “primitiv” sind.Primitive Datentypen sind keine Klassen (wir erklären gleich einige Konsequen-zen), und darum sind ihre Werte und Variablen auch keine Objekte.Alle primitiven Datentypen haben gemeinsam, daß man die möglichen Werteeines primitiven Datentyps durch Literale angegeben kann:

Beispiel: Angabe einiger Werte primitiver Datentypen durch Literale.

int i = 1;char c = ’a’;double f = 4.2390823;

Sie haben auch schon Objekte und Klassen kennengelernt, ohne daß Sie es wus-sten. Zeichenketten sind nämlich keine primitiven Datentypen sondern Objekteder Klasse String. Da wir bisher nur wenige Fähigkeiten von Strings benutzthaben, konnten Sie aber bisher vermutlich noch keinen Unterschied zwischenStrings und den primitiven Datentypen feststellen. In diesem Kapitel wird sichdas etwas ändern.Objekte kann man in der Regel nicht durch Literale erzeugen. Strings und Ob-jekte der in Kapitel 11 behandelten Array–Klassen bilden hier die große Aus-nahme. Die Java–Erfinder waren sich darüber im klaren, daß Strings unheimlichhäufig verwendet werden und haben daher die Möglichkeit geschaffen, Stringsdurch Literale zu erzeugen.

Beispiel: Hier werden einige Objekte der Klasse String erzeugt:

76

Page 77: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

String einString = "Hallo, Welt";String name = "Homer";String wunsch = "Pizza";

Einen prinzipiellen Unterschied zwischen Klassen und primitiven Datentypenkönnen Sie vermutlich immer noch nicht erkennen. Vielleicht fällt Ihnen abereine ganz banale Sache fällt auf: Die primitiven Datentypen werden alle kleinge-schrieben, der erste Buchstabe der String–Klasse hingegen wird großgeschrieben.Eigentlich ist es Java egal, ob Klassennamen mit einem großen oder einem klei-nen Buchstaben beginnen. Es ist aber üblich, alle Klassennamen mit einemGroßbuchstaben beginnen zu lassen. Bitte merken Sie sich das: Alle Klassen-namen sollten mit einem Großbuchstaben beginnen.Primitive Daten und Objekte unterscheiden sich durch das, was man mit ih-nen anstellen kann. Den wichtigsten Unterschied können wir Ihnen hier leidernoch nicht erklären, da Sie vermutlich noch nicht wissen, was wir unter Verer-bung verstehen. Für die fortgeschritteneren Leser sei hier erwähnt, daß man vonprimitiven Datentypen nicht erben kann und daß primitive Datentypen keineExtension einer anderen Klasse sind.Einen fast genauso wichtigen Unterschied zwischen Objekten und primitivenDaten werden Sie in diesem Kapitel aber noch kennenlernen: Während primiti-ve Daten in einer Variablen gespeichert werden, ist eine Variable, in der Objektegespeichert werden, nur ein Verweis auf ein Objekt. Objekte haben im Unter-schied zu primitiven Daten eine Identität (dazu mehr in Abschnitt 10.3).Einen weiteren Unterschied zwischen Objekten und primitiven Daten könnenwir Ihnen hier schon demonstrieren. Sie erinnern sich sicher, daß wir in Kapitel?? geschrieben haben, daß Objekte Verhalten und einen Zustand haben und daßObjekte miteinander kommunizieren können.Primitive Daten haben hingegen nur einen Zustand. Sie sind nicht aktiv und be-sitzen weder eine Schnittstelle noch Verhalten. Man kann mit primitiven Datenzwar rechnen oder sie verwenden, man kann primitiven Daten jedoch keine Bot-schaften schicken. Kurz gesagt: Primitive Daten sind nichts als dumme Datenohne Eigenleben.Einen ersten Eindruck vom Unterschied zwischen primitiven Daten und Ob-jekten liefert das folgende Beispiel. Es demonstriert, wie man String–ObjektenBotschaften schicken kann.

Beispiel: Im folgenden Beispiel erzeugen wir einige String–Objekte undschicken ihnen dann Botschaften.

Klasse StringBotschaften

1 class StringBotschaften {2 public static void main( String[] args ) {3 String name = "Homer Simpson";4 String wunsch = new String("Pizza");5 System.out.println( "Bart Simpson".substring(0,4) );6 System.out.println( name.substring(0,5) );7 System.out.println( name.length() );8 System.out.println( name.concat(" will ").concat( wunsch ) );9 }

10 }

In Zeile 3 des Beispiels wird ein neues String–Objekt erzeugt, welches

77

Page 78: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

danach über die String–Variable name angesprochen werden kann.Auch in Zeile 4 wird ein String–Objekt erzeugt, welches den Text "Pizza"enthält. Hier wird das Objekt jedoch nicht einfach durch Angabe desString–Literals sondern durch Verwendung des new–Operators erzeugt.Der new–Operator wird normalerweise immer benötigt, um ein Objekteiner Klasse zu erzeugen. Da Strings auch durch Literale erzeugt werdenkönnen, kann man auf den new–Operator bei Strings aber meist verzich-ten.In Zeile 5 wird demonstriert, wie man an ein Objekt eine Botschaftschicken kann. Hier wird an das String–Objekt "Bart Simpson" die Bot-schaft substring(0,4) geschickt. Das String–Objekt liefert daraufhin einString–Objekt zurück, das seine ersten vier Buchstaben, also den Text"Bart", enthält. In Zeile 6 wird auf die gleiche Weise ein String–Objekterzeugt, das die ersten 5 Buchstaben des durch name bezeichneten Ob-jektes enthält.In Zeile 7 wird an das durch name bezeichnete Objekt die Botschaftlength() geschickt. Daraufhin liefert das Objekt die Länge des enthal-tenen Textes.In Zeile 8 wird an das durch name bezeichnete Objekt die Bot-schaft concat(" will ") geschickt. Die Botschaft concat veranlaßtein String–Objekt, ein neues Objekt zu erzeugen, indem es das inder concat–Botschaft mit übergebene Objekt an sich selbst anhängt.Das "Homer Simpson"–Objekt erzeugt also das neue String–Objekt"Homer Simpson will ".An dieses String–Objekt wird dann die Botschaft "concat(wunsch)" ge-schickt, woraufhin das String–Objekt "Homer Simpson will Pizza" er-zeugt wird.

An primitive Daten kann man keine Botschaften schicken. Beispielsweise gibtes keine Methode der ganzen Zahlen, die man als

int a;a.tueWas(); // gibts nicht5.quadrieren(); // auch ein Fehler

aufrufen könnte.

10.2 Der Lebenszyklus eines Objektes

Primitive Daten brauchen nicht erst irgendwie erzeugt zu werden. Sie werdendurch Literale gegeben und besitzen keinen Lebenszyklus.Bei Objekten sieht das anders aus — sie haben einen gewissen Lebenszyklus:Bevor man ein Objekt verwenden kann, muß es erzeugt werden. Während seinerLebensdauer kann es mit anderen Objekten kommunizieren, und wenn es nichtmehr benötigt wird, wird es zerstört.

10.2.1 Die Erzeugung von Objekten

Die Erzeugung eines Objektes geschieht durch Anwendung seines Bauplanes.Seine Klasse wird als Muster genommen, um die Attribute des Objektes, seineSchnittstelle und sein Verhalten zu definieren.

78

Page 79: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Die Objekterzeugung geht so vor sich, daß zunächst Speicherplatz für das Ob-jekt bereitgestellt wird. Diesen Speicherplatz können Sie sich als eine Sammlungvon Variablen vorstellen: Ein Objekt ist eine Art Container, in dem einige Va-riablen enthalten sind. Dabei entspricht jedes in der Klasse definierte Attributeiner Variable. Die Variablen, die zu einem Objekt gehören, nennt man auchInstanzvariablen, und der Zustand eines Objektes bestimmt sich aus den Zu-ständen seiner Instanzvariablen.Als erster Schritt wird also das Objekt mitsamt den enthaltenen Variablen an-gelegt. Da neu angelegte Variablen normalerweise einen undefinierten Zustandhaben und Objekte mit nicht definiertem Zustand in der Regel unerwünschtsind, wird anschließend ein in der Klasse definiertes Initialisierungsverhaltenausgeführt, welches den Instanzvariablen bestimmte Werte zuweist.Dieses Initialisierungsverhalten wird in einer oder mehreren Methoden beschrie-ben, welche man in der objektorientierten Methodik als Konstruktoren be-zeichnet. Man kann in Java das Anlegen und das Initialisieren des Objektesnicht voneinander trennen, insofern empfiehlt es sich davon zu sprechen, daßder Konstruktor ein Objekt erzeugt und initialisiert.Einem Konstruktor können auch zusätzliche Daten mitgegeben werden, die zurInitialisierung verwendet werden. KonstruktorDefinition: Konstruktor

Ein Konstruktor ist eine Methode, welche ein Objekt erzeugt und da-bei seinen anfänglichen Zustand initialisiert. Eine Klasse kann meh-rere Konstruktoren für ihre Objekte definieren.

Jede Klasse erhält automatisch einen Standardkonstruktor. Daher ist es nichtunbedingt nötig, in eigenen Klassen einen Konstruktor vorzusehen.Welcher Konstruktor in einer Klasse mit mehreren Konstruktoren beim Er-zeugen eines Objektes benutzt wird, wird durch die Art der Objekterzeugungfestgelegt (genaueres dazu werden Sie in Kapitel 12 erfahren).Der Standardkonstruktor einer Klasse kann man aufrufen, indem man den Aus-druck

new Klasse()

verwendet. Allgemeiner geschieht die Erzeugung eines Objektes durch einen Aus-druck der Form

new Klasse( argument1, argument2, ..., argumentN )

Dabei sind argument1 bis argumentN Argumente, die zur Initialisierung desObjektes benutzt werden. Als Konstruktor wird ein solcher gewählt, der zu denangegebenen Argumenten paßt (falls es in der Klasse keinen solchen Konstruktorgibt, wird ein Kompilierfehler erzeugt). Was das genau bedeutet, erfahren Siein Kapitel 12.

Beispiel: Ein String kann außer per Literal auch per Konstruktor erzeugtwerden.

1 String string1 = new String();

79

Page 80: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

2 String string2 = "Andreas";3 String string3 = new String("Hallo, Welt");4 String string4 = new String( string3 );

Im obigen Beispiel wird in Zeile 1 ein String durch den Standardkonstruk-tor erzeugt (new String()). In der String–Klasse ist festgelegt, daß dieserKonstruktor den leeren String "" erzeugt.Der durch string2 bezeichnete String wird durch das String–Literal auto-matisch erzeugt — immer wenn der Java–Compiler ein String–Literal ent-deckt, fügt er automatisch einen entsprechenden Konstruktoraufruf zumErzeugen eines String–Objektes ein.In Zeile 3 wird ein String durch einen Konstruktor erzeugt, der als Ar-gument einen String entgegennimmt. Es wird daraufhin ein neuer Stringerzeugt, der eine Kopie des Strings "Hallo, Welt" enthält.In Zeile 4 wird ein String erzeugt, der eine Kopie des Strings string3enthält.

Hier noch ein Beispiel mit einer selbstgebauten Klasse:

Beispiel: Angenommen, es sei eine Klasse Kind gegeben, welche ein Kinddurch seinen Namen und sein Alter repräsentiert. Die Klasse könnte wiefolgt definiert sein:

1 class Kind {23 // Instanzvariablen eines Kindes:4 String name;5 int alter;67 // Konstruktor:8 public Kind( String neuerName, int neuesAlter ) {9 name = neuerName;

10 alter = neuesAlter;11 }12 }

In Zeile 4 und 5 sind zwei Attribute, name und alter definiert. In Zeile8–11 ist eine Methode definiert, deren Name gleich dem Klassennamenist. Dies ist ein Konstruktor.Wenn ein neues Kind erzeugt werden soll, könnte der Konstruktor wiefolgt aufgerufen werden:

Kind einKind = new Kind( "Bart Simpson", 12 );

Hier wird zunächst ein neues Kind–Objekt erzeugt, welches die beidenVariablen name und alter enthält. Anschließend wird der Konstruktor derKlasse (Zeile 8–11) ausgeführt. Der Konstruktor initialisiert daraufhin dasAttribut name zu "Bart Simpson" und das Attribut alter zu 12.Sie sehen an diesem Beispiel, daß ein Konstruktor eigentlich nichts anderesals eine Methode mit besonderem Namen ist.

80

Page 81: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

10.3 Die Identität eines Objektes

Nachdem wir ein Objekt erzeugt haben, wollen wir es verwenden. Dazu müssenwir das Objekt identifizieren können — wir benötigen also einen Namen, unterdem wir es ansprechen können.Genau wie bei primitiven Datentypen verwenden wir auch für Objekte Varia-blen. Es gibt dabei jedoch einen großen Unterschied: Während primitive Datenin einer Variable gespeichert werden, wird ein Objekt durch eine Variablenur referenziert.Um primitive Daten in einer Variable zu speichern, verwendet man den Zu-weisungsoperator. Auch bei der Zuweisung von Objekten verwendet man denZuweisungsoperator. Er bewirkt hier aber nicht, daß eine Kopie angelegt wirdsondern daß die zugewiesene Variable danach das Objekt referenziert. Es istdurchaus möglich, daß mehrere Variablen das gleiche Objekt referenzieren.Bitte merken Sie sich: Durch die alleinige Verwendung des Zuweisungs-operators wird kein neues Objekt erzeugt.

Beispiel: Im folgendenProgrammfragment werden Zahlen in Variablengespeichert.

int i = 1; // speichere die Zahl 1 in iint j = i; // speichere die Zahl 1 in jdouble f = 3.141;// speichere 3.141 in f

Die Situation nach der Ausführung dieses Programmfragments könnteman wie folgt darstellen: Zu jeder Variable gehört ein gewisser Teil desSpeichers, in welchem der Wert der Variable gespeichert ist:

int i 1

int j 1

double f 3.141

Beispiel: Nun soll demonstriert werden, wie Zuweisungsoperatoren aufObjekte wirden. In Zeile 3 wird ein String–Objekt erzeugt und durch dieVariable name referenziert.In Zeile 4 wird eine weitere String–Variable definiert und verweist nachder Zuweisung auf das gleiche Objekt wie die Variable name. Durch dieZuweisung in Zeile 4 wird kein neues Objekt erzeugt !In Zeile 5 hingegegen wird durch Verwendung des new–Operators ein neu-es String–Objekt erzeugt, welches eine Kopie des durch Name name refe-renzierten Strings enthält. Dies Objekt wird dann durch n2 referenziert.

81

Page 82: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Klasse ReferenzDemo

1 class ReferenzDemo {2 public static void main( String[] args ) {3 String name = "Hallo, Welt";4 String n1 = name;5 String n2 = new String( name );6 System.out.println( n1 == name );7 System.out.println( n2 == name );8 }9 }

Die Situation nach Ausführung der Zuweisungen kann hier wie folgt gra-phisch dargestellt werden: Es gibt zwei String–Objekte mit gleichem In-halt. Eines wird durch die Variablen name und n1 referenziert, und dasandere wird durch die Variable n2 referenziert:

String n1

String name

String n2 referenziert

referenziert

referenziert String−Objekt

Zustand: "Hallo, Welt"

String−Objekt

Zustand: "Hallo, Welt"

In Zeilen 6 und 7 des vorigen Beispiels verwenden wir den == Operator. Bis-her haben Sie vermutlich gedacht, daß der ==–Operator zwei Ausdrücke aufGleichheit prüfe. Das stimmt aber so nicht ganz: der ==–Operator prüft, obzwei Ausdrücke identisch sind.Zwei primitive Daten mit gleichem Wert sind auch identisch. Zwei Variablen,die Objekte referenzieren, sind hingegen nur dann identisch, wenn sie beide aufdas gleiche Objekt verweisen. In Zeile 6 des vorigen Beispiels wurde daher trueund in Zeile 7 false ausgegeben. Gleichheit

undIdentität

Um das nochmal ganz deutlich zu machen: Wir unterscheiden zwischen Gleich-heit und Identität. Zwei Objekte sind gleich, wenn sie den gleichen Zustandhaben. Zwei Objekte sind identisch, wenn sie beide das gleiche Objekt sind.Im obigen Beispiel sind die durch name und n2 referenzierten Objekte gleich, dasie beide den Text "Hallo,Welt" enthalten. Hingegen sind name und n2 nichtidentisch, da sie auf unterschiedliche Objekte verweisen.Die Identität eines Objektes ist unabhängig von seinem Zustand. Auch wennsich der Zustand eines Objektes ändert, bleibt seine Identität erhalten.Es ist möglich, daß zwei nicht–identische Objekte den gleichen Zustand haben.Es ist aber nicht möglich, daß zwei identische Objekte unterschiedliche Zuständehaben.Bitte merken Sie sich folgendes: Identität

82

Page 83: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Identität:

Jedes Objekt hat Identität — die Identität existiert unabhängig vonNamen, mit denen wir das Objekt bezeichnen. Die Identität einesObjektes ändert sich vom Beginn seines Lebenszyklus bis zur Zer-störung nicht. Sie ändert sich auch nicht, wenn wir den Zustand desObjektes verändern.

Übrigens bestimmt Java, ob zwei Objekte identisch sind, indem es nachschaut,an welcher Stelle im Speicher sie gespeichert sind. Identisch sind genau diejeni-gen Objekte, die an gleichen Speicherstellen liegen.Oft möchte man verhindern, daß zwei nicht–identische Objekte mit gleichemZustand existieren. In diesem Fall muß man das durch einen geeigneten Mecha-nismus sicherstellen.

Beispiel: Es ist denkbar, daß zwei verschiedene Studenten den gleichenNamen haben. Will eine Universität verschiedene Studenten auseinander-halten, eignet sich der Name also nicht zur Identifizierung.Aus diesem Grund wird jedem Studenten eine eindeutige Immatrikula-tionsnummer gegeben. Eine Verfahrensvorschrift bei der Immatrikulationstellt sicher, daß jede Immatrikulationsnummer nur einmal vergeben wird.Die Immatrikulationsnummer ist aus Sicht der Universität also die Iden-tität des Studenten.

10.4 Die Kommunikation mit Objekten

Nachdem ein Objekt erzeugt wurde, können wir mit ihm kommunizieren. Wirkönnen es durch das Zusenden von Botschaften zu einem gewissen Verhaltenveranlassen, und es kann selbst Botschaften an andere Objekte verschicken.Um einem Objekt eine Botschaft zu schicken, müssen wir eine Referenz aufdas Objekt kennen. Wir können ihm nur Botschaften schicken, die es versteht.Welche Botschaften ein Objekt versteht und wie diese Botschaften aufgebautsein müssen, ist in seiner Klasse beschrieben.Nochmal zur Erinnerung: Den Aufbau von Methoden definieren wir in derSchnittstelle der Klasse wie folgt:

Klasser methodenName(Klasse1 e1, . . . ,Klassen en)

Wenn wir nun ein Objekt auffordern wollen, eine Methode auszuführen, schickenwir ihm eine Botschaft, deren Aufbau genau dieser Beschreibung entspricht.Wenn eine Methode kein Ergebnis zurückliefert, schreiben wir die Aufforderungan das Objekt einObjekt die Methode methodenName auszuführen, wie folgt:

einAusfuehrer.methodenName(eingabe1, . . . , eingaben)

Dabei übergeben wir wir soviele zusätzliche Objekte eingabe1, . . . , eingaben, wiein der Schnittstelle beschrieben. Das Objekt eingabei muß dabei Mitglied derKlasse Klassei sein.Wenn die Methode ein Ergebnis liefert, können wir dieses Ergebnis abholen.Dazu benötigen wir ein Objekt ergebnis der Klasse Klasser. Wir schreiben indiesem Fall:

83

Page 84: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

ergebnis = einAusfuehrer.methodenName(eingabe1, . . . , eingaben).

Beispiel: Zum Beispiel ist in der String–Klasse die Methode length de-finiert, welche die Länge eines Strings zurückgibt. Sie nimmt keinen wei-teren Parameter entgegen und liefert eine int–Zahl zurück.Die Länge eines Strings kann man daher ermitteln, indem man dem Stringdie Botschaft length() schickt:

String meinString = "Ein Text";int laenge = meinString.length();int laenge1 = "Noch ein Text".length();

Bisher haben wir uns das Bild gemacht, daß wir mit Objekten kommunizieren,indem wir ihnen Botschaften schicken. Dieses Bild ist auch weiterhin richtig, undes entspricht hervorragend der objektorientierten Denkweise. Es ist nun leideran der Zeit, diese Denkweise ein wenig an Java anzupassen.In Java bedeutet der Punkt nach dem Objektnamen eigentlich nicht das Ver-schicken einer Botschaft. Vielmehr hat man in Java die Vorstellung, daß einObjekt ein Container ist, welcher Instanzvariablen und Methoden enthält. Aufdie in einem Objekt enthaltenen Dinge kann man dann zugreifen, indem man

objekt.enthaltenesDing

schreibt. Der Punkt dient also sozusagen dazu, das Objekt aufzumachjen und aufdie enthaltenen Dinge zuzugreifen. Insofern paßt die Vorstellung, man schicke ei-nem Objekt Botschaften nicht hundertprozentig zu Java. Man kann die Schreib-weise

objekt.methode()

auch als den Aufruf einer im Objekt enthaltenen Methode verstehen. Natür-lich ist diese Vorstellung äquivalent zur Vorstellung, daß wir dem Objekt eineBotschaft schicken.Man kann den Punkt auch verwenden, um auf Instanzvariablen eines Objekteszuzugreifen, und hier hört die Analogie zum Verschicken von Botschaften auf.Weiter oben hatten wir ein Beispiel mit einer Kind–Klasse. Wir können auf dieAttribute eines Kindes dieser Klasse wie folgt zugreifen:

Kind einKind;einKind.name = "Bart Simpson";einKind.alter = 12;

Hier dient der Punkt also tatsächlich dazu, auf die in einem Objekt enthaltenenVariablen zuzugreifen.Vielleicht sollten wir daher in Zukunft lieber davon reden, daß ein Objekt Me-thoden enthalte, und daß wir, statt dem Objekt eine Botschaft zu schicken, eineim Objekt enthaltene Methode aufrufen. Vermutlich werden wir in Zukunft bei-de Sprechweisen verwenden — sie sind schließlich äquivalent. Das Schicken vonBotschaften scheint dabei auch immer noch anschaulicher, auch wenn es nichtso hundertprozentig zur Java–Philosophie paßt.

84

Page 85: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

10.5 Welche Botschaften versteht ein Objekt ?

Wenn Sie selbst eine Klasse schreiben, wissen Sie natürlich, welche Methodenenthalten sind. Wie aber können Sie erfahren, welche Methoden fremde Klassenenthalten ?Zu Java gehört eine ganze Menge an Dokumentation. Sämtliche in Java ent-haltenen Klassen sind in der Dokumentation des JDK (Java Development Kit)beschrieben. Wie diese Dokumentation genau aufgebaut ist, erklären wir Ihnen,sobald wir Klassen (Kapitel 12) und Pakete (Kapitel 15) besprochen haben.In den folgenden Hausaufgaben und in den weiteren Texten werden Sie häufigmit dieser Dokumentation arbeiten müssen. Hier soll Ihnen die Verwendung derJDK–Dokumentation anhand eines Beispiels demonstriert werden:

Beispiel: Die Dokumentation zur String–Klasse finden Sie auf derWWW–Seite

http://www.tu-bs.de:82/wir/EIP/jdk1.1.8/docs/api/java.lang.String.html

Bitte klicken Sie sich dorthin, indem Sie von unseren WWW–Seiten un-ter den Litaturlinks zu Java auf den relativ weit unten stehenden Link“Java–Api (lokal)” klicken. Sie gelangen dann auf eine Seite, auf der eini-ge sogenannte “packages” aufgelistet sind.Dort klicken Sie bitte auf den als java.lang bezeichneten Link. Anschlie-ßend erhalten Sie eine Liste von Klassen, unter denen sich auch die KlasseString befindet.Wenn Sie nun auf den String betitelten Link klicken, gelangen Sie zu deroben genannten WWW–Seite.Auf dieser WWW–Seite sind alle Methoden beschrieben, die String–Objekte verstehen. Bitte lesen Sie den kompletten ersten Teil der Seitedurch und schauen Sie sich unter der Überschrift “Method Index” dieMethode charAt an. Wenn Sie darauf klicken, sollten Sie die folgende Er-läuterung erhalten:

public char charAt(int index)

Returns the character at the specified index. An indexranges from 0 to length() - 1.

Parameters:index - the index of the character.

Returns:the character at the specified index of this string.The first character is at index 0.

Throws: StringIndexOutOfBoundsExceptionif the index is out of range.

Sie erkennen, daß hier eine Methode namens charAt beschrieben wird,mit der man einen String auffordern kann, ein in ihm enthaltenes Zeichenzurückliefern.Beachten Sie, daß die Zeichen eines Strings mit 0 beginnend durchnume-riert werden. Das erste Zeichen eines Strings erhält man, also indem manihm die Botschaft charAt( 0 ) schickt.

85

Page 86: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Mit Hilfe der obigen Beschreibung können wir ein Programm schreiben,das alle Zeichen eines Strings einzeln ausgibt. Dazu rufen wir in einerSchleife wiederholt die String–Methode charAt auf und geben das durchden String zurückgegebene Zeichen mit der Methode System.out.printlnaus. Um die Länge des Strings zu ermitteln, schicken wir ihm die Botschaftlength(). Bitte sehen Sie sich auch die Dokumentation zur length–Methodean.

Klasse DemoStringMethods

1 class DemoStringMethods {2 static public void main( String[] args ) {3 String text = "Hallo, Welt";4 for( int i = 0; i < text.length(); i++ ) {5 System.out.println( text.charAt( i ) );6 }7 }8 }

10.6 Die Zerstörung von Objekten

Wenn ein Objekt nicht mehr benötigt wird, wird es zerstört und entsorgt. Da-bei wird der gesamte Speicherplatz, den das Objekt im Speicher belegt hatte,freigegeben.Glücklicherweise muß man sich als Programmierer in Java überhaupt nicht umdie Objektentsorgung kümmern. Java kann nämlich selbst erkennen, ob ein Ob-jekt noch benötigt wird oder nicht. Dazu enthält Java eine Funktion, die zwi-schendurch immer wieder mal automatisch gestartet wird und sich als “Müll-sammler” betätigt — diese Funktion heißt sehr treffend der Garbage Collec-tor14

Der Garbage Collector kann feststellen, auf welche der momentan existierendenObjekte Variablenreferenzen existieren. Immer wenn er ein Objekt entdeckt, dasdurch keine einzige Variable referenziert wird, sammelt er es ein und gibt den be-legten Speicherplatz für andere Objekte frei — er betreibt also Recycling, dennder so freigegebene Speicherplatz schafft Lebensraum im Speicher des Compu-ters für neue Objekte. Das tollste daran ist, daß Sie selbst sich überhaupt nichtum Ihre Müllentsorgung kümmern müssen — alle nicht mehr Objekte werdenvolautomatisch entsorgt.Vielleicht fragen Sie sich, ob das nicht etwas unsicher sei: Da kommt irgendsoein dahergelaufenes Programm und löscht einfach Ihre Objekte.Bedenken Sie aber, daß Sie ohnehin keine Möglichkeit haben, ein Objekt, dasSie nicht durch eine Variable referenziert haben, zu benutzen. Insofern kann derGarbage Collector keinen Schaden anrichten — er löscht niemals Objekte, aufdie Sie noch zugreifen können.Noch ein Hinweis: Es ist zwar möglich, den Garbage Collector von Hand zustarten. Nötig ist es aber meist nicht, da Java ihn ohnehin immer automatischstartet, wenn mehr Platz benötigt wird.Und noch ein Hinweis: Selbstverständlich werden nur Objekte gelöscht — beiprimitiven Daten ist das nicht nötig, da sie in einer Variable enthalten sind

14Garbage Collectoren sind übrigens keine Erfindung von Java — das in den 70ern ent-wickelte Smalltalk besaß bereits einen Garbage Collector.

86

Page 87: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

und ihre Lebensdauer daher durch die Lebensdauer der Variablen begrenzt ist.Objekte müssen nur deshalb gelöscht werden, da sie unabhängig von Variablenexistieren.

Beispiel: Im folgenden Programm werden in Zeile 3 und 4 zwei String–Objekte erzeugt.Die Zuweisung in Zeile 5 bewirkt, daß auf "String1" keine Referenz mehrexistiert. Daher kann "String1" nach Ausführung von Zeile 5 vom Gar-bage Collector gelöscht werden.In Zeile 6 wird a2 ein neues Objekt zugewiesen. Das Objekt "String2"darf jedoch noch nicht gelöscht werden, da es noch durch die Variable a1referenziert wird.Erst nach Ausführung von Zeile 7 wird das Objekt "String2" von kei-ner Variable mehr referenziert und kann vom Garbage Collector entsorgtwerden.

Klasse DemoGarbage

1 class DemoGarbage {2 public static void main() {3 String a1 = "String 1";4 String a2 = "String 2";5 a1 = a2;6 a2 = "String 3";7 a1 = "";8 }9 }

10.7 Zusammenfassung

Sie sollten nun die folgenden Fragen beantworten können:

87

Page 88: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

B Welche primitiven Datentypen kennt Java ?B Nennen Sie einige Unterschiede zwischen primitiven Datentypen und

Klassen !B Wie erzeugt man ein Objekt ?B Was ist ein Konstruktor ?B Beschreiben Sie, was Sie unter der Identität eines Objektes verstehen !B Enthalten Variablen Objekte ?B Was bewirkt der Zuweisungsoperator bei primitiven Daten ?B Was bewirkt der Zuweisungsoperator bei primitiven Objekten ?B Was bewirkt der ==–Operator bei primitiven Daten ?B Was bewirkt der ==–Operator bei Objekten ?B Was ist der Unterschied zwischen Gleichheit und Identität ?B Wie schickt man einem Objekt eine Botschaft ?B Wie kann man herausfinden, welche Methoden die Klasse String ent-

hält ?B Wie werden Objekte zerstört ?B Wie arbeitet der Garbage–Collector ?B Warum kann der Garbage–Collector keinen Schaden anrichten ?

11 ArraysBevor Sie lernen, selbst Klassen zu definieren, möchten wir Ihnen noch einenweiteren Typ von sehr wichtigen Objekten vorstellen: Arrays.Arrays sind Objekte, welche eine größere Anzahl von Zahlenwerten oder anderenDaten verwalten können. Sie können sich ein Array als eine durchnumerierteSammlung von Variablen vorstellen. Arrays sind die einfachste Möglichkeit, dieJava zur Verwaltung mehrerer gleichartiger Daten oder Objekte bietet.Arrays unterscheiden sich von allen anderen Objekten und Klassen in Java: DieArray–Klassen haben einen recht eigenartigen Namen, und auch die Konstruktor–Aufrufe von Arrays unterscheiden sich von normalen Konstruktor–Aufrufen.

11.1 Definition von Arrays

Ein Array ist ein Vektor gleichartiger Variablen. Die Klasse eines Arrays, inwelchem Variablen des Datentyps typ gespeichert werden können, ist typ[].Beispielsweise speichern Objekte der Klasse int[] einen Vektor von int–Werten,während Objekte der Klasse String[] einen Vektor String–Werten verwaltenkönnen.Eine Array–Klasse erhält man also, indem man hinter einen anderen Klassenna-men zwei eckige Klammern setzt. Diese merkwürdige Schreibweise ist praktisch,da sie sehr prägnant ist und für jede beliebige Klasse — auch für selbstent-wickelte Klassen — verwendbar ist.Eine Variable, welche ein Array–Objekt referenzieren kann, definiert man alsoso:

88

Page 89: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

typ[] arrayVariable;

Da Arrays Objekte sind, müssen sie durch einen Konstruktor erzeugt werden.Dem Erzeugen eines Arrays muß man angebeben, wie groß das Array sein soll,d.h. für wie viele Werte oder Objekte im Array Platz sein soll.Ein Array–Objekt der Größe n eines Datentyps typ wird wie folgt erzeugt:

new typ[ n ]

Auch hier wird eine etwas eigenartige Schreibweise verwendet — normalerwei-se wird der Konstruktor einer Klasse ja geschrieben als Klasse( argumente ).Für ein Array würde man also eigentlich erwarten, daß der Konstruktor–Aufrufals Datentyp[](n) geschrieben wird. Auch hier haben Arrays also eine Sonder-stellung.

Beispiel: Im folgenden Beispiel wird in Zeile 3 eine Array–Variable na-mens einIntArray definiert, welche int–Werte speichern kann. In Zeile 4wird ein Array–Objekt der Größe 100 angelegt und durch einIntArrayreferenziert.In Zeile 6 wird eine Variable zur Referenzierung eines double–Arrays er-zeugt und mit einem Array der Größe 10 initialisiert.Zeile 8–9 zeigen, daß man nicht nur Arrays von primitiven Datentypensondern auch Arrays von Objekten definieren kann.

Klasse ArrayDefinitionen

1 class ArrayDefinitionen {2 public static void main( String[] args ) {3 int[] einIntArray;4 einIntArray = new int[ 100 ];56 double[] einDoubleArray = new double[ 10 ];78 String[] einStringArray;9 einStringArray = new String[ 50 ];

10 }11 }

Bevor wir darauf eingehen, wie man Objekte benutzt, sollen noch ein paar Ei-genarten von Arrays erwähnt werden:

• Die Größe eines Arrays kann im Nachhinen nicht mehr verändert werden.Wenn Sie nach der Erzeugung eines Arrays feststellen, daß es zu klein ist,können Sie es also nicht mehr wachsen lassen.Statt dessen müssten Sie in diesem Fall ein weiteres, hinreichend großesArray erzeugen und den Inhalt des alten Arrays in das neue Array hinein-kopieren.

• Es ist nicht möglich, in einem Array Daten verschiedener Klassen oderDatentypen zu speichern. Beispielsweise können Sie kein Array erzeugen,das sowohl int– als auch String–Werte speichern kann15

15Das stimmt nicht völlig — ein Array kann schon Objekte verschiedener Klassen speichern.Das verstehen Sie aber erst, wenn Sie wissen, was Vererbung ist. Für die fortgeschrittenen Leserein Hinweis: Ein Array des Typs MeineKlasse[] kann selbstverständlich auch Instanzen vonExtensionen von MeineKlasse speichern. Insbesondere kann ein Array vom Typ Object[] alleObjekte aufnehmen.

89

Page 90: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

• Beachten Sie bitte den Unterschied zwischen Arrays primitiver Datentypenwie int[], double[] und Arrays von Objekten wie String[].Arrays primitiver Datentypen der Größe n bieten n Positionen, an denenDaten gespeichert werden, während Arrays von Objekten der Größe nnicht die Objekte selbst sondern nur Referenzen auf Objekte speichern.Wir besprechen das weiter unten noch an einem Beispiel.

11.2 Verwendung von Arrays

Jedes Array der Größe n enthält n von 0 bis n− 1 durchnumerierte Variablen.Wenn array eine Array–Variable ist und wenn i eine int–Zahl ist, so kann manauf den i–ten Arrayinhalt wie folgt zugreifen.

array[i]

Einen Kompilierfehler erhält man, wenn man versucht mit einem Wert, welchernicht automatisch in einen int gewandelt werden kann, auf ein Array zuzugreifen.Wäre i eine long oder eine double–Variable, so würde der Zugriff array[i] alsoeinen Kompilierfehler erzeugen.Wenn man versucht, auf eine negative oder auf eine sonstige nicht–vorhandeneArray–Position zuzugreifen, erhält man während der Laufzeit seines Programmseine Fehlermeldung. Das Programm wird dann beendet.

Beispiel: Das folgende Programm definiert ein int–Array der Größe 10.In diesem Array speichert es die Zahlen 1 bis 10.Anschließend wird versucht, die Zahlen auszugeben. Dabei wird ausverse-hen auf eine Array–Position zugegriffen, die nicht existiert. An der Stellebricht das Programm mit einer Fehlermeldung ab.

Klasse ArrayZugriff

1 class ArrayZugriff {2 public static void main( String[] args ) {3 int[] intArr = new int[ 10 ];45 // Array mit Zahlen von 1 bis 10 fuellen6 for( int i = 0; i < 10 ; i++ ) {7 intArr[ i ] = i + 1;8 }9

10 // Arrayinhalt ausgeben. Dabei wird ein Fehler gemacht:11 // Statt von 0..9 wird auf Array-Position 1..10 zugegriffen12 for( int i = 1; i <= 10; i++ ) {13 System.out.println( intArr[i]);14 }15 }16 }

Man kann bei einem gegebenen Array herausfinden, wie groß es ist. Dazu greiftman auf sein Längen–Attribut zu, indem man schreibt:

array.length

Wannimmer Sie die Größe eines Arrays verwenden, sollten Sie das Längen–Attribut des Arrays verwenden. Sie sollten die Größe niemals direkt als Literalim Programm benutzen.

90

Page 91: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Beispiel: Angenommen, Sie wissen, daß ein Array namens meinArray10 Elemente enthält, welche Sie ausgeben wollen, so sollten Sie dennochnicht schreiben

for( int i = 0 ; i < 10 ; i++ ) {System.out.println( meinArray[i] )

}

Verwenden Sie statt dessen das Längen–Attribut:

for( int i = 0 ; i < meinArray.length ; i++ ) {System.out.println( meinArray[i] )

}

Sie fragen sich vielleicht, warum man in seinem Programm die Größe eines Ar-rays nicht explizit verdrahten soll. Die Antwort ist einfach: Programme ändernsich. Wenn Sie später die Größe des Arrays verändern, so müssten Sie alle Stel-len, an denen Sie die Größe als Zahl geschrieben haben, manuell nachbessern.Das führt dann meist zu Fehlern.Wenn Sie von vorneherein darauf achten, daß Ihre Programmteile möglichst we-nig Annahmen über die zu bearbeitenden Objekte machen, werden Änderungeneinfacher.

11.3 Array–Literale

Auch Arrays kann man als Literale schreiben. Ein Array–Literal hat die Form{ wert, wert, ...., wert }.Zum Beispiel wird hier ein durch Verwendung eines Array–Literales ein int–Array der Größe 5 erzeugt und mit den Zahlen 1, 4, 9, 16, 25 initialisiert:

int[] quadrate = {1, 4, 9, 16, 25};

Ähnlich kann man auch andere Arrays initialisieren:

double[] werte = {1.1, 1.3, 1.4};String[] tage = {"Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"};

11.4 Primitive Arrays und Objektarrays

Wir möchten Ihnen hier anhand eines Beispiels nochmal den Unterschied zwi-schen Arrays von primitiven Daten und zwischen Arrays von Objekten zeigen.Dazu betrachten wir ein Programm, welches ein int– und ein String–Array ver-wendet. Beide Arrays haben 4 Einträge.

91

Page 92: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Klasse ArrayPrimObj

1 class ArrayPrimObj {2 public static void main( String[] args ) {3 int[] daten = {100, 200, 300, 400};4 for( int i = 0; i < daten.length; i ++ ) {5 System.out.println( daten[i] );6 }78 String[] sDaten = new String [ 4 ];9 sDaten[0] = "String 1";

10 sDaten[1] = "String 2";11 sDaten[2] = sDaten[3] = "String 3";12 for( int i = 0; i < sDaten.length; i++ ) {13 System.out.println( sDaten[i] );14 }15 }16 }

Um Ihnen deutlich zu machen, wie die beiden Arrays von Java gehandhabtwerden, finden Sie hier zwei Zeichnungen:

int[] daten;

300

200

100

int−Array

length=4

0

1

2

4

Inhalt=:

referenziert

400

Das int–Array ist ein Objekt, welches von der Variable daten referenziert wird.Als Array der Größe 4 enthält es vier von 0 bis 3 durchnumerierte Variablen, inwelchen int–Werte gespeichert werden. Das Array enthält außerdem ein Attributnamens length, in welchem gespeichert wird, wie viele Speicherplätze das Arrayenthält.

Inhalt: String 1

String−Objekt

referenziert

length=4

0

1

2

4

Inhalt=:

String[] sDaten;

String−Array

String−Objekt

String−Objekt

Inhalt: String 2

Inhalt: String 3referenziert

referenziert

referenziert

referenziert

Auch das String–Array ist ein Objekt. Es wird von der Variable sDaten re-ferenziert. Auch das String–Array enthält vier String–Variablen. Da String–Variablen aber Objekte nicht speichern sondern nur referenzieren, enthält dasString–Array selbst lediglich vier Verweise auf andere Objekte.

92

Page 93: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

11.5 Referenztypen am Array-Beispiel

Nun möchten wir Ihnen noch am Beispiel der Arrays demonstrieren, was esfür die Praxis bedeutet, mit Referenztypen zu arbeiten. Sie sollten dieses Pro-gramm auf jeden Fall ausprobieren und danach ein wenig mit dem Programmherumspielen !

Klasse ArrayReferenz

1 class ArrayReferenz {2 public static void main( String[] args ) {3 int[] daten = {100, 200, 300, 400};45 int[] datenNeu = daten;6 datenNeu[1] = 1;7 datenNeu[3] = 3;8 datenNeu = new int[4];9

10 for(int i = 0; i < daten.length; i++ ) {11 System.out.println( daten[i] );12 }13 }14 }

Im obigen Programm wird ein Array–Objekt erzeugt, welches durch die Variabledaten referenziert wird. In Zeile 5 wird eine weitere Variable, datenNeu definiert,welche das selbe Objekt referenziert.Dann wird in Zeile 6 und 7 die Variable datenNeu verwendet, um das Array–Objekt zu verändern.Obwohl wir die Variable daten nicht benutzt haben, um das Array zu verändern,hat sich das durch die Variable daten referenzierte Array hierdurch verändert,wie die Ausgabe in Zeile 10–12 beweist.Sie sehen also, daß Änderungen an Objekten alle Variablen beeinflussen, wel-che das Objekt referenzieren. Wenn man im Umgang mit Referenztypen nichtaufpasst und sich nicht immer wieder klarmacht, daß die Zuweisung keine Ko-pie sondern nur eine Referenz erzeugt, kann man daher große Überraschungenerleben.

11.6 Mehrdimensionale Arrays

Man kann auch Arrays erzeugen, die Arrays enthalten. Beispielsweise wird hierein Array erzeugt, das int–Arrays enthält:

int[][] einZweiDIntArray;

Arrays, die Arrays enthalten, nennt man mehrdimensionale Arrays. Unter “Di-mension” versteht man dabei die Schachtelungstiefe der Arrays. Ein vierdimen-sionales Array könnte man so definieren:

int[][][][] einVierdimArray;

Mehrdimensionale Arrays eignen sich zur Darstellung von Daten wie Matrizen,Tensoren, Spreadsheets, und so weiter.Ein zweidimensionales Array wird wie folgt erzeugt:

93

Page 94: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

int[][] zweiDArray = new int[ zeilen ][ spalten ];

Beachten Sie aber den Unterschied zwischen einem zweidimensionalen Arrayund einer Matrix: In einer Matrix hat jede Zeile und jede Spalte die gleicheLänge. Ein zweidimensionales Array ist hingegen einfach ein Array, das andereArrays enthält. Über die Längen der enthaltenen Arrays ist damit nichts gesagt.Die obige Initialisierung eines zweidimensionalen Arrays stellt allerdings sicher,daß alle Zeilen des erzeugten Arrays die gleiche Länge haben.

Beispiel: Das folgende Programm demonstriert die Erzeugung eines ma-trixförmigen Arrays und eines zweidimensionalen Arrays einDreieck, inwelchem die Zeilen unterschiedliche Längen besitzen:

Klasse Array2D

1 class Array2D {2 public static void main( String[] args ) {3 int[][] eineMatrix = new int[10][10];4 for( int i=0; i < eineMatrix.length; i++) {5 for( int j=0; j < eineMatrix.length; j++) {6 eineMatrix[i][j] = i-j;7 }8 }9

10 int[][] einDreieck = new int[10][1];11 for( int i=0; i < einDreieck.length; i++) {12 einDreieck[i] = new int[i+1];13 }14 for( int i=0; i < einDreieck.length; i++) {15 for( int j=0; j < einDreieck[i].length; j++ ) {16 einDreieck[i][j]=i-j;17 System.out.print( einDreieck[i][j] );18 System.out.print(" ");19 }20 System.out.println();21 }22 }23 }

Beispiel: Schließlich demonstriert das folgende Programm demonstriertden Umgang mit 2–dimensionalen Arrays und 2–dimensionalen Array–Literalen.Zuerst wird ein matrixförmiges double–Array definiert und ausgegeben,und anschließend wird ein dreieckförmiges int–Array definiert und ausge-geben.

94

Page 95: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Klasse Array2D

1 class Array2D {2 public static void main( String[] args ) {34 // matrixförmiges double--array5 double[][] matrix = { {1.1, 1.2}, {1.2, 1.3} };67 for( int i = 0; i < matrix.length ; i++ ) {8 for( int j= 0; j < matrix[i].length; j++ ) {9 System.out.print( matrix[i][j] );

10 System.out.print(" ");11 }12 System.out.println();13 }1415 // dreieckförmiges int--Array16 int[][] zweiDInt = { {1}, {2,3}, {4,5,6}, {7,8,9,10} };1718 for( int i = 0; i < zweiDInt.length ; i++ ) {19 for( int j= 0; j < zweiDInt[i].length; j++ ) {20 System.out.print( zweiDInt[i][j] );21 System.out.print(" ");22 }23 System.out.println();24 }2526 }27 }

11.7 Zusammenfassung

Sie sollten nun die folgenden Fragen beantworten können:

B Was ist ein Array ?B Wie definiert man ein boolean–Array ?B Wie erzeugt man ein Array–Objekt ?B Wie kann man im Nachhinein die Größe eines Arrays ändern ?B Erläutern Sie den Unterschied zwischen Arrays primitiver Datentypen

und Arrays von Objekten !B Wie greift man auf Array–Elemente zu ?B Wie sind die Variablen in einem Array der Länge 4 durchnumeriert ?B Wie kann man auf das letzte Element eines Arrays der Länge 4 zu-

greifen ?B Wie kann man auf das erste Element eines Arrays zugreifen ? Wie auf

das zweite ?B Wie kann man die Größe eines gegebenen Arrays bestimmen ?B Was ist ein Array–Literal, und wie benutzt man es ?B Welche Gefahr besteht bei der Verwendung von Referenz–Typen ?B Was ist ein Mehrdimensionales Array ?B Wie erzeugt man ein mehrdimensionales Array ?B Wie unterscheiden sich 2–dimensionale Arrays von Matrizen ?

95

Page 96: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

12 Klassen in JavaNun soll es endlich daran gehen, in Java eigene Klassen zu erstellen. Wir schlie-ßen hier an der in in Kapitel ?? begonnenen Diskussion über Klassen und Ob-jekte an. Wenn Ihnen die Inhalte von Kapitel ?? nicht mehr geläufig sind, solltenSie es nun noch einmal lesen.

12.1 Instanz- und Klassenbestandteile

Bevor wir beginnen, Klassen zu programmieren, müssen wir unsere Vorstellungvon Klassen etwas revidieren — Sie wissen bisher, daß eine Klasse ein Bauplanfür Objekte ist. Sie ist aber noch mehr — genau wie Objekte kann auch eineKlasse Variablen und Methoden enthalten (eine Java–Klasse ist aber selbst keinObjekt).Die Klasse hat also zwei Funktionen: Zum einen ist die Klasse der Bauplan vonObjekten — in der Klasse ist beschrieben, welche Attribute die Objekte tragensollen, und auch das Verhalten der Objekte ist in der Klasse durch Methodenbeschrieben.Zur Erinnerung: Die Methoden und Attribute der Objekte nennt man Instanz-methoden und Instanzvariablen. Von jeder Instanzvariable hat jedes Objektseine eigene, private Kopie. Instanzmethoden können nur im Zusammenhangmit einem Objekt verwendet werden, und aus Instanzmethoden ist der direkteZugriff auf die Instanzvariablen des Objektes möglich.Zum anderen kann auch eine Klasse selbst Methoden und Attribute besitzen. Dieder Klasse zugeordneten Methoden und Attribute nennt man Klassenmetho-den und Klassenvariablen oder auch statische Methoden und statischeVariablen.Von jeder Klassenvariable gibt es nur eine einzige Kopie pro Klasse, und jedesObjekt der Klasse kann darauf zugreifen. Insofern teilen sich alle Objekte derKlasse die Klassenvariablen. Da von jeder Klassenvariable nur ein Exemplar proKlasse vorhanden ist, greifen alle Objekte auf dieselben Klassenvariablen zu —die Änderung einer Klassenvariable wirkt sich also auf alle Objekte aus, welchediese Variable verwenden.Ihnen ist sicher nicht klar, was wir mit dieser Unterscheidung in Instanzmetho-den und Instanzvariablen auf der einen Seite und Klassenmethoden und Klas-senvariablen auf der anderen Seite meinen. Nun, daß ein Objekt Methoden undVariablen besitzt, sollte schon im vorigen Text hinreichend klar geworden sein.Wieso aber sollte auch die Klasse Methoden und Variablen besitzen ? Dafürgibt es einige Gründe:

• Eine Instanzmethode kann nur im Zusammenhang mit einem Objekt aus-geführt werden. Manchmal benötigt man aber Methoden, die ohne dieExistenz eines Objektes ausgeführt werden können. Ein Beispiel hierfürist die Ihnen schon bekannte main–Methode. Sie erst ermöglicht das Star-ten von Anwendungen, denn sie kann auch ausgeführt werden, ohne daßbereits Objekte angelegt wurden.

• Oft benötigen alle Objekte einer Klasse Zugriff auf gemeinsame, von denObjekten unabhängige Daten. Derartige Daten möchte man nicht in den

96

Page 97: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Objekten selbst sondern an einer zentralen Stelle speichern, die irgendwiezu den Objekten gehört. Hierzu verwendet man Klassenvariablen.

• Oft benötigt man in Objekten eine Funktionalität, die zwar logisch zumObjekt gehört, aber nicht auf den Zustand des Objektes angewiesen ist,und die man daher nicht den Objekten sondern woanders zuordnen möch-te. Hierzu verwendet man Klassenmethoden.

Wir werden Ihnen gleich erzählen, wie man diese verschiedenen Arten von Me-thoden und Variablen definieren kann. Vorher aber ein Beispiel, das Sie jetztschon verstehen können müssten:

Beispiel:

Klasse Autoa

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/KapKlassen/Auto.java

Die obige Klasse definiert eine Klasse namens Auto.In der Klasse sind drei Attribute definiert:In Zeile 6 und 7 ist ein String–Attribut namens hersteller und ein int–Attribut namens ps definiert. Da diese Variablen nicht als statisch dekla-riert sind, sind sie Instanzvariablen. Jedes Auto–Objekt hat eine eigeneKopie dieser beiden Attribute. Dabei legen die Attribute den Herstellerdes Autos und die PS–Zahl fest.In Zeile 4 ist eine als static ausgezeichnete double–Variable namenskwpsfaktor definiert. Diese Variable wird in Zeile 4 mit einem Zahlenwertinitialisiert, welcher zur Umrechnung von Pferdestärken in Kilowatt ver-wendet werden kann. Die Kennzeichnung als static macht aus kwpsfaktoreine statische Variable bzw. eine Klassenvariable.Der Grund, warum die Variablen hersteller und ps als Instanzvariablendeklariert sind, ist klar — jedes Auto hat einen Hersteller und eine gewissePS–Zahl und braucht somit seine eigene Kopie dieser beiden Variablen.Man kann diese Attribute von einem Auto nicht trennen.Der Umrechnungsfaktor von PS–Werten zu Kilowatt hingegen ist für jedesAuto gleich. Er existiert unabhängig von irgendwelchen Auto–Objekten,und es wäre daher nicht angemessen, ihn zu einer Instanzvariable zu ma-chen. Aus diesem Grund haben wir den Umrechnungsfaktor zu einer Klas-senvariable gemacht. Damit können alle Auto–Objekte auf den Umrech-nungsfaktor zugreifen, und es ist sichergestellt, daß alle Auto–Objektedenselben Umrechnungsfaktor verwenden.In Zeilen 9–12 sehen Sie eine Methode namens Auto. Ihnen sollte auffallen,daß der Name dieser Methode mit dem Namen der Klasse übereinstimmt.Derartige Methoden nennt man Konstruktoren (was das Wörtchen publicbedeutet, erzählen wir Ihnen später noch). Ein Konstruktor wird beimErzeugen eines Objektes benutzt, um die Instanzvariablen des Objekteszu initialisieren.Wir verwenden den Konstruktor zweimal — in der main–Methode in Zeile29 wird ein Auto–Objekt namens mercedes erzeugt, und in Zeile 32 wird

97

Page 98: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

ein Auto–Objekt namens ferrari erzeugt. Beide Male wird der Konstruktorverwendet. Im Kapitel 10 haben wir bereits erläutert, wozu Konstruktorenda sind. Vielleicht sollten Sie sich dieses Kapitel nochmal anschauen ?In Zeilen 14–20 wird eine Methode void anzeigen() definiert. Dies ist ei-ne Instanzmethode, welche ein Auto–Objekt anzeigen kann. Als Instanz-methode kann sie direkt auf die Attribute des Objektes zugreifen. BeimAufruf muß ihr daher ein Objekt angegeben werden.Die anzeigen()–Methode wird in Zeile 30 und in Zeile 33 aufgerufen. Da-bei wird sie einmal im Objekt mercedes und einmal im Objekt ferrariaktiviert.Beachten Sie bitte auch, daß die anzeigen()–Methode auf die Klassenva-riable kwpsfaktor zugreifen kann — dies geschieht in Zeile 19.In der anzeigen()–Methode wird in Zeile 17 eine Methode namenswandlePSzuKW aufgerufen, um die PS–Zahl des Autos in den Kilowatt–Wert umzuwandeln. Die wandlePSzuKW–Methode ist in Zeilen 22–25definiert. Da sie als static ausgezeichnet ist, ist sie keine Instanz– sonderneine Klassenmethode. Als solche kann sie auch auf alle Klassenvariablen(in diesem Fall nur kwpsfaktor), nicht aber auf Instanzvariablen zugreifen.Der Grund, daß die wandlePSzuKW–Methode als Klassenmethode undnicht als Instanzmethode definiert wurde, sollte klar sein: Die Wandlungeines Pferdestärken in einen Kilowatt–Wert ist nicht von einem konkretenAuto–Objekt abhängig. Es wäre daher nicht angemessen, diese Methodeals Instanzmethode zu definieren.Schließlich noch ein Wort zur main–Methode auf Zeile 27–34: Diese Me-thode ist durch die Definition als static eine Klassenmethode, ist alsonicht mit einem Objekt assoziiert. Die main–Methode macht die Klasseausführbar.In der main–Methode werden zwei Objekte namens mercedes und ferraridefiniert, und es werden die anzeigen()–Methoden beider Objekte aufge-rufen.

12.2 Zugriff auf Methoden und Attribute

In Kapitel 10.4 haben wir zwar bereits beschrieben, wie man auf die Bestandteilevon Objekten zugreift. Das soll hier nochmal rekapituliert werden:Sie können sich die Java–Philosophie so vorstellen, daß ein Objekt Attribute undMethoden enthält. Wenn man auf die Attribute zugreifen oder die Methodenverwenden will, muß man in das Objekt hineingreifen. Dies geschieht in Javadurch den Punkt “.”. Will man auf etwas in einem Objekt zugreifen, schreibt manhinter den Objektnamen einen Punkt und dahinter den Namen dessen, woraufman zugreifen möchte.Will man von außen auf ein Attribut attribut in einem Objekt einObjekt zu-greifen oder eine Methode methode() aufrufen, schreibt man

einObjekt.attribut;// odereinObjekt.methode();

Genauso wie man auf die Inhalte eines Objektes zugreift, kann man auch aufin einer Klasse enthaltene Klassenvariablen und Klassenmethoden zugreifen.

98

Page 99: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Auch hier benutzt man den Punkt. Wenn eine Klasse namens EineKlasse eineKlassenvariable namens klassenVar oder eine Methode klassenMethode() kannman hierauf von außen wie folgt zugreifen:

EineKlasse.klassenVar;// oderEineKlasse.klassenMethode();

Der Punkt dient also dazu, von außen auf die Inhalte eines Objektes oder einerKlasse zuzugreifen. Ein Objekt kann auf seine Instanzvariablen, Klassenvaria-blen, Instanzmethoden und Klassenmethoden direkt zugreifen. Genauso könnenSie in einer Klassenmethode direkt auf die Klassenattribute zugreifen.

Beispiel:Die folgende Klasse verwendet die eben definierte Klasse Auto. Diekompilierte Datei UseAuto.class sollte sich im gleichen Verzeichnis wieAuto.class befinden, damit sie funktioniert:

Klasse UseAutoa

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/KapKlassen/UseAuto.java

In Zeile 5 wird ein Auto–Objekt namens vw erzeugt. Auf dessen Attributewird in Zeilen 7–8 zugegriffen.In Zeile 10 und 11 werden die Attribute des Objektes von außen geändert.Der dann erfolgte Aufruf der anzeigen()–Methode beweist, daß wir vonaußen den Zustand des Objektes verändert haben.In Zeile 15–16 greifen wir von außen auf die Klassenvariable kwpsfaktorzu. In Zeile 18 erdreisten wir uns sogar, diese von außen auf einen falschenWert zu setzen.Da die Umrechnungsroutine der Auto–Klasse auf diese Klassenvariableangewiesen ist, haben wir damit auch unser vw–Objekt beeinflußt — absofort funktioniert die Umrechnung von PS in KW nur noch fehlerhaft,wie der Aufruf der anzeigen()–Instanzmethode in Zeile 21 beweist.

Sie sehen am vorigen Beispiel, daß man durch Eingriffe von außen die Funk-tionsfähigkeit einer Klasse beeinträchtigen kann. Java bietet Mechanismen an,die derartige Eingriffe in das Innenleben von Klassen und Objekten abwehren.In einem späteren Kapitel werden Sie lernen, wie man “wehrhafte” Objekte undKlassen entwickeln kann, die Eingriffe von außen abweisen.

12.3 Die Bestandteile einer Java–Klasse

Nun endlich zum Aufbau einer Java–Klasse: Jede Java–Klasse beginnt mit derDefinition der Klasseneigenschaften — dem Klassenkopf — gefolgt von einemBlock, in welchem die Klasse definiert wird — dem Klassenkörper. Vorerst soll-ten Sie davon ausgehen, daß jede Klasse in einer eigenen Datei enthalten ist.Der Name dieser Datei ist der Klassenname gefolgt von der Endung “.java”.Die Klassendefinition hat in ihrer einfachsten Form den Aufbau

99

Page 100: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

class KlassenName // Klassenkopf{

// Klassenkörper}

Die Beschreibung der Klasseneigenschaften im Klassenkopf werden wir späternoch ergänzen. Beispielsweise könnte eine kompliziertere Klasse auch die folgen-de Eigenschaftsbeschreibung haben:

public class MyClass extends AnotherClass implements MyInterface{

// Klassenkörper}

Eine Klassendefinition besteht also aus zwei Teilen: Dem Klassenkopf, in wel-chem gewisse später zu erläuternde Eigenschaften der Klasse beschrieben werdenund dem Klassenkörper, in welchem die Klasse selbst definiert wird.In der einfachsten Version besteht der Klassenkopf aus dem Text

class KlassenName

Das Wort class weist den Java–Compiler darauf hin, daß nun die Definitioneiner Klasse folgt. Durch den hinter dem Wort class stehenden Namen erfährtder Compiler den Namen der zu definierenden Klasse. Der Klassenkopf veran-lasst den Java–Compiler, den darauf folgenden Block als Definition der im Kopfbenannten Klasse zu interpretieren.Beachten Sie, daß sich der Klassenkörper von den Ihnen bereits bekannten An-weisungsblöcken unterscheidet — der Klassenkörper selbst enthält nämlich imGegensatz zu den Anweisungsblöcken keine Anweisungen sondern eine Folge vonDefinitionen.Abstrakt ist ein Klassenkörper wie folgt aufgabaut:

class KlassenName {Definition_1Definition_2...Definition_n

}

Die einzelnen Definitionen definieren dabei entweder Attribute oder Methoden.Es ist auch möglich, in einer Klasse andere Klassen zu definieren, aber das sollzunächst außer acht gelassen werden.Es gibt keine vorgeschriebene Reihenfolge für die einzelnen Definitionen — es istalso nicht nötig, alle Attribute vor allen Methoden zu definieren oder umgekehrt.Methoden– und Attribut–Definitionen dürfen in beliebiger Reihenfolge stehen.Es empfiehlt sich allerdings, die einzelnen Definitionen zusammenzulassen. Meistdefiniert man zuerst alle Attribute und danach alle Methoden.Wie die Methoden- und Attributdefinitionen aufgebaut sein müssen, wird in dennächsten Abschnitten erklärt.

100

Page 101: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

12.4 Attribute

Ein Attribut wird genauso definiert wie eine Variable: Es wird sein Datentypoder seine Klasse gefolgt von seinem Namen angegeben. Die Definition einesAttributs muß mit einem Semikolon beendet werden.Wenn die Objekte der Klasse eine Instanzvariable namens instanzVariable desDatentyps Datentyp haben sollen, so wird diese wie folgt definiert (ein funktio-nierendes Beispiel folgt weiter unten):

Datentyp instanzVariable;

Soll statt einer Instanzvariable eine Klassenvariable definiert werden, so schreibtman vor die Definition das Wort “static”. Soll beispielsweise eine KlassenvariableklassenVariable des Typs Datentyp definiert werden, so schreibt man

static Datentyp klassenVariable;

Genau wie alle Variablendefinitionen kann auch ein Klassenattribut oder einInstanzattribut schon bei der Definition initialisiert werden. Dazu schreibt manhinter den Namen des Attributes direkt die Initialisierungszuweisung:

Datentyp instanzVariable = Initialisierung;static Datentyp klassenVariable = Initialisierung;

Wird auf diese Weise eine Instanzvariable initialisiert, so erhält diese Instanz-variable bei jedem neu erzeugten Objekt den angegebenen Wert erhält. Wirdhingegen eine Klassenvariable auf diese Weise initialisiert, so erhält die Klassen-variable noch vor der ersten Verwendung der Klasse den angegebenen Wert.Das folgende Beispiel demonstriert die Definition von Instanzvariablen:

Beispiel:Hier wird eine Klasse Punkt3D definiert, deren Objekte Punkte im dreidi-mensionalen Raum repräsentieren. Zunächst definieren wir keine Metho-den sondern nur die Attribute der Objekte.Objekte dieser Klasse erhalten drei double–Instanzvariablen namens x,yund z, welche die Koordinaten des Punktes beschreiben.Die Klasse ist in dieser Form kompilierbar aber nicht ausführbar, da siekeine main–Methode besitzt.

Klasse Punkt3Da

1 class Punkt3Da {23 // Koordinaten:4 double x;5 double y;6 double z;78 }

Falls wir möchten, daß jeder neu angelegte Punkt einen vorher festge-legten Zustand erhält, können wir dies dadurch erreichen, daß wir jedeInstanzvariable schon bei der Definition initialisieren.

101

Page 102: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Wenn wir uns entscheiden, jeden neu angelegten Punkt auf die Koordina-ten (0, 0, 0) zu initialisieren, können wir das so erreichen:

Klasse Punkt3D

1 class Punkt3D {23 // Koordinaten:4 double x = 0;5 double y = 0;6 double z = 0;78 }

Beispiel: Hier noch ein Beispiel ohne tieferen Sinn, in welchem auchKlassenvariable verwendet werden:

Klasse InstKlassVar

1 class InstKlassVar {23 static double klassenVar1 = 0;4 static double klassenVar2 = 1.3;56 double instanzVar1 = 3;7 double instanzVar2 = 5;89 }

Und noch eine hoffentlich überflüssige Bemerkung: Als Attribute können natür-lich nicht nur primitive Daten sondern auch Objekte anderer Klassen verwendetwerden.

Beispiel:Das folgende Beispiel verwendet die oben definierte Klasse Punkt3D, umeine Linie von einem Punkt zum anderem im dreidimensionalen Raum zubeschreiben.Eine Linie ist dabei gegeben durch zwei Eckpunkte, welche wir punkt1und punkt2 nennen, und welche Objekte der Klasse Punkt3D sind:

Klasse Linie

1 class Linie {23 Punkt3D punkt1, punkt2;45 }

12.5 Definition von Methoden

Auch eine Methodendefinition besteht aus zwei Teilen, nämlich dem Methoden-kopf und dem Methodenkörper. Abstrakt hat eine Methodendefinition folgendenAufbau:

Methodenkopf {

102

Page 103: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

// Methodenkörper}

Dabei beschreibt der Methodenkopf mindestens

• den Namen der Methode,

• welche Werte die Methode zur Ausführung benötigt,

• den Typ der von der Methode zurückgelieferten Daten

• und ob es sich um eine Instanzmethode oder eine Klassenmethode handelt.

Der Methodenkörper besteht aus einer Folge von Anweisungen, welche bei jederAusführung der Methode abgearbeitet werden.

Beispiel: Die wohl einfachste Methode wird so definiert:

void nichtsTun() {}

Diese Methode hat einen leeren Methodenkörper und tut daher beim Auf-ruf gar nichts.Der Methodenkopf legt fest, daß die Methode den Namen “nichtsTun”hat. Das Wort “void” bedeutet, daß sie keinen Wert zurückliefert.

Der Methodenkopf ist in Java genauso wie in Kapitel ?? beschrieben aufge-baut. Eine Instanzmethode namensmethodenName, welche einenWert des TypsRueckgabeTyp zurückliefert und zur Ausführung Werte der Datentypen Typ1bis TypN benötigt, welche dann in der Methode unter den Bezeichnern wert1bis wertN angesprochen werden können, wird wie folgt definiert:

RueckgabeTyp instanzMethode( Typ1 wert1, ... TypN wertN )

Falls eine Methode keinen Wert zurückliefern soll, wird als Rückgabe–Typ derTyp void verwendet (eng. void: leer, ungültig). Die zur Ausführung der Methodebenötigten Werte wert1 bis wertN nennt man auch formale Parameter derMethode.Soll eine Methode nicht als Instanz– sondern als Klassenmethode definiert wer-den, so ist vor die Methodendefinition noch das Wort “static” zu setzen:

static RueckgabeTyp klassenMethode( Typ1 wert1, ... TypN wertN )

Vom Aufbau unterscheiden sich Klassen– und Instanzmethoden ansonsten nicht— der Unterschied ist der, daß innerhalb von Instanzmethoden auf alle Instanz-variablen eines Objektes sowie auf alle Klassenvariablen der Klasse zugegriffenwerden kann, während aus Klassenmethoden nur auf die Klassenvariablen, nichtaber auf Instanzvariablen zugegriffen werden kann.

Beispiel: Hier einige Beispiele für gültige Methodenköpfe:

103

Page 104: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

1 void anzeigen()2 static void zeilenVorschub( int anzahlZeilen )3 static double summiere( double[] werte )4 double[] sortiere( double[] werte )5 static int searchIndex( String[] stringListe, String s2 )

Beschreibung der obigen Methodenköpfen:

1. Eine Instanzmethode namens anzeigen, welche keine Argumente ent-gegennimmt und keinen Wert zurückliefert.

2. Eine Klassenmethode namens zeilenVorschub, welche einen Parame-ter vom Typ int entgegennimmt, welcher in der Methode unter demNamen anzahlZeilen angesprochen werden kann. Diese Methode lie-fert keinen Wert zurück.

3. Eine Klassenmethode namens summiere, welche ein Array vondouble–Werten entgegennimmt und einen double–Wert zurücklie-fert. Das Array kann im Methodenkörper unter der Variabel werteangesprochen werden.

4. Eine Instanzmethode namens sortiere, welche ein double–Array zu-rückliefert und ein Array aus double–Werten namens werte entge-gennimmt.

5. Eine Klassenmethode namens searchIndex, welche ein String–Arraynamens stringListe und einen String namens s2 entgegennimmt undeine int–Wert zurückliefert.

Der Methodenkörper besteht aus einer Folge von Anweisungen. Wenn im Metho-denkopf Übergabeparameter beschrieben sind, so kann im Methodenkörper aufdiese genauso wie auf alle anderen Variablen zugegriffen werden. Dabei werdendie formalen Parameter bei jedem Aufruf der Methode durch die Aufrufspara-meter ersetzt.Ist eine Methode nicht als void gekennzeichnet, so muß sie ein Ergebnis anden Aufrufer zurückübermitteln. Dazu wird der return–Befehl verwendet. Derreturn–Befehl gibt einen Wert zurück und beendet dabei die Bearbeitung derMethode.In einer Methode darf der return–Befehl beliebig oft verwendet werden. Es dientaber normalerweise nicht der Übersichtlichkeit und dem besseren Verständnisdes Programmes, wenn man viele return–Befehle in einer Methode benutzt.Abstrakt wird der return–Befehl wie folgt benutzt:

return Wert;

Der zurückgegebene Wert muß dabei den Datentyp haben, welchen die Methodezurückliefern soll.

Beispiel: Die folgende Methode würde zu einem Kompilierfehler führen,denn die Methode ist als int deklariert. Der Wert, der im return–Befehlzurückgegeben wird, ist aber ein double–Wert.

int rechne( int wert ) {return wert * 1.355;

}

104

Page 105: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

So wäre die Methode korrekt:

int rechne( int wert ) {return (int) (wert * 1.355);

}

Der return–Befehl darf auch in einer als void deklarierten Methode verwendetwerden, um die Methodenbearbeitung abzubrechen und zum Aufrufer der Me-thode zurückzukehren. In einer void–Methode muß allerdings nicht unbedingtein return stehen, denn am Ende eines jeden Methodenkörpers wird vom Java–Compiler automatisch ein return eingefügt.In einer void–Methode darf kein Wert zurückgegeben werden. Die Verwendungdes return–Befehles in einer void–Methode sieht so aus:

return;

Beispiel: Hier ein Beispiel für eine void–Methode, in der mehrere return–Befehle auftauchen. Wenn man sehr viele Fallunterscheidungen hat, kannes Sinn machen, mehrere return–Befehle in einer Methode zu haben. Nor-malerweise sollten Sie das jedoch vermeiden. In dieser einfachen Methodeist die Verwendung mehrerer return–Befehle kein guter Programmierstil:

/** Beispiel für unschöne Verwendung mehrerer return--Befehle*/

void intervallausgabe( int i ) {if( i < 0) return;System.out.println("i ist >= 0");

if( i < 10) return;System.out.println("i ist >= 10");

if( i < 20) return;System.out.println("i ist >= 20");

}

Hier folgt die Methode nochmal ohne Verwendung von return–Befehlen.Durch die Verwendung geschachtelter if –Befehle wird die Struktur derMethode im Gegensatz zur ersten Version auf den ersten Blick klar.

void intervallausgabe( int i ) {if( i >= 0) {

System.out.println("i ist >= 0");

if( i >= 10) {System.out.println("i ist >= 10");

if( i >= 20) {System.out.println("i ist >= 20")

}}

}}

105

Page 106: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Nun sollen noch einige Beispiel–Methoden gezeigt und besprochen werden.

Beispiel: Die folgende Klasse enthält eine Klassenmethode namensquadriereWerte und eine Klassenmethode namens durchschnitt:

Klasse DemoMethodea

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/KapKlassen/DemoMethode.java

Die Klassenmethode quadriereWerte ist als void deklariert und hat einenformalen Parameter, der innerhalb der Methode als werte angesprochenwerden kann und vom Typ double[] ist. Da die Methode als void dekla-riert ist, muß in ihr kein return–Befehl stehen. Auf den formalen Parame-ter kann in der Methode (z.B. in Zeile 5) zugegriffen werden wie auf jedeandere Variable auch.In Zeilen 25 und 26 wird die Methode verwendet. Dabei wird anstelle desformalen Parameters werte einmal die Variable w1 und einmal die Varia-ble w2 eingesetzt. In der Methode wird dann der Inhalt der Parameterverändert.Auch die durchschnitt–Methode hat einen formalen Parameter namenswerte. Da sie keine void–Methode ist, muß sie mit return einen Wertzurückliefern.

Beispiel: Nun noch ein Beispiel mit einigen Instanzmethoden:Wir erweitern die Punkt3D–Klasse aus dem vorigen Abschnitt um zweiMethoden: Die Methode show zeigt einen Punkt auf dem Bildschirm an,die Methode norm berechnet die Euklidische Norm des Punktes, die Me-thode move verschiebt den Punkt um eine gewisse Distanz, indem dieKoordinaten eines anderen Punktes addiert werden:

Klasse Punkt3Da

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/KapKlassen/Punkt3D.java

Beispiel: Und hier noch ein Beispiel, welches das vorige Beispiel verwen-det. Die Klasse Linie3D muß im selben Verzeichnis gespeichert sein wiedie Klasse Punkt3D.

Klasse Linie3Da

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/KapKlassen/Linie3D.java

12.6 Mehrere Methoden mit gleichem Namen

Java hat eine Fähigkeit, die nur wenige andere Sprachen bieten: Es ist möglich,mehrere Methoden mit gleichem Namen zu benutzen. Damit Java weiß, welche

106

Page 107: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Methode bei einem Aufruf gemeint ist, müssen sich die Methoden dann durchdie geforderten Parameter unterscheiden.

Beispiel: In der folgenden Klasse ist die Methode max zweimal definiert— einmal als Methode, welche zwei int–Werte akzeptiert und einmal alsMethode, welche zwei double–Werte akzeptiert.

Klasse MethodenDemoa

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/KapKlassen/MethodenDemo.java

Immer wenn Java einen Methodenaufruf sieht, geht es folgendermaßen vor:

• Zuerst schaut es nach, ob in der Klasse eine Methode definiert ist, die zuden aktuellen Parametern im Methodenaufruf stehen.Im obigen Beispiel geschieht der Aufruf in Zeile 20 mit zwei int–Wertenund in Zeile 21 mit zwei double–Werten. Dem Compiler ist also sofortklar, daß der Aufruf in Zeile 20 die erste max–Methode auf Zeile 3–9 undder Aufruf in Zeile 21 die max–Methode auf Zeile 11–17 meint.

• Wenn auf die Parameter im Methodenaufruf keine Methode passt, soschaut der Compiler nach, ob er die Argumente im Methodenaufruf ineinen anderen Typ verwandeln kann, so daß der Aufruf dann auf eine De-finition paßt. Beim Wandeln der Typen werden die Regeln aus Kapitel 8verwendet.Im obigen Beispiel werden im Aufruf in Zeile 22 ein int und ein double–Wert verwendet. Eine solche Methode kennt der Compiler nicht. Er kannaber den int–Wert in einen double–Wert verwandeln und dann die double–Methode verwenden.

Kurz gesagt: Sie können beliebig viele Methoden des gleichen Namens schreiben,wenn es eine eindeutige Möglichkeit gibt, anhand der übergebenen Parameterherauszufinden, welche Methode gemeint ist.Sie können insbesondere nicht zwei Methoden schreiben, die sich nur durch denRückgabewert unterscheiden. Warum ist das so ? Nun, man muß ja den Rück-gabewert einer Methode nicht unbedingt verwenden. Zum Beispiel ist folgenderProgrammtext legal:

int rechne(int i) {return i * 2;

}

public static void main(String[] args) {rechne(5);reche(3);

}

Wenn Sie nun mehrere Methoden definieren, die die gleichen Parameter definie-ren aber unterschiedliche Rückgabewerte haben, hätte Java keine Möglichkeitherauszufinden, welche Methode Sie meinen.

107

Page 108: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Beispiel: Das folgende Beispiel würde nicht kompilieren, da sich die bei-den Methoden nur durch den Rückgabewert unterscheiden.

public class MethodenDemo2 {

int rechne( int i ) {return i*2;

}

double rechne( int i ) { // Fehlerreturn i*3.0;

}}

12.7 Konstruktoren

Konstruktoren sind besondere Methoden, welche beim Erzeugen von Objek-ten benutzt werden. Jedesmal wenn ein Objekt erzeugt wird, wird vom Java–Laufzeitsystem zunächst Speicher für das Objekt bereitgestellt, d.h. für jedeInstanzvariable des Objektes wird Speicher belegt.Anschließend wird ein Konstruktor aufgerufen. Der Konstruktor dient dazu, dieInstanzvariablen des Objektes zu initialisieren. Ein Konstruktor ist eine Metho-de, deren Namen gleich dem Namen der Klasse ist.Eine Klasse darf mehrere Konstruktoren besitzen. Welcher Konstruktor bei derErzeugung eines Objektes aufgerufen wird, richtet sich nach den beim Erzeugendes Objektes durch den new–Operator übergebenen Parametern

Beispiel: Die folgende Klasse PunktND repräsentiert einen Punkt imN–dimensionalen Raum. Sie enthält drei Konstruktoren:

Klasse PunktNDa

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/KapKlassen/PunktND.java

Der erste Konstruktor, PunktND() wird in Zeilen 9–14 definiert. Er wirdin Zeile 39 aufgerufen. Beachten Sie bitte, daß in Zeile 39 zwar durch dennew–Operator ein neues Objekt angelegt wird; dieses wird aber keinerVariable zugewiesen.Der zweite Konstruktor, PunktND( double[] ) wird in Zeilen 15–20 defi-niert. Er wird in Zeile 42 verwendet.In Zeile 22–27 wird ein weiterer Konstruktor,PunktND(double,double,double) definiert, welcher auf Zeile 45 ver-wendet wird. Auch hier wird das durch den new–Operator erzeugteObjekt keiner Variable zugewiesen.

12.8 Die Parameterübergabe an eine Methode

Wie werden Parameter an eine Methode übergeben ? Das wollen wir am folgen-den Beispielprogramm besprechen:

108

Page 109: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Beispiel:

Klasse ParamUebergabea

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/KapKlassen/ParamUebergabe.java

Wenn Sie das Programm starten, erhalten Sie folgende Ausgabe:

a ist 3a ist jetzt 5In main ist i = 3a[0] ist 2a[0] ist jetzt 5In main ist arr[0] = 5

Wie Sie sehen, wirkt sich die Änderung des Parameters a innerhalb der erstenchange–Methode nicht auf die Variable i im Hauptprogramm aus.Hingegen wirkt sich die Änderung am Array in der zweiten change–Methodeauf das Hauptprogramm aus.Den Grund für dieses unterschiedliche Verhalten haben wir bereits in einem vo-rigen Kapitel erklärt — in Kapitel 11.5 haben wir Ihnen den Unterschiend zwi-schen Referenztypen und primitiven Typen erläutert. Genau dieser Unterschiedist es, der bewirkt, daß das Array in der Methode verändert, die int–Variablejedoch nicht.Wenn Java einen Methodenaufruf sieht, so erzeugt es für jeden Parameter derMethode eine Variable und weist diesen die übergebenen Variablen zu.Wenn Sie sich noch an die Ausführungen über die Referenztypen erinnern, sollteIhnen nun sofort einleuchten, warum die Variable des primitiven Datentyps nichtverändert und die Array-Variable verändert wurde.

12.9 Zusammenfassung

Sie sollten nun die folgenden Fragen beantworten können:

• Was ist der Unterschied zwischen Klassen- und Instanzvariablen ?

• Was ist der Unterschied zwischen Klassen- und Instanzmethoden ?

• Auf welche Variablen kann in einer Klassenmethode zugegriffen werden ?Auf welche Variablen kann in einer Instanzmethode zugegriffen werden ?

• Wie greift man auf eine Klassenvariable zu, wie greift man auf eine In-stanzvariable zu ?

• Wie unterscheidet sich ein Klassenkörper von einem Anweisungsblock ?

• Wie definiert man Klassenvariablen und Instanzvariablen ?

• Wie unterscheiden sich Klassenmethoden und Instanzmethoden ?

109

Page 110: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

• Wie definiert man einen Konstruktor und was tut er ?

• Unter welchen Umständen dürfen innerhalb einer Klasse mehrere gleich-namige Instanz- oder Klassenmethoden definiert sein ?

• Besprechen Sie die Unterschiede zwischen Primitiven Datentypen und Re-ferenztypen bei der Wertübergabe an eine Methode.

13 Dokumentieren von Java–ProgrammenEs ist sehr wichtig, seine Programme zu dokumentieren, denn wenn Sie Ihre Pro-gramme in einigen Monaten nochmal anschauen, wissen Sie meist nicht mehr,wozu diese oder jene Klasse da ist und was welche Methode oder Variable tut.Üblicherweise schreibt man seine Dokumentation in den Klassencode. Wennman dann später etwas über eine Klasse in Erfahrung wissen will, kann manden Quelltext öffnen und lesen.Zur Erzeugung übersichtlicher Dokumentation gibt gibt es für Java das Werk-zeug javadoc. Diese extrahiert die Dokumentation aus einer Klasse und schreibtsie in Html–Dateien, welche dann mit einem WWW–Browser betrachtet werdenkönnen. Auf diese Weise kann man seine eigenen Klassen mit einer Hypertext–Dokumentation16 versehen.Sie haben bereits die Dokumentation des Java–API kennengelernt. Sie wurdemit diesem Werkzeug erzeugt. Wäre das Java–API nicht in Form von HTML–Dateien oder einem anderen Hypertext–Format dokumentiert, wäre es sicherschwerer, sich darin zurechtzufinden.

13.1 Wie arbeitet javadoc ?

Javadoc nimmt eine oder mehrere Java–Quelltextdateien entgegen und erzeugtaus diesen Dokumentation im HTML–Format. Die erzeugten Dateien dokumen-tieren die angegebenen Klassen, Methoden und Instanzvariablen. Zur Doku-mentation werden dabei in den Quelltexten gefundene besondere Kommentareverwendet, welche man auch javadoc–Komentare nennt.Ein javadoc–Kommentar sieht aus wie ein normaler mehrzeiliger Kommentar,nur beginnt er nicht mit den Zeichen /* sondern mit den Zeichen /**.Ein Javadoc–Kommentar könnte so aussehen:

/*** Ein Javadoc -- Komentar*/

Jeder gefundene Javadoc–Kommentar wird von Javadoc als Dokumentation dernachfolgenden Klasse, Instanzvariable, Klassenvariable oder Methode interpre-tiert.Um javadoc zu starten, geben Sie auf der Kommandozeile den Befehl “javadoc”gefolgt von den Namen aller zu verarbeitenden Dateien ein:

16Unter Hypertext versteht man einen Text, in welchem man sich mit Hilfe von Mausklickszwischen einzelnen Textteilen bewegen kann

110

Page 111: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

> javadoc datei1.java datei2.java ...

Um alle Dateien in einem Verzeichnis zu dokumentieren könnten Sie eingeben:

> javadoc *.java

Beispiel: Am besten schauen wir uns die Arbeit von javadoc an einemBeispiel an. Die folgende Klasse tut keine sinnvollen Dinge, zeigt aber denEinsatz von javadoc–Kommentaren:

Klasse DemoDoca

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/KapJavaDoc/DemoDoc.java

Bitte speichern Sie die obige Datei in einem eigenen Verzeichnis, wechselnin das Verzeichnis und geben dann ein:

> javadoc -private DemoDoc.java

Hieraufhin werden mehrere HTML–Dateien erzeugt, von denen uns zu-nächst nur die DemoDoc.html–Datei interessiert. Sie beschreibt die Klas-se. Am besten sehen Sie sich die Datei in einem WWW–Browser an.Schauen Sie sich auch die anderen erzeugten Dateien an.Die Option -private im obigen Befehl haben wir deshalb verwendet, weilSie sich vermutlich noch nicht mit dem Zugriffsschutz von Objektattribu-ten auskennen — normalerweise läßt man das Wort -private weg. Dannerscheinen in der Html–Ausgabe nur Methoden und Variablen, die entwe-der als “public” oder als “protected” definiert sind.

Im fünften Hausaufgabenblock ist ein Beispiel mit mehreren Klassen enthalten,welches mit javadoc dokumentiert ist. Nachdem Sie dieses Beispiel durchgear-beitet haben, sollte Ihnen der Umgang mit Javadoc sofort einsichtig werden.Zu Javadoc gibt es in der von Sun bereitgestellten Dokumentation des Java–APIweitere Informationen, die hier nicht wiederholt werden sollen. Wenn Sie selberJavadoc–Kommentare schreiben wollen, schauen Sie dabei am besten entwederauf der lokalen WWW–Seitehttp://www.tu-bs.de:82/wir/EIP/jdk1.1.8/docs/tooldocs/solaris/javadoc.html

oder auf der WWW–Seite von Sun aufhttp://www.javasoft.com/products/jdk/1.1/docs/tooldocs/solaris/javadoc.html

nach.

13.2 Zusammenfassung

Nach Lesen dieses Kapitels

• sollten Sie wissen, was javadoc tut,

• wie man javadoc einsetzt,

• wie es prinzipiell arbeitet und

• wo Sie weitere Informationen zu javadoc erhalten können.

111

Page 112: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

14 Vererbung — Extensionen von KlassenSie haben bisher Klassen als Mittel kennengelernt, um Konzepte im Computerals Einheit von Daten und Verhalten zu repräsentieren. Die objektorientierteMethodik wäre heute nicht so verbreitet, wenn das Zusammenfügen von Datenund Methoden der einzige Zweck von Klassen wäre.Die objektorientierte Methodik wird erst dadurch zu einem mächtigen Werk-zeug, daß wir gleichartiges Verhalten verschiedener Klassen in einer abstrakterenKlasse zusammenfassen können.Um mehrere Klassen zu einer abstrakteren zusammenzufassen, suchen wir nachKlassen, die im Rahmen unserer Anwendung ähnliche Aufgaben haben oderähnliche Dinge beschreiben. Dann abstrahieren wir von diesen Klassen und er-arbeiten ein gedankliches Konzept, welches die entscheidenden Merkmale unddas gemeinsame Verhalten dieser Klassen enthält.Dieses Konzept implementieren wir dann als Klasse. Dabei wird alles Verhal-ten, das den ursprünglichen Klassen gemeinsam ist, in der abstrakteren, über-geordneten Klasse implementiert. Das gemeinsame Verhalten muß dann nichtmehrfach in jeder der spezielleren Klassen implementiert werden sondern kannvon der abstrakteren Klasse übernommen (man sagt auch “vererbt”) werden.Indem man Verhalten vererbt, spart man sich nicht nur viel Programmierarbeit;die Programme werden auch übersichtlicher und leichter wartbar.

14.1 Ein einführendes Beispiel

Angenommen, wir schreiben ein Spiel, in welchem die Hauptfigur verschiedeneFahrzeuge wie Auto, LKW, Fahrrad oder Kutsche verwenden soll. Jedes die-ser Fahrzeuge kann von der Hauptfigur des Spiels gefahren werden, und diemotorisierten Fahrzeuge müssen tanken, sobald der Tank leer ist.Wir könnten nun 4 verschiedene Klassen bilden:

Auto

double geschwindigkeitdouble tankFuellstand

void fahren()void tanken()

LKW

double geschwindigkeitdouble tankFuellstand

void fahren()void tanken()

Fahrrad

double geschwindigkeit

void fahren()

Kutsche

double geschwindigkeit

void fahren()

All diese Klassen beschreiben ein Fahrzeug, und vermutlich wäre die fahren()–Methode in allen Klassen ähnlich. Wir können daher diese vier Klassen ineiner abstrakteren Klasse zusammenfassen, welche wir Fahrzeug nennen. DieFahrzeug–Klasse würde dabei alle Attribute und Methoden enthalten, welchemit dem eigentlichen Vorgang des fahrens zusammenhängen. Sie enthielte alsodas Attribut geschwindigkeit und die Methode fahren().Auch die tanken()–Methode in den Klassen Auto und LKW wären annäherndidentisch (sie würde den Füllstand des Tanks hochsetzen). Wir können daherdie Attribute und Methoden, die mit dem Tanken zusammenhängen in einergemeinsamen Klasse namens Motorisiertes Fahrzeug zusammenfassen.Eine Klasse Unmotorisiertes Fahrzeug würden wir übrigens nicht einführen, dawir in den Klassen Fahrrad und Kutsche kein eigenständiges Verhalten beschrie-ben haben, das man allen unmotorisierten Fahrzeugen zuschreiben könnte.

112

Page 113: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Das Verhältnis zwischen all diesen Klassen sieht nun wie folgt aus: Jedes Autound jeder LKW ist ein Motorisiertes Fahrzeug. Jedes Motorisierte Fahrzeugist auch ein Fahrzeug. Wir meinen hiermit, daß jede Instanz der Klasse Autound jedes LKW–Objekt gleichzeitig auch eine Instanz der Klasse MotorisiertesFahrzeug ist. Jedes Objekt der Klasse Motorisiertes Fahrzeug ist gleichzeitig einObjekt der Klasse Fahrzeug.Auch jedes Objekt der Klasse Fahrrad oder Kutsche ist gleichzeitig ein Objektder Klasse Fahrzeug.Wir können diese Beziehungen in einem Diagramm darstellen. Wenn jede In-stanz der Klasse B auch eine Instanz der Klasse A ist, machen wir einen Pfeilvon Klasse B zu Klasse A. Das resultierende Klassendiagramm sieht wie folgtaus:

Auto LKW

Motorisiertes Fahrzeug

double tankFuellstand

void tanken()

Fahrrad Kutsche

Fahrzeug

double geschwindigkeit

void fahren()

Wir verwenden im weiteren folgende Begriffe:

Elternklasse/Vorfahre Eine Klasse A ist eine Elternklasse oder ein Vorfahre vonKlasse B, wenn jedes Objekt von Klasse B gleichzeitigObjekt von Klasse A ist.Im vorigen Beispiel ist die Klasse Motorisiertes FahrzeugElternklasse von Auto und LKW . Die Klasse Fahrzeugist eine Elternklasse der Klassen Motorisiertes Fahrzeug,Fahrrad Kutsche, Auto und LKW .Dabei ist die Fahrzeug–Klasse nur indirekter Vorfahreder Klassen Auto und LKW aber direkter Vorfahre derKlassen Fahrrad, Kutsche und Motorisiertes Fahrzeug.

Super–Klasse Ein anderer Begriff für Elternklasse oder Vorfahre.Erweiterung Eine Klasse B ist eine Erweiterung von Klasse A, wenn

Klasse A eine Elternklasse für Klasse B ist.Im obigen Beispiel ist die Fahrrad–Klasse eine Erweite-rung der Fahrzeug–Klasse; die Auto–Klasse ist eine Er-weiterung der Klasse Motorisiertes Fahrzeug und eineErweiterung der Klasse Fahrzeug.

Kindklasse Ein anderer Begriff für Erweiterung.

113

Page 114: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Extension Ein anderer Begriff für Erweiterung.erben Eine Klasse B erbt von Klasse A, wenn sie eine Erweite-

rung von Klasse A ist. Wenn eine Kindklasse von einerElternklasse erbt, so übernimmt sie alles in der Eltern-klasse beschriebene Verhalten.

Wir haben ein Java–Programm vorbereitet, welches die obige Klassenhierarchieimplementiert. Es ist allerdings zum Abdrucken etwas lang — wir besprechenes mit weiteren Beispielen in Kapitel 14.6.

14.2 Erweitern von Klassen

Eine Erweiterung einer Klasse Elternklasse wird definiert, indem im Klassenkopfder Text extends Elternklasse angefügt wird:

class Kindklasse extends Elternklasse {// Klassenkoerper}

Der Effekt ist ungefähr der gleiche als hätten Sie alle Definitionen aus demKlassenkörper der Elternklasse in Ihre neue Klasse Kindklasse kopiert.Die Kindklasse enthält dann alle in der Elternklasse vorgenommenen Definitio-nen plus die im Klassenkörper der Kindklasse getätigten Definitionen.

Beispiel:

Beispiel: Erweitern einer Klasse

1 class Point {2 double x, y;3 void move(double dx, double dy) {4 x+=dx;5 y+=dy;6 }7 }89 class LabeledPoint extends Point {

10 String label;11 void setLabel(String newLabel) {12 label = newLabel;13 }14 }

Die Klasse Point stellt einen Punkt mit Koordinaten (x, y) dar, welcherdurch die move–Methode verschoben werden kann.Die Klasse LabeledPoint stellt einen Punkt dar, welcher zusätzlich eineBeschriftung trägt. Indem in Zeile 9 die Klasse LabeledPoint als Erweite-rung der Klasse Point definiert wird, übernimmt LabeledPoint alle Defini-tionen der Klasse Point. Ein ähnliches Ergebnis hätten wir also erhalten,wenn wir die Klasse LabeledPoint wie folgt definiert hätten:

114

Page 115: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Beispiel: Erweiterte Klasse

1 class LabeledPoint2 {2 double x, y;3 String label;45 void move(double dx, double dy) {6 x+=dx;7 y+=dy;8 }9

10 void setLabel(String newLabel) {11 label = newLabel;12 }13 }

Die Übernahme von Definitionen aus der Elternklasse geschieht nach folgendenRegeln:

• Wenn eine Kindklasse eine Elternklasse erweitert, so werden bis auf Kon-struktordefinitionen alle Definitionen der Elternklasse übernommen (Siekönnen davon jedoch einige Definitionen ausnehmen — wie das geht, er-fahren Sie im Kapitel über “Zugriffsschutz: private, protected, public”).Die Kindklasse erhält somit alle Instanzvariablen, Klassenvariablen, In-stanzmethoden und Klassenmethoden der Elternklasse. All diese Dingehaben in der Kindklasse die gleiche Definition wie in der Elternklasse.

• Definitionen der Elternklasse können in der Kindklasse verdeckt werden,indem eine Definition gleicher Signatur vorgenommen wird (das wird imnächsten Beispiel klar). Man sagt hierzu auch, daß eine Definition “über-schrieben” wird.Zwei Variablen haben dabei die gleiche Signatur, wenn sie den gleichenNamen haben. Zwei Methoden besitzen die gleiche Signatur, wenn sie dengleichen Namen haben und die gleichen formalen Parameter entgegenneh-men.

• Beim Vererben werden alle Definitionen, die die Elternklasse selbst ge-erbt hat, weiter vererbt. Hat die Elternklasse eine Methode oder Variablemit einer neuen Definition überschrieben, so wird nur die überschriebeneVersion der Elternklasse weitervererbt.

14.3 Überschreiben von Methoden

Wie schon erwähnt, können Methoden und Variablen in der Unterklasse über-schrieben werden — da es sich in der Regel nicht empfiehlt, Variablen einesgewissen Typs mit einer Variable eines anderen Typs zu überschreiben, gehenwir hier nur auf das Überschreiben von Methoden ein.Eine Methode in der Oberklasse wird immer dann überschrieben, wenn in derUnterklasse eine Methode mit gleicher Signatur definiert wird. Dabei habenzwei Methoden die gleiche Signatur, wenn sie den gleichen Namen haben unddie gleichen Parameter entgegennehmen.

115

Page 116: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Beispiel:

Beispiel: Methoden überschreiben

1 class Point {2 double x, y;34 String getDescription() {5 return "Punkt";6 }7 }89 class LabeledPoint extends Point {

10 String label;1112 String getDescription() {13 return "Punkt mit Label";14 }15 }

Hier wird die getDescription()–Methode überschrieben. Objekte der Klas-se LabeledPoint liefern daher beim Aufruf der getDescription()–Methodeimmer den Text “Punkt mit Label” zurück.

Beispiel: Methoden überladen

1 class Point {2 double x, y;34 String getDescription() {5 return "Punkt";6 }7 }89 class LabeledPoint extends Point {

10 String label;1112 String getDescription(boolean outputFlag) {13 if( outputFlag ) {14 return "Punkt mit Label";15 } else {16 return "";17 }18 }19 }

Hier wird die getDescription()–Methode nicht überschrieben, da diegetDescription–Methode in der Klasse LabeledPoint nicht die gleiche Si-gnatur wie in der Klasse Point hat.

Die objektorientierte Methodik ist zum Teil deshalb so mächtig, weil ererbteRoutinen in der Lage sind, überschriebene Routinen aufzurufen. Um dies zuverstehen, stellen Sie sich den Methodenaufruf am besten als das Verschickenvon Botschaften vor:Immer wenn ein Objekt eine Botschaft erhält, schaut es nach, ob in seiner Klasseeine Methode für diese Botschaft definiert ist. Wenn ja, benutzt es diese Metho-de. Wenn nein, schaut es in seiner Oberklasse nach und benutzt gegebenenfallsdie dort definierte Methode. Wenn auch in seiner Oberklasse keine passendeMethode definiert ist, so schaut es in der Oberklasse seiner Oberklasse nachund so weiter.Entscheidend ist hier, daß das Objekt dies für jede Botschaft tut, die es erhält,

116

Page 117: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

selbst wenn die Botschaft in seiner Oberklasse abgesetzt wurde. Schauen Siesich das folgende Programmfragment an:

Beispiel: Überschreiben und Botschaften

1 class Point {2 double x, y;34 String getDescription() {5 return "Punkt (" + x + "," + y + ")";6 }78 void output() {9 System.out.println( getDescription() );

10 }11 }1213 class LabeledPoint extends Point {14 String label;1516 String getDescription() {17 return "Punkt mit Label:" + label;18 }19 }

Was passiert in diesem Beispiel, wenn man einem Objekt der Klasse LabeledPointdie Botschaft “output()” schickt ? Sie müssten die Frage bereits beantwortenkönnen.Hier die Antwort: Zuerst schaut das LabeledPoint–Objekt in seiner Klasse nach,ob es dort eine Methode namens output() findet. Da das nicht der Fall ist,schaut es dann in seiner Oberklasse Point nach und findet dort die output()–Methode von Zeile 8–10. Nun wird der Programmtext dieser output()–Methodeausgeführt.Bei der Ausführung des Programmtextes wird in Zeile 9 an das Objekt dieBotschaft getDescription() geschickt. Obwohl dies im Programmtext der KlassePoint geschieht, ist unser Objekt immer noch ein Objekt der Klasse LabeledPoint.Es schaut daher zuerst in der LabeledPoint–Klasse nach und findet dort diegetDescription()–Methode aus Zeilen 16–17. Nun führt es den in der LabeledPointenthaltenen Programmtext der getDescription()–Methode aus.Es ist also ohne weiteres möglich, daß in der Oberklasse definierte MethodenProgrammtext aufrufen, der in den Unterklassen überschrieben wurde. Es istdaher möglich, in einer Oberklasse sehr abstrakt formulierten Programmtext zuschreiben und die Details erst in den Unterklassen einzusetzen.

14.4 Die super–Variable

Das Überschreiben von Methoden wird dann zum Problem, wenn man die über-schriebene Methode weiterverwenden möchte — oft verändert die überschrei-bende Methode das Verhalten der überschriebenen Methode nur minimal, undso möchte man die Möglichkeit haben, die überschriebene Methode zu verwen-den und vielleicht ihr Resultat zu modifizieren.Um dies zu ermöglichen, trägt jedes Objekt in sich eine Variable namens super.Immer wenn man innerhalb des Objektes diese Variable anspricht, spricht mandas Objekt als Instanz seiner Oberklasse an.

117

Page 118: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Beispiel: Verwendung von super

1 class Point {2 double x, y;34 String getDescription() {5 return "Punkt (" + x + "," + y + ")";6 }78 void output() {9 System.out.println( getDescription() );

10 }11 }1213 class LabeledPoint extends Point {14 String label;1516 String getDescription() {17 return super.getDescription() + " mit Label: " + label;18 }19 }

Im obigen Programmtext benutzen wir in der überschreibenden getDescription()–Routine die super–Variable, um die überschriebene getDescription()–Methodevon Zeile 4–6 aufzurufen.Die super–Variable ermöglicht also den Zugriff auf überschriebene Methoden.

14.5 Vererbung und Konstruktoren

Wie schon erwähnt, erbt ein Objekt von seiner Oberklasse alle Definitionen,nicht aber Konstruktoren. Es ist aber häufig nötig, Konstruktoren der Ober-klasse aufzurufen.Hier ein Beispiel:

Beispiel: Vererbung und Konstruktoren

1 class Point {2 double x, y;34 Point( double newX, double newY ) {5 x = newX;6 y = newY;7 }89 }

1011 class LabeledPoint extends Point {12 String label;1314 LabeledPoint( double newX, double newY, String newLabel ) {15 x = newX;16 y = newY;17 label = newLabel;18 }19 }

Dieser Programmtext ist nicht besonders gut. Wir haben im LabeledPoint–Konstruktor nämlich Programmtext wiederholt, der eigentlich in die Klase Pointgehört. Damit greifen wir auf Interna der Klasse Point zu, die die vererbteKlasse nicht zu interessieren haben (Kinder sollten nicht alle Geheimnisse derEltern kennen, das gilt auch beim objektorientierten Programmieren). Wenn

118

Page 119: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

sich später irgendwann der Konstruktor für Point ändert, müssten wir auch denProgrammtext für den LabeledPoint–Konstruktor ändern.Statt dessen sollten wir den Konstruktor der Oberklasse direkt verwenden. Diesgeschieht auch mit Hilfe des super–Schlüsselwortes, allerdings wird es jetzt nichtwie vorhin als Variable sondern als Methode verwendet:

Beispiel: Konstruktoren der Oberklasse aufrufen

1 class Point { double x, y;23 Point( double newX, double newY ) {4 x = newX;5 y = newY;6 }78 }9

10 class LabeledPoint extends Point {11 String label;1213 LabeledPoint( double newX, double newY, String newLabel ) {14 super(x,y);15 label = newLabel;16 }17 }

Immer wenn in einem Konstruktor einer Unterklasse ein Methodenaufruf na-mens super(...) steht, so wird der zu den angegebenen Parametern passendeKonstruktor der Oberklasse aufgerufen.Sie können diese Art des Konstruktor–Aufrufes übrigens nur in Konstruktorenverwenden.

14.6 BeispieleBeispiel: Point und LabeledPointDas folgende Beispiel besteht aus drei Klassen, welche sich alle in einergemeinsamen Datei befinden. Sie können das Beispiel ausführen, indemSie auf der Kommandozeile javac Points.java und dann java Demo ein-geben.

Beispiel: Überschreiben von Methodena

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/Vererbung/ex1/Points.java

Die Klasse Point repräsentiert einen Punkt im zweidimensionalen Raum.Sie besitzt unter anderem eine Methode output(), welche eine Beschrei-bung des Punktes ausgibt. Um die Beschreibung zu ermitteln, wird aufdie Methode getDescription() zurückgegriffen.Von der Klasse Point wird in Zeilen 23–38 eine Klasse namensLabeledPoint abgeleitet. Objekte dieser Klasse haben durch Vererbungalle Variablen und Methoden, die auch die Objekte der Point–Klassebesitzen. Dabei werden alle Definitionen der Oberklasse bis auf diegetDescription()–Methode direkt übernommen.Die getDescription()–Methode wird in Zeilen 35–37 erneut definiert

119

Page 120: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

und überschreibt so die getDescription()–Methode der Oberklasse Point.Immer wenn nun in einem Objekt der Klasse LabeledPoint diegetDescription()–Methode aufgerufen wird, wird diese überschriebene Me-thode benutzt.

Beispiel: Das Beispiel vom AnfangAm Anfang des Kapitels haben wir Klassenhierarchien am Beispiel ver-schiedener Fahrzeuge eingeführt. Wir haben ein dazu passendes Java–Programm entwickelt, welches zum Abdrucken leider zu groß ist.Sie sollten es austesten, sich ausdrucken und lesen. Sie starten das Pro-gramm, indem Sie die Klasse FahrzeugDemo.java kompilieren und aus-führen. Sie finden das Programm unterhttp://www.wire.tu-bs.de/lehre/eipclasses/Vererbung/Fahrzeug/.Dieses Beispiel besteht aus den Klassen Fahrzeug, MotorisiertesFahrzeug,Auto, Fahrrad, LKW und Kutsche. Vergleichen Sie die Klassenstrukturder Programme bitte mit dem Diagramm am Anfang des Kapitels.

Beispiel: Geometrische ObjekteHier eine kleine Klassenhierarchie zur Modellierung geometrischer Objek-te. Starten Sie das Beispiel, indem Sie javac Demo.java und dann javaDemo eingeben.Beachten Sie, wie wir die Interna der Objekte kapseln — wir vermeidendirekte Zugriffe auf die Instanzvariablen von GeomObjekt und verwendenstatt dessen die getX() und getY()–Methoden. Hierdurch erhalten wirFlexibilität, wenn wir irgendwann mal in einer Unterklasse die Art undWeise verändern möchten, wie die Position berechnet wird.Es empfiehlt sich sehr, Zugriffe auf Instanzvariablen durch entsprechendeget– bzw. set– Methoden zu erledigen. Beachten Sie auch die Klasse Linie— sie erbt nicht nur von GeomObjekt sondern verwendet auch noch imKonstruktor ein zweitesGeomObjekt, um den Linienvektor zu bestimmen.

Beispiel: Geometrisches Objekta

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/Vererbung/Geom/GeomObjekt.java

Beispiel: Punkta

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/Vererbung/Geom/Punkt.java

Beispiel: Liniea

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/Vererbung/Geom/Linie.java

120

Page 121: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Beispiel: Demoa

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/Vererbung/Geom/Demo.java

14.7 Die Object-Klasse

Zu Java gehört eine spezielle Klasse namens Object. Wannimmer Sie eine Klassedefinieren, welche nicht explizit von einer anderen Klasse erbt, fügt der Java–Compiler automatisch eine Vererbung von Object ein.Wenn Sie eine Klasse

class MeineKlasse {// Klassenkörper

}

definieren, so wird das vom Java–Compiler übersetzt als

class MeineKlasse extends Object {// Klassenkörper

}

Es ist also unmöglich, eine Klasse zu schreiben, die nicht zumindest indirekt vonObject erbt. Die meisten von Object geerbten Methoden sind nur mit größeremWissen über Java zu verstehen.Schauen Sie sich bitte im Java–API die Klasse Object an. Sie erhalten die Do-kumentation, indem Sie unter

http://www.tu-bs.de:82/wir/EIP/jdk1.1.8/docs/api/packages.html

auf das Paket java.lang und dann auf die Klasse Object klicken.

14.8 Abstrakte Klassen

Häufig führt man Klassen ein, von denen man überhaupt nicht plant, Instanzenzu erzeugen.Möchte man beispielsweise geometrische Objekte wie Linien, Rechtecke undPunkte in einem gemeinsamen Konzept zusammenfassen, so könnte man eineKlasse GeometrischesObjekt definieren.In der Klasse GeometrischesObjekt könnte die Intelligenz zum Verschieben vongeometrischen Objekten enthalten sein. Dieses Verhalten wäre für alle geome-trischen Objekte gleich und sollte daher in der Klasse GeometrischesObjektrealisiert werden.Allerdings würde man vermutlich niemals eine Instanz vonGeometrischesObjekterzeugen, da dies nur ein abstraktes Konzept ist — Sie wissen, wie man eine Linieoder ein Rechteck zeichnet, aber welches Verhalten soll das abstrakte KonzeptGeometrischesObjekt beim Zeichnen an den Tag legen ?

121

Page 122: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Java bietet spezielle Unterstützung für abstrakte Klassen. Eine abstrakte Klas-se ist eine Klasse, in der zwar alle nötigen Methodenköpfe definiert sind, inder einige Methoden jedoch noch keinen Methodenkörper besitzen. Von einerabstrakten Klasse weiß man somit zwar, wie man jede Methode aufruft undwelchen Zweck jede Methode hat, aber da die Klasse nur ein abstraktes Gedan-kenmodell ist, weiß man nicht, welches Verhalten die Methoden zeigen sollen.Eine abstrakte Methode wird definiert, indem der Methodenkörper ausgelassenund vor den Methodenname das Wort “abstract” gesetzt wird. Beispielsweisekönnte eine abstrakte Methode namens draw wie folgt definiert werden:

abstract void draw();

Sobald eine Klasse mindestens eine abstrakte Methode enthält, muß auch dieKlasse als abstract definiert werden. Dies geschieht, indem in die Klassendefini-tion das Wort “abstract” gesetzt wird:

abstract class GeometrischesObjekt {

double x, y;

void move(double dx, dy) {x+=dx; y+=dy;

}

abstract void draw();}

Eine abstrakte Klasse ist zum Erweitern gedacht. Für die Extensionen einerabstrakten Klasse gilt: Entweder füllt die Extension jede abstrakte Methodeder Oberklasse mit einem Methodenkörper, oder auch die Extension muß alsabstrakte Klasse definiert werden.Es ist nicht möglich, Instanzen abstrakter Klassen zu erzeugen. Es ist jedochmöglich, Variablen abstrakter Klassen zu definieren. Diese Variablen könnendann Instanzen der Unterklassen aufnehmen.

Beispiel: Im folgenden Beispiel wird eine abstrakte Klasse namensGeometrischesObjekt definiert, welche eine abstrakte draw–Methode so-wie Verhalten zum Verschieben eines geometrischen Objektes enthält.Von dieser abstrakten Klasse werden zwei konkrete Klassen, Punkt undLinie vererbt. Die Klasse Demo zeigt, wie man Variablen abstrakter Klas-sen verwenden kann.

Beispiel: Geometrisches Objekta

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/Vererbung/Geom2/GeomObjekt.java

Beispiel: Punkta

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/Vererbung/Geom2/Punkt.java

122

Page 123: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Beispiel: Liniea

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/Vererbung/Geom2/Linie.java

Beispiel: Demoa

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/Vererbung/Geom2/Demo.java

14.9 Zuweisung an Variablen und Arrays

Jedes Objekt ist eine Instanz all seiner Oberklassen. Dies erschliesst vielfältigeMöglichkeiten beim Umgang mit Variablen und Arrays. Angenommen, es seiendie folgenden drei Klassen definiert:

abstract class GeometrischesObjekt { ... }class Linie extends GeometrischesObjekt { ... }abstract class Flaeche extends GeometrischesObjekt { ... }class Rechteck extends Flaeche { ... }class Dreieck extends Flaeche { ... }

In diesem Fall ist jedes Rechteck–Objekt auch eine Flaeche– und eineGeometrischesObjekt–Instanz. Da GeometrischesObjekt automatisch von der Object–Klasse erbt, istjedes Rechteck–Objekt auch eine Instanz der Klasse Object.Die folgenden Definitionen sind daher gültig:

Object einObj = new Rechteck();GeometrischesObjekt einGeoObj = new Rechteck();Flaeche eineFlaeche = new Rechteck();Rechteck einRechteck = new Rechteck();

Sie dürfen jedes Objekt an Variablen seiner Oberklassen zuweisen. Dies ist ei-gentlich logisch, denn jedes Objekt IST auch ein Objekt seiner Oberklassen:Jedes Rechteck ist ein Object, jedes Rechteck ist ein GeometrischesObjekt, undjedes Rechteck ist eine Flaeche; daher sind die obigen Definitionen gültig.Die folgenden Definitionen hingegen sind allesamt ungültig:

Rechteck einRechteck1 = new Flaeche(); // FehlerRechteck einRechteck2 = new Object(); // FehlerRechteck einRechteck3 = new Dreieck(); // Fehler

Daß diese Definitionen ungültig sind, sollte einleuchten — denn in unseremVererbungsbaum ist zwar jedes Rechteck eine Flaeche, aber nicht jede Flaecheist ein Rechteck. Auch ist zwar jedes Rechteck ein Object aber nicht jedes Objectein Rechteck.Es ist nun ohne weiteres möglich, Arrays zu erzeugen, welche Objekte verschie-dener Klassen aufnehmen (man spricht hier auch von “polymorphen Arrays”).Das folgende Programmfragment ist korrekt:

123

Page 124: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Dreieck einDreieck = new Dreieck();Rechteck einRechteck = new Rechteck();Flaeche eineFlaeche = new Rechteck();

GeometrischesObject[] meinArray = new GeometrischesObject[3];meinArray[0] = einDreieck;meinArray[1] = einRechteck;meinArray[2] = eineFlaeche;

Was kann man nun mit den Objekten anstellen, die man in Variablen einerOberklasse gespeichert hat ? Man kann ihnen natürlich Botschaften schicken,aber der Java–Compiler achtet sehr darauf, daß man jedem Objekt nur dieBotschaften schickt, die es sicher verstehen kann.Angenommen, in der GeometrischesObjekt–Klasse sei eine Methode Methodedraw() definiert, welche ein geometrisches Objekt auf dem Bildschirm zeichnet,und welche in den erbenden Klassen durch das spezielle benötigte Verhaltenüberschrieben wird.In diesem Fall könnte der obige Programmtext wie folgt fortgesetzt werden:

for(int i=0; i < meinArray.length(); i++) {meinArray[i].draw();

}

Hier würde das Array durchlaufen und jedes gespeicherte Objekt würde diezugehörige draw()–Methode ausführen. Auf diese Art und Weise könnte maneine ganze Sammlung von geometrischen Objekten zeichnen ohne sich darum zukümmern, ob das gerade gezeichnete Objekt ein Dreieck, Rechteck oder sonstwasist — das jeweilige Objekt weiß ja immer selbst, wie es zu zeichnen ist.Es ist hingegen nicht möglich, einem Objekt Botschaften zu schicken, die nureine Unterklasse versteht. Angenommen, ein Dreieck–Objekt besitze eine Me-thode Linie getHypothenuse(), welche in einem Linie–Objekt die Hypothenusezurückliefere. Die Klasse GeometrischesObjekt besitze keine solche Methode.In diesem Fall wäre der folgende Programmtext ungültig:

GeometrischesObjekt einGeomObj = new Dreieck();Linie eineLinie = einGeomObj.getHypothenuse(); // Fehler

Können Sie schon beantworten, warum der Programmtext ungültig ist ? Inder Variable “einGeomObj” ist ein Dreieck gespeichert, und da ein Dreieck dieBotschaft “getHypothenuse()” versteht, sollte doch alles in Ordnung sein.Berücksichtigen Sie aber, daß wir “einGeomObj” als GeometrischesObjekt defi-niert haben. Der Compiler weiß in der zweiten Zeile daher lediglich, daß wir aneine Variable des Typs GeometrischesObjekt die Botschaft “getHypothenuse()”schicken, und da in der Klasse GeometrischesObjekt keine derartige Methodeexistiert, läßt er das nicht zu.Wenn Sie wissen, daß ein Objekt ein Objekt einer gewissen Klasse enthält,können Sie einen Type–Cast verwenden. Der folgende Programmtext ist gültig:

GeometrischesObjekt einGeomObj = new Dreieck();Linie eineLinie = (Dreieck)einGeomObj.getHypothenuse(); // ok

124

Page 125: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Durch den Type–Cast “(Dreieck)” sagen wir dem Compiler: Compiler, wir ma-chen hier schon das korrekte, gehe davon aus, daß in einGeomObj ein Objektder Klasse Dreieck steht.Der Compiler würde in solch einem Fall keinen Fehler melden. Wenn wir hierbeiaber einen Fehler machen, entsteht während der Laufzeit des Programms einFehler:

GeometrischesObjekt einGeomObj = new Quadrat();Linie eineLinie = (Dreieck)einGeomObj.getHypothenuse();

Das obige Fragment ist so kompilierbar, da wir durch den Type–Cast die Über-prüfung durch den Compiler ausgeschaltet haben. Wenn das Programm abläuft,merkt das Laufzeitsystem aber, daß hier versucht wird, ein Quadrat als Drei-eck zu betrachten. Das Programm würde dann einen Fehler ausgeben und sichbeenden.

Beispiel: Das folgende Beispiel demonstriert eine Verwendung des Type–Cast–Operators

Beispiel: TypeCast–Demoa

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/Vererbung/Cast/CastDemo.java

Hier wird in Zeile 36–39 ein Object[]–Array definiert, in welchem ver-schiedene Objekte gespeichert werden. Außerdem wird in Zeile 35 ein Ar-ray definiert, in welchem beschrieben ist, was für ein Objekt an welcherPosition des Object–Arrays liegt.Beide Arrays werden an die Methode output übergeben. Diese Methodedurchläuft das Object[]–Array und führt für jeden Eintrag basierend aufder Information im desc–Array einen Type–Cast aus. Dann führt es injedem gecasteten Objekt eine spezielle Methode aus.

14.10 Zusammenfassung

Nach Lesen dieses Kapitels sollten Sie

• erklären können, welche Vorteile Vererbung bietet.

• anhand von Beispielen die Vorzüge von Vererbung demonstrieren können.

• die Begriffe, Extension, erben, Super–Klasse, Elternklasse, Erweiterung,direkter/indirekter Nachkomme erklären können.

• beschreiben können, wie man in Java Extensionen schreibt.

• erklären können, was beim Vererben in Java passiert.

• beschreiben können, was es bedeutet, eine Methode zu überschreiben, undwie man überschriebene Methoden der Oberklasse aufrufen kann.

• sich Gedanken darüber gemacht haben, was es bedeutet, daß Konstrukto-ren nicht vererbt werden.

125

Page 126: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

• erklären können, wie man Konstruktoren einer Kindklasse schreiben sollte.

• die Beispiele in Kapitel 14.6 verstanden haben und Fragen dazu beant-worten können.

• beschreiben können, an Variablen welchen Typs man Objekte zuweisenkann.

• erklären können, warum man nicht direkt alle Methoden von Objektenaufrufen kann, die in einer Variable der Oberklasse gespeichert sind.

• beschreiben können, wie und warum man im Rahmen von Vererbung denType–Cast–Operator einsetzen kann.

• sich überlegen, ob und warum der Einsatz von Type–Cast–Operatorengefährlich sein kann.

15 PackagesZu Java gehören sehr viele verschiedene Klassen. Um nicht die Übersicht zuverlieren, werden Klassen mit ähnlichem Zweck gemeinsam zu größeren Paketen,sogenannten “packages” zusammengeschnürt.Um einen weiteren Zweck von Paketen klarzumachen, stellen Sie sich vor, Siehätten eine Klasse namens Y2K erstellt, welche alle Millenium–Bugs vertreibtund wollten diese Klasse verkaufen. Stellen Sie sich nun vor, ein potentiellerKunde habe bereits eine eigene Klasse namens Y2K erstellt, benutze diese inseinem Programm und wolle nicht auf sie verzichten.Was tun ? Sie könnten natürlich ihre Klasse umbenennen. Aber selbst wenn siesie umbenennen, könnte es einen Namenskonflikt mit einem anderen Kundengeben.Eine Lösung, derartige Namenskonflikte gar nicht erst zum Problem werden zulassen, sind packages. Ein package oder Paket enthält beliebig viele Klassen.Die in einem package enthaltenen Klassen kann man ansprechen, indem manhinter den Namen des packages einen Punkt und dann den Namen der Klassesetzt.Wenn zum Beispiel ein Paket den Namen de.tubs.cs.sc.akeese hat und in demPaket eine Klasse namens Y2K enthalten ist, so könnte man die Klasse alsde.tubs.cs.sc.akeese.Y2K ansprechen.Es ist üblich, Paket–Namen aus der Internet–Adressierung einer Firma zu ge-nerieren. Wenn die Firma SUN (www.sun.com) eine Erweiterung zu Java ent-wickelt, welche nicht im Java–Kern enthalten ist, so würde diese Erweiterung ineinem Paket namens com.sun.paketname enthalten sein.Da Internet–Adressen eindeutig sind, wird so sichergestellt, daß Pakete unter-schiedlicher Firmen unterschiedliche Namen enthalten. Somit haben auch in derRegel Klassen verschiedener Firmen verschiedene Namen und sind deshalb ge-meinsam einsetzbar.Alle zu Java gehörigen Klassen sind in Paketen enthalten, die mit dem Text“java” beginnen. So gibt es ein Paket java.awt, in welchem alle Bestandteiledes “Abstract Windowing Toolkits” enthalten sind, es gibt ein Paket java.math,

126

Page 127: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

in welchem spezielle mathematische Klassen enthalten sind, und viele mehr.Das wichtigste Paket ist das Paket java.lang, in welchem die wichtigsten Java–Klassen wie z.B. String oder Object enthalten sind.Wir wollen hier nicht weiter darauf eingehen, wie man packages erstellt, möchtenIhnen jedoch erläutern, wie man packages benutzt.Um eine in einem Paket enthaltene Klasse anzusprechen, müssen Sie vor denNamen der Klasse jedesmal den Namen des Paketes setzen. Wenn der Paketnamelang ist, wird das eine ganze Menge Schreibarbeit. Stellen Sie sich vor, stattString müssten Sie jedesmal java.lang.String schreiben.Man kann daher die in einem Paket enthaltenen Namen in ein Programm im-portieren. Dazu setzt man an den Anfang der Datei den Text

import paketname.*;

Hierdurch werden alle in dem jeweiligen Paket enthaltenen Klassen importiertund sind in Zukunft ansprechbar, ohne daß Sie den Paketnamen vor den Klas-sennamen setzen müssen.Wenn Sie nur einzelne Klassen eines Paketes importieren wollen, können Siestatt des Sterns auch für jede zu importierende Klasse einen einzelnen import–Befehl angeben, etwa so:

import paketname.klasse1;import paketname.klasse2;

Beispielsweise enthält das Paket java.util die Klasse Dictionary. Wenn Sie dieseKlasse benutzen wollen, haben Sie zwei Möglichkeiten:Sie können die Klasse direkt verwenden:

class MeineKlasse {

java.util.Dictionary einDict;

public static void main( String[] args ) {java.util.Dictionary aDict = new java.util.Dictionary();

}}

Alternativ können Sie die Klasse auch importieren und können dann eine kürzereSchreibweise wählen:

import java.util.*; // oder import java.util.Dictionary

class MeineKlasse {

Dictionary einDict;

public static void main( String[] args ) {Dictionary aDict = new Dictionary();

}}

127

Page 128: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Es ist übrigens nicht nötig, Inhalte des java.lang–Paketes zu importieren. Da diedort enthaltenen Klassen so häufig benutzt werden, wird es automatisch in jedesProgramm exportiert. Der Java–Compiler fügt automatisch in jedes kompilierteProgramm den Befehl

import java.lang.*;

ein.Eine Übersicht über die zu Java gehörigen Pakete finden Sie in der Dokumen-tation zum Java API unter

http://www.tu-bs.de:82/wir/EIP/jdk1.1.8/docs/api/packages.html

Bitte klicken Sie sich dorthin, indem Sie von unseren WWW–Seiten unter denLitaturlinks zu Java auf den relativ weit unten stehenden Link “Java–Api (lo-kal)” klicken.Bitte schauen Sie sich auf dieser WWW–Seite um, klicken Sie dort auf dasPackage java.lang und schauen Sie sich die Dokumentation der Object–Klassein java.lang an.

15.1 Zusammenfassung

Nach Lesen dieses Kapitels sollten Sie

• erklären können, welche Vorteile ein Package bietet.

• den import–Befehl kennen.

• wissen, was am java.lang–Paket besonders ist.

• eine Übersicht der zu Java gehörenden Packages aufrufen können.

16 ExceptionsZur Behandlung unerwarteter Situationen bietet Java Unterstützung in Formvon Exceptions oder Ausnahmen.Den Sinn von Exceptions können wir Ihnen an einem kleinen Beispiel klarma-chen. Nehmen Sie an, wir schreiben eine Methode, in welcher durch eine Zahlgeteilt werden muß — es könnte etwa aus der zurückgelegten Distanz und ei-nem Zeitintervall berechnet werden, mit welcher Geschwindigkeit sich ein Autobewegt. Eine erste Fassung einer entsprechenden Methode könnte wie folgt aus-sehen:

Beispiel: Methode mit einem Fehler

1 static int geschwindigkeit( int distanz, int dauer )2 {3 return distanz / dauer;4 }

Diese Methode wird problematisch, wenn von außen eine Dauer von 0 Sekundenangegeben wird, etwa im Aufruf

128

Page 129: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

int speed = geschwindigkeit( 10, 0 );

Was soll in solch einem Fall geschehen — in der Methode würde nun offensicht-lich versucht, durch 0 zu teilen. Dies wiederum würde einen Fehler erzeugen,welcher das Programm beenden würde.Nun ist es nicht besonders wünschenswert, daß ein Programm sich einfach been-det, wenn irgendwo ein ungültiger Zahlenwert erscheint. Das Programm solltezumindest die noch nicht gespeicherten Daten speichern und Aufräumarbeitendurchführen (etwa die vom Programm erzeugen 5 Gigabyte temporärer Datenvon der Festplatte löschen).Noch schöner wäre es natürlich, wenn das Programm einen Fehler melden würde.Man könnte nun vor jedem Aufruf der Funktion überprüfen, ob die Eingabeda-ten in Ordnung sind. Es ist aber durchaus denkbar, daß vor dem Aufruf einerMethode nicht von außen prüfbar ist, ob sie durchführbar ist — stellen Sie sicheine Methode vor, welche auf eine Diskette zugreifen will. Hier hinge es davonab, ob eine Diskette im Laufwerk liegt, ob die Methode funktioniert oder nicht.Beim Programmieren kommt es immer wieder zu Situationen, in denen uner-wartete Daten oder unerwartete Ereignisse (Ausnahmen) vorliegen. Wenn eineAusnahme auftritt, muß sie entweder dort, wo sie aufgetreten ist, behandelt wer-den, oder sie muß weitergegeben werden, so daß ein anderer Programmteil eineMöglichkeit hat, auf die Ausnahme zu reagieren. Wird die Ausnahme nirgendsbehandelt, bleibt als einzige Alternative der Abbruch des Programms mit einemFehler.

16.1 Try–catch

Der try–catch–Block bietet eine Möglichkeit, Programmtext auszuführen, in wel-chem Ausnahmen auftreten könnten. Dabei ist eine Ausnahme ein Objekt einergewissen Klasse, welches erzeugt wird, wenn eine unerwartete Situation aufge-treten ist.Sie können sich das wie folgt vorstellen: An einer Stelle der Programmausfüh-rung tritt eine unerwartete Situation auf (z.B. Teilen durch Null, Diskette fehltim Laufwerk). Als Reaktion auf diese Situation wird ein Ausnahme–Objekt er-zeugt, welches die aufgetretene Situation genauer beschreibt. Dieses Ausnahme–Objekt wird nun weitergereicht (“geworfen”), bis irgendwo Programmtext ge-funden wird, welcher das Ausnahmeobjekt auffängt und dann die Ausnahmebehandelt. Wird kein Programmtext gefunden, der das Ausnahmeobjekt fängt,wird das Programm mit einer Fehlermeldung beendet.Eine Ausnahme kann nur gefangen werden, wenn sie innerhalb eines try–catch–Blocks auftritt. Die try–catch–Anweisung ermöglicht erst das Einfangen derAusnahmeobjekte und schützt so einen gewissen Programmtextbereich vor ei-nem ungewollten Programmabbruch. Man verwendet einen try–catch–Block, in-dem man den Programmtext, in welchem Ausnahmen–Objekte geworfen werdenkönnten, in einen try–Block setzt und dann für jeden Ausnahmetyp, der einge-fangen werden soll, hinter den geschützten Block eine catch–Anweisung setzt:

try {geschuetzte Anweisungen;...

129

Page 130: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

} catch ( Ausnahmetyp1 x ) {Ausnahme-Anweisungen für Ausnahmetyp 1;...

} catch ( Ausnahmetyp2 x ) {Ausnahme-Anweisungen für Ausnahmetyp 2;...

}

Der Block zwischen dem try und dem ersten catch ist hierdurch vor jeder Aus-nahme geschützt, welche durch eine der catch–Anweisungen aufgefangen werdenkann.Sofern im geschützten Block eine Ausnahme auftritt (wie man selbst Ausnahmenerzeugt, erzählen wir gleich noch), wird die Ausführung des geschützten Blockssofort abgebrochen, und die Ausführung wird in demjenigen Block ausgeführt,welcher auf das passende catch folgt.Was da genau passiert, wird nach dem folgenden Beispiel sicher klarer:

Beispiel: Beispielsweise entsteht in Java beim ganzzahligen Teilen durch0 eine Ausnahme des Typs ArithmeticException. Das folgende Programmdemonstriert, wie man einen Programmteil vor einer solchen Ausnahmeschützen kann:

Beispiel: Exceptions 1a

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/Except/ExcDemo1.java

Der Programmtext von Zeile 6 bis Zeile 8 ist durch den umschliessen-den try–Block und das folgende catch–Statement vor einem Programmab-bruch durch alle Ausnahmen des Typs ArithmeticException geschützt.Beim Ablauf des Programmtextes entsteht in Zeile 7 beim Teilen durch0 ein ArithmeticException–Objekt, welches dann als Ausnahme geworfenwird. Dadurch bricht die Ausführung von Zeile 7 sofort ab. Da in Zeile 9 ei-ne catch–Anweisung für Ausnahmeobjekte des Typs ArithmeticExceptionsteht, wird das Programm dann in Zeile 10 fortgesetzt.Das gefangene ArithmeticException–Ausnahmeobjekt kann in Zeile 10 un-ter der Variable e angesprochen werden.

Durch die Aneinanderreihung mehrerer catch–Blöcke kann man unterschiedlicheAusnahmen fangen und auf die unterschiedlichen Ausnahmen auch unterschied-lich reagieren.

Beispiel:Spricht man in einem Array nicht existierende Indizes an,so wird eine ArrayOutOfBoundsException geworfen. DieKlasse ArrayOutOfBoundsException erbt von der KlasseIndexOutOfBoundsException.Im folgenden Programm wird sowohl das Teilen durch 0 als auch dasVerwenden eines zu großen Index abgefangen:

130

Page 131: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Beispiel: Exceptions 2a

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/Except/ExcDemo2.java

16.2 Ausnahmen werfen

Ausnahmen entstehen entweder durch die mißbräuchliche Verwendung von Java–Anweisungen oder dadurch, daß im Programmtext eine Ausnahme geworfenwird. Die bei der fehlerhaften Verwendung von Java–Anweisungen entstehen-den Ausnahmen sind im Java–API im java.lang–Paket beschrieben.Alle Ausnahmen müssen indirekt oder direkt von der Klasse Throwable erben.Von dieser Klasse vererben sich unter anderem die Klasse Exception, und vonException ist eine Klasse RuntimeException abgeleitet. Alle Ausnahmen, diebei fehlerhafter Verwendung von Java–Anweisungen auftreten kommen, sindvon RuntimeException erbende Objekte.Wenn Sie selbst Ausnahmen definieren wollen, so sollten Sie diese in der Regelvon der Klasse Exception oder einer ihrer Unterklassen ableiten (schauen Siesich die genannten Klassen bitte in der JDK–Dokumentation an).Sie können selbst Ausnahmen werfen, indem Sie ein Objekt der Klasse Throwableoder ein Objekt einer Unterklasse von Throwable erzeugen und dann mit derthrow–Anweisung die Ausnahme auslösen.

Exception myException = new Exception("Meine Ausnahme");throw myException;

oder kürzer:

throw new Exception();

Beispiel: So können Sie selbst eine Exception werfen und wieder fangen:

Beispiel: Throw 1a

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/Except/ThrowDemo1.java

16.3 Exceptions in Methoden

Wenn bei der Ausführung einer Methode A eine Ausnahme geworfen wird, wel-che nicht in der Methode selbst gefangen wird, so wird die Methode beendet. DieAusnahme wird dann an die Stelle übergeben, an der die Methode A aufgerufenwurde. Dort wird die Ausnahme erneut geworfen.Wurde die Methode A aus einer anderen Methode B aufgerufen, so gibt eszwei Möglichkeiten: Wenn der Aufruf der Methode A in Methode B von einemtry–catch–Block geschützt wurde, welcher die erzeugte Ausnahme fangen kann,

131

Page 132: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

so wird das Programm im zugehörigen catch–Block fortgesetzt. Wurde der Me-thode A jedoch ungeschützt aufgerufen, so wird Methode B abgebrochen, unddie Ausnahme wird dort erneut geworfen, wo Methode B aufgerufen wurde.Dies setzt sich fort, bis ein try–catch–Block gefunden wird, welcher die gewor-fene Ausnahme fängt. Wird kein try–catch–Block gefunden, der die Ausnahmebehandelt, so wird das Programm mit einer Fehlermeldung abgebrochen.

Beispiel: Im folgenden Beispiel wird in der geschwindigkeit–Routine eineException geworfen, wenn versucht wird durch 0 zu teilen. Die Ausnahmewird in der main–Methode gefangen.

Beispiel: Exceptions in Methodena

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/Except/MethodsDemo1.java

Wenn eine Methode eine Ausnahme zurückgibt, welche nicht zu den Java–Laufzeitausnahmen gehört, muß dies im Kopf der Methode vermerkt werden.Die Java–Laufzeitausnahmen (dies sind alle Ausnahmen, welche von der Klassejava.lang.RuntimeException vererbt sind) wird dies deshalb nicht gefordert, weildiese Ausnahmen fast jederzeit auftreten können und daher fast jede Methodeeine RuntimeException werfen kann. Wäre aber im Kopf einer jeden Methodenvermerkt, daß sie eine Java–Laufzeitausnahme werfen kann, so wäre das keinbesonderer Informationsgewinn.In einer Methode wird im Methodenkopf beschrieben, welche Ausnahmen ihreAusführung erzeugen kann, indem hinter der Kopfdeklaration der Text

throws Ausnahmetyp1, ... , AusnahmetypN

folgt.

Beispiel:Im folgenden Beispiel wirft die geschwindigkeit–Methode eine eigene Aus-nahme. Da diese Ausnahme keine Java–Laufzeitausnahme ist, muß sie imMethodenkopf durch die throws–Klausel deklariert werden. Wir deklarie-ren hier auch überflüssigerweise, daß die Routine eine ArithmeticExcep-tion (dies ist eine Java–Laufzeitausnahme) werfen kann.

Beispiel: Eigene Exceptions in Methodena

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/Except/MethodsDemo2.java

Wenn in einer Methode A eine Methode B aufgerufen wird, welche eine Ausnah-me von Typ X (abgesehen von RuntimeExceptions) erzeugen kann, so muß dievon B erzeugte Ausnahme entweder innerhalb der Methode A gefangen werden,oder im Methodenkopf von A muß vermerkt sein, daß Methode A eine Ausnah-me vom Typ X werfen kann. Andernfalls wird ein Kompilierfehler erzeugt.

132

Page 133: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

So wird sichergestellt, daß jede Methode, welche Ausnahmen werfen kann, diesim Methodenkopf vermerkt.

Beispiel:Das folgende Beispiel kompiliert nicht korrekt. Der Compiler beschwertsich, daß die Methode test eine DistanzException werfen kann, ohne daßdas im Kopf der Methode vermerkt ist.

Beispiel: Eigene Exceptions in Methodena

aSiehe http://www.wire.tu-bs.de/lehre/eipclasses/Except/MethodsDemo3.java

Wir können das Beispiel reparieren, indem wir den Kopf der test–Methodewie folgt ändern:

public static void test() throws DistanzException

Wir könnten das Beispiel auch reparieren, indem wir in der test–Methodeeinen try–catch–Block einfügen. Die test–Methode sähe dann so aus:

public static void test() {try {

System.out.println( geschwindigkeit(11,3) );} catch( DistanzException e ) {

System.out.println("Habe Ausnahme gefangen: " + e);}

}

16.4 Ein paar abschließende Bemerkungen

Immer wenn Sie Klassen aus dem Java–API benutzen wollen, so müssen Siein der Dokumentation des Java–API nachsehen, ob die von Ihnen verwendetenMethoden eine Ausnahme werfen können. Wenn ja, so müssen Sie sich in IhremProgramm um diese Ausnahme kümmern.Wir haben nicht alle Aspekte von Ausnahmen besprochen. Wenn Sie sich dafürinteressieren, lesen Sie es bitte im Buch Go To Java 2 (Kapitel 9) oder sonstirgendwo nach.

16.5 Zusammenfassung

Nach Lesen dieses Kapitels sollten Sie

• erklären können, was eine Ausnahme ist.

• Beispielsituationen nennen können, in denen Ausnahmen auftreten.

• erklären können, wie Ausnahmen in Java repräsentiert werden.

• den try–catch–Befehl erklären können.

133

Page 134: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

• beschreiben können, wie Ausnahmen behandelt werden, die innerhalb einerMethodenausführung auftreten.

• beschreiben können, was man beim Schreiben von Methoden berücksich-tigen muß, in denen Ausnahmen entstehen können.

• erläutern können, was man beachten muß, wenn man JDK–Funktionenverwendet, die Ausnahmen werfen können.

A Anhang: Unix, Editor und CIP-Pool

A.1 Hinweise zu weiterer Unix-Literatur

Sie sollten zuerst das Don’t Panic-Heftchen des Rechenzentrums lesen, um dieGrundlagen von Unix kennenzulernen.Zusätzlich empfiehlt es sich, auf die in den Seiten des Rechenzentrums ange-botene Dokumentation zu schauen. Insbesondere möchten wir Sie auf folgendeDokumente hinweisen:

• Verzeichnis der vom Rechenzentrum angebotenen Dokumente17

• Don’t Panic online18

• Dokumentation zu Unix19

A.2 Editoren

A.2.1 Der nedit-Editor

Um Programmtexte zu schreiben, benötigen Sie einen Editor. Wir empfehlenIhnen, den nedit Editor zu verwenden. Denn wenn Sie bereits mit Windowsoder DOS gearbeitet haben, werden Sie ihn sehr schnell verwenden können.Sie starten ihn, indem Sie auf einer Unix-Shell

> nc &

eingeben (Das Größerzeichen sollten Sie dabei nicht miteingeben; wir verwendenes hier nur, um zu verdeutlichen, daß Sie etwas eingeben sollen). Nach demStart lesen Sie in seinem Hilfe-Menü bitte die Abschnitte Getting Started undProgramming with NEdit (letzteres finden Sie im Untermenü des Hilfe-MenusFeatures for programming).Weitere Dokumentation finden Sie auf folgenden Seiten:

• Dokumentation im Rechenzentrum20

• Dokumentation zu nedit (FU Berlin; engl.)21

• Regular Expressions in nedit (eher ein Thema für Fortgeschrittene)2217http://www.tu-bs.de/rz/doku/18http://www.tu-bs.de/rz/doku/panic.html19http://www.tu-bs.de/rz/doku/unix-pages/kap0-unix.html20http://www.tu-bs.de/rz/software/nedit/neditdoc.htm21http://www.chemie.fu-berlin.de/chemnet/use/nedit.html22HTTP://www.iti.cs.tu-bs.de/soft/nedit/hlp11.html

134

Page 135: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

A.2.2 Der Emacs-Editor

Der Editor Emacs ist vermutlich der mächtigste Editor überhaupt. Seine Bedie-nung ist für MS Windows-Kenner nicht sofort einsichtig, und das Kennenlernendes Emacs deutlich länger, als den Umgang mit nedit zu lernen.Dafür werden Sie niemals wieder einen anderen Editor benötigen, wenn Sie ihnerstmal schätzen gelernt haben. Sie sollten sich mit dem Emacs allerdings nurdann auseinandersetzen, wenn Sie etwas Zeit haben und wissen, daß Sie auch inZukunft Programme schreiben werden.Starten Sie ihn von der Unix-Shell per

> emacs &

Anschließend sollten Sie das Emacs-Tutorial durcharbeiten. Sie starten es, indemSie nach dem Start des Emacs die Tastenkombination Strg+h (auf englischenTastaturen ist die “Strg”-Taste mit “Ctrl” bezeichnet) und danach die Taste“t”drücken .Weitere Hilfe zum Emacs finden Sie hier:http://www.cs.tu-bs.de/softech/info/

A.3 Das Hilfe-System

Unter Unix-Systemen sind mehrere Hilfesysteme verfügbar. Gerade beim Pro-grammieren ist es wichtig, sich mit diesen Systemen auszukennen, da man desöfteren die Aufrufkonventionen von Bibliotheksfunktionen nachschlagen muß.

A.3.1 Der man-Befehl

Um Hilfe zu einem Unix-Befehl zu erhalten, können Sie den man-Befehl verwen-den. Hierzu geben Sie beim Aufruf des man-Befehls als Argument den Namendes Unix-Kommandos, zu dem Sie Hilfe wünschen.Sie können auch zum man-Befehl Hilfe erhalten, und das wollen wir gleich malausprobieren. Geben Sie ein:

> man man

Wenn Sie im CIP-Pool arbeiten, erscheint nun zuerst ein Hilfetext zum apropos-Befehl (dieser ist ein Bestandteil des man-Befehls), aber wenn Sie mit der Leer-taste weiterblättern, erscheint etwas weiter unten auch Hilfe zum man-Befehl.Diese Hilfe verlassen Sie durch drücken der Taste “q”.Um den Umgang mit man zu trainieren, schauen Sie sich bitte auch die Hilfe zuanderen Unix-Kommandos an. Wenn Sie Hilfe zum Kopier-Befehl cp oder zumDirectory-Anzeigekommando ls wünschen, probieren Sie aus:

> man cp> man ls

Es gibt übrigens auch eine graphische Version des man-Befehls. Um diese zustarten, geben Sie im CIP-Pool ein:

> xman &

135

Page 136: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

A.3.2 Der Apropos-Befehl

Die oben beschriebene Form des man-Befehles hat einen Nachteil: Sie können sichnur Informationen zu einem Kommando geben lassen, wenn Sie schon dessenNamen kennen.Wenn Sie einen Befehl suchen, der eine gewisse Aufgabe erledigt, dessen Na-men Sie aber nicht kennen, können Sie das apropos Kommando, gefolgt voneinem Schlüsselwort, verwenden. Daraufhin werden die Kurzbeschreibungen al-ler durch man dokumentierten Kommandos durchsucht. Alle Kommandos, inderen Beschreibung dies Schlüsselwort auftaucht, werden aufgelistet.Wenn Sie ganz allgemein nach Hilfe suchen, könnten Sie zum Beispiel einen derfolgenden Befehle ausprobieren:

> apropos help> apropos info> apropos manual

Sie erhalten bei jedem apropos-Befehl eine Liste von zum Schlüsselwort passen-den Kommandos mit einer Kurzerklärung angezeigt.Diese Beispiele demonstrieren, daß Sie je nach gewählten Schlüsselwort unter-schiedliche Kommandos angezeigt bekommen. Selbst wenn ein Befehl sinngemäßetwas mit dem Hilfesystem zu tun hat, nennt apropos help ihn nur dann, wennin seiner Kurzbeschreibung auch das Wort help vorkommt. Man muß dahermanchmal ein wenig mit unterschiedlichen Schlüsselwörtern rumprobieren, bisman einen Befehl gefunden hat.Außerdem zeigen diese Beispiele, daß apropos auch unerwartete Antworten lie-fert - so hat der Befehl apropos manual auch die Zeile

route(1) - Manually manipulates the routing tables

angezeigt. Das hat nichts mit manuals zu tun, aber weil in der Beschreibungdie Zeichenkette “manual” vorkommt, hat der apropos-Befehl auch dieses Kom-mando angezeigt.Ein weiteres Beispiel: Angenommen, Sie suchen nach einem Befehl, der eineEingabe sortiert. Also geben Sie ein

> apropos sort

Irgendwo in der Anzeige findet sich die Zeile

sort(1) - Sorts files, merges files that are already sorted, andchecks files to determine if they have been sorted.

So haben wir also herausgefunden, daß man zum sortieren einer Textdatei densort-Befehl verwenden kann. Bevor man den Befehl verwenden kann, brauchtman natürlich noch detailliertere Hilfe:

> man sort

136

Page 137: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

A.4 Ausgabeumleitung

Als nächstes wollen wir Sie mit Ausgabeumleitung bekannt machen. Ausga-beumleitung ist ein Weg, mehrere Unix-Programme miteinander zu kombinie-ren. Eine für das Programmieren hilfreiche Anwendung ist z.B. das Blätternoder Suchen in Ausgaben des Compilers oder anderer Werkzeuge.Fast alle Unix-Shell-Programme arbeiten wie folgt: Sie nehmen Eingaben ausIhrem Eingabekanal entgegen, verarbeiten diese und geben Sie auf ihrem Ausga-bekanal aus. Ein Eingabekanal kann z.B. eine Datei, Eingaben eines Benutzersoder Ausgaben eines anderen Programms sein. Ein Ausgabekanal kann z.B. derBildschirm, eine Datei oder der Eingabekanal eines anderen Programms sein.Normalerweise wählt jedes Unix-Programm als Eingabekanal die Tastatur undals Ausgabekanal den Bildschirm. Nehmen wir beispielsweise den Befehl cat. Erkopiert alle Daten aus seinem Eingabekanal zu seinem Ausgabekanal. Probierenwir das aus:

> cat

Sie erhalten nun einen blinkenden Cursor. Geben Sie irgend etwas ein unddrücken die Return-Taste. Als Ergebnis wird Ihre Eingabe ein zweites Mal aus-geben. Als Sie Return gedrückt haben, hat cat Ihre Eingabe (von der Tastatur)auf seinen Ausgabekanal (das Bildschirmfenster) kopiert. Die Tatsache, daß Ih-re Eingabe schon beim Tippen auf dem Bildschirm erschien, darf Sie hier nichtstören - damit hatte cat nichts zu tun.Geben Sie noch ein paar Zeilen ein - jedesmal, wenn Sie Return drücken, wirdihre Eingabe abgeschickt und von cat auf die Ausgabe kopiert. Beenden Sie cat,indem Sie die Tasten Strg und “d” gleichzeitig drücken. Die Tastenkombination“Strg+d” bedeutet für cat, daß die Eingabe beendet ist und es zu arbeitenaufhören kann — Hier gleich eine Warnung: Der Tastendruck Strg+d und dasEOF, das sie beim Programmieren mit C kennenlernen werden, sind nicht dasgleiche — allerdings erzeugt “Strg+d” ein EOF.Jetzt wollen wir die Ausgabe von cat umleiten, d.h. wir wollen seinen Ausgabe-kanal verändern. Wenn man die Ausgabe in eine Datei leiten will, so gibt mannach dem umzuleitenden Befehl den Text > dateiname an, wobei “dateiname”für den Namen der Zieldatei steht.Probieren wir das aus:

> cat > testDatei

Geben Sie wieder ein paar Textzeilen, jedesmal gefolgt von Return, ein. Ihnenfällt sicher auf, daß die Textzeilen nach dem Return nicht ein zweites Mal ausge-ben werden. Das war erwartet, da der Ausgabekanal nicht mehr der Bildschirmsondern die Datei testDatei ist. Schließen Sie nach ein paar Zeilen die Eingabeab, indem Sie wieder Strg+d drücken.Benutzen Sie bitte den ls-Befehl, um sich davon zu überzeugen, daß eine Dateinamens testDatei erzeugt wurde. Um den Inhalt dieser Datei am Bildschirmanzuzeigen, benutzen wir wieder cat, leiten diesmal aber nicht die Ausgabesondern die Eingabe um. Dies geschieht, indem man hinter den Befehl den Text> dateiname schreibt. Probieren Sie das bitte aus:

137

Page 138: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

> cat < testDatei

Dies sollte Ihre vorhin angegebenen Zeilen vom Eingabekanal, also der DateitestDatei auf den Ausgabekanal, also den Bildschirm, ausgeben.Das man auch auch kombinieren, um eine eine Datei zu kopieren (in der Praxisverwendet man dafür aber lieber den cp-Befehl):

> cat < testDatei > kopie

Dies liefert keine Ausgabe auf dem Bildschirm. Der Eingabekanal war die DateitestDatei und der Ausgabekanal ging in die Datei kopie. Testen Sie, ob dieDatei auch wirklich kopiert wurde:

> cat < kopie

Übrigens ist dies gleichwertig zu

> cat kopie

Das letzte Beispiel demonstriert eine Eigenschaft vieler Unix-Befehle — oft in-terpretieren Unix-Befehle Parameter als Dateinamen, welche dann zum Ein-oder Ausgabekanal werden.Nun folgen noch ein paar Anwendungen und Beispiele zur Ausgabeumleitung.Das Umleiten von Ein- und Ausgabekanal funktioniert bei fast allen Unix-Programmen. Probieren Sie einfach mal die folgenden Kommandos aus (FallsSie wissen wollen, was der sort-Befehl tut, können Sie sich darüber mit demman-Befehl informieren):

> ls > verzeichnis> cat verzeichnis> sort -r < verzeichnis

Was ist hier passiert ? Wir haben die Ausgabe von ls in eine Datei geleitet undanschließend diese Datei als Eingabekanal an den sort-Befehl gegeben. Dieserhat den Inhalt der Datei absteigend sortiert wieder an seinen Ausgabekanal,den Bildschirm, ausgegeben.Mit Hilfe des |-Operators kann man mehrere Ausgabeumleitungen kombinieren.Der |-Operator leitet den Ausgabekanal eines Programms in den Eingabekanaleines anderen Programms um. Konstrukte der Form

> befehl1 | befehl2

arbeiten ungefähr wie folgende Sequenz von Befehlen, allerdings ohne eine tem-poräre Datei anzulegen:

> befehl1 > temporäreDatei> befehl2 < temporäreDatei

Wir können dies auf das Beispiel, in welchem wir das Verzeichnis sortiert haben,anwenden — probieren Sie bitte folgende Befehle aus:

138

Page 139: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

> ls | sort -r> ls | sort -r > sorted> cat sorted> ls -lF /usr/bin | sort | less

Die letzte Zeile demonstriert, daß man beliebig viele Ausgabeumleitungen hin-tereinanderschalten kann. Hier wird die Ausgabe von ls an sort weitergeleitet,dort sortiert und dann an den less-Befehl weitergegeben.Der less-Befehl gibt die Eingabe seitenweise auf den Bildschirm aus. Sie ver-lassen ihn durch die Taste “q”. Wenn Sie etwas durch den less-Befehl anzeigenlassen, können Sie sich mit den Cursor hoch und Cursor runter-Tasten in derAusgabe bewegen.

A.5 Trennung von Rechner und Bildschirm

Es ist in einigen Praktika aufgefallen, daß viele Studenten einen der genialstenMechanismen von Unix nicht kennen. Darum werden wir hier kurz darauf ein-gehen.Der Monitor, auf dem Ihre Programme angezeigt werden, und der Rechner aufdem Ihre Programme laufen, sind voneinander völlig unabhängig. Auf IhremMonitor hier in Braunschweig könnte ein in München oder in Amerika laufendesProgramm angezeigt werden. Dazu müsste man in München einem Programmbeim Start nur mitteilen, daß es für Ausgaben bitte nicht den lokalen Monitorsondern den Monitor in Braunschweig verwenden soll.Nehmen wir an, Sie sitzen an einem Terminal namens lokalerRechner.rz.tu-bs.deund wollen sich auf den Rechner fremderRechner.rz.tu-bs.de einloggen unddort Programme ausführen, deren Fenster dann bei Ihnen landen sollen.Dazu müssen Sie drei Dinge tun:

1. Zuerst müssen Sie dem anderen Rechner gestatten, auf Ihren Monitor zu-zugreifen. Die Methode, die wir hier beschreiben, ist zwar etwas unsicher,da Sie dem fremden Rechner völligen Zugriff auf Ihren Monitor gewährt,aber sie demonstriert am besten die Trennung von Bildschirm und Rech-ner.Um dem fremden Rechner Zugriff auf Ihren Monitor zu gestatten, gebenSie in einer Unix-Shell auf dem lokalen Rechner ein:

> xhost fremderRechner.rz.tu-bs.de

Damit kann der fremde Rechner Ihren Monitor beschreiben und auch aus-lesen.

2. Anschließend müssen Sie in Erfahrung bringen, wie das Display heißt, aufdem Ihr Rechner seine Fenster momentan öffnet. Dazu geben Sie auf derKommandozeile ein:

> echo $DISPLAY

Daraufhin sollte entweder der Text :0.0 oder ein Text der Form rechnername:0.0ausgeben werden. Merken Sie sich diesen Namen.

139

Page 140: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

3. Anschließend müssen Sie sich auf den fremden Rechner einloggen.

> telnet fremderRechner.rz.tu-bs.de

4. Nachdem Sie sich auf dem fremden Rechner angemeldet haben, müssennoch das Display einstellen, auf das er seine Ausgabe leiten soll.Wenn Sie bei der Ausgabe von

> echo $DISPLAY

vorhin den Text :0.0 erhalten haben, ist der Name des Displays lokalerRechner.rz.tu-bs.de:0.0.Ansonsten ist der Name des Displays der vorhin angezeigte Name.Geben Sie in der telnet-Sitzung23 folgendes ein, wenn vorhin der Name:0.0 angezeigt wurde:

> export DISPLAY=lokalerRechner.rz.tu-bs.de:0.0

oder, wenn vorhin ein anderer Name als :0.0 angezeigt wurde, geben Siehinter dem Gleichheitszeichen den Namen des vorhin angezeigten Displaysan.

> export DISPLAY=name des displays

Anschließend starten Sie irgendein X-Programm, z.B. xclock, um zu te-sten, daß das Umlenken des Displays funktioniert hat:

> xclock

Und hier auch gleich eine Tip: Der Pool ist sehr stark ausgelastet. Wenn Sieim Pool arbeiten und nebenher einen WWW-Browser wie Netscape verwendenwollen, so können Sie sich mit Ihrer y-Nummer auf einem Rechner außerhalbdes Pools einloggen und dann das Display auf Ihren Arbeitsrechner im Poolumlenken. Sie können dann Netscape auf dem entfernten Rechner starten.Und noch ein Tip: Natürlich können Sie sich auf diese Weise auch von anderenRechnern aus im CIP-Pool einloggen. Sie können ohne weiteres in einem Institutoder im Rechenzentrum sitzen, während Sie im Pool im Altbau arbeiten.

B Anhang: Verwendung von Java unter Unix

B.1 Java-Compiler und Laufzeitumgebung

Die Programmierung mit Java geht folgendermaßen vor sich: Sie tippen IhrenProgrammtext mit einem Editor ein und speichern ihn irgendwo in Ihrem Home-verzeichnis. Der Programmtext kann von einem Computer aber nicht verstandenund muß erst in eine vom Computer verstandene Form übersetzt (kompiliert)werden.

23wir gehen davon aus, daß Sie die bash–Shell benutzen

140

Page 141: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Das Programm, welches Ihren Quelltext in eine vom Computer verstandeneForm übersetzt, nennt sichCompiler. Der Java-Compiler hat eine Besonderheit— er erzeugt zwar für einen Computer verständlichen Code, aber der erzeugteCode ist für keinen existierenden Computer verständlich.Der Java-Compiler erzeugt Code — den sogenannten Java Bytecode, der voneinem sogenannten virtuellen Computer — der Java Virtual Machine(JVM) — verstanden werden kann. Die Java Virtual Machine ähnelt real exi-stierenden Prozessoren, berücksichtigt dabei aber die besonderen Eigenschaftenvon Java.Zum Java-System gehört nun ein Programm, welches diesen virtuellen Compu-ter auf einem anderen Computer emuliert. Sie müssen also nach dem Kompi-lieren Ihres Quelltextes ein weiteres Programm starten, welches den Bytecodeentgegennimmt und interpretiert.Natürlich kann Java damit nicht so schnell sein wie andere Programmierspra-chen, die direkt Programmcode die jeweilige Zielplattform erzeugen, weil derProzessor niemals Java-Code direkt ausführt. Es gibt allerdings inzwischen Lauf-zeitsysteme, welche welche den Bytecode auf die jeweilige reale Hardware-Plattformkompilieren und dort direkt ausführen können.Die Tatsache, daß Java-Programme nicht auf eine spezielle Zielarchitektur kom-piliert werden, bewirkt also daß Java-Programme nicht so schnell laufen wie inanderen Sprachen entwickelte Software. Dennoch ist die Verwendung der virtu-ellen Maschine ein großer Vorteil und hat den Einsatz von Java im Internet erstermöglicht — hierdurch wird nämlich Systemunabhängigkeit erreicht.In der Theorie läuft ein Java-Programm auf jeder Hardware und jedem Be-triebssystem, für das eine virtuelle Maschine existiert. Man muß sich also nichtmehr entscheiden, ob man ein Programm für Windows, Macintosh, Linux, HP-Unix, Be-OS, OS/2 oder sonst ein Betriebssystem entwickelt. Sobald die virtu-elle Java Maschine auf diesem Betriebssystem vorhanden ist, läuft hierauf jedesJava-Programm identisch (wohlgemerkt: in der Theorie).

B.2 Kompilation

Wir wollen nun ein erstes Programm kompilieren. Bitte tippen Sie dazu folgen-des Programm in einem Editor ein — beachten Sie dabei, Groß und Kleinschrei-bung exakt so wiederzugeben wie hier beschrieben.

public class HalloWelt{

public static void main( String[] args ){

System.out.println("Hallo, Welt");}

}

Sie sollten immer darauf achten, daß der Name einer Programmdatei mit demNamen der enthaltenen Klasse beginnt und auf .java endet. Hier ist der Nameder Klasse “HalloWelt”. Speichern Sie daher den obigen Programmtext in derDatei HalloWelt.java ab.

141

Page 142: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Um die Klasse zu kompilieren, gehen Sie bitte auf eine Unix-Shell und wechselnin das Verzeichnis, in welchem Sie die Datei gespeichert haben. Hier geben Siedann ein

> javac HalloWelt.java

Wenn Sie beim Abtippen einen Fehler gemacht haben, meldet sich der Compilermit einer Fehlermeldung. Lesen Sie bitte die Fehlermeldung aufmerksam —Sie sollten Fehlermeldungen immer aufmerksam lessen — und korrigieren ihnbitte im Editor anschließend den in der Fehlermeldung beschriebenen Fehler.Speichern Sie dann die Datei und kompilieren sie erneut.Wenn Sie beim abtippen keine Fehler gemacht haben, sollte beim Kompilie-ren keine Ausgabe auf dem Bildschirm erzeugt worden sein aber die DateiHalloWelt.class entstanden sein. Prüfen Sie dies bitte nach !Die Datei HalloWelt.class enthält den Bytecode unserer Klasse. Sie könnendas Programm nun laufen lassen, indem Sie die Java-Virtual-Machine mit un-serem kompilierten Programm starten:

> java HalloWelt

Achten Sie bitte darauf, beim Aufruf von java nicht die Erweiterung .classanzugeben. Dann wird ihre Klasse nämlich nicht gefunden.Wenn Sie bis hierher alles nachgemacht haben, sollte der Text “Hallo, Welt” aufdem Bildschirm ausgegeben werden.

B.3 Datentypen

Um dieses Kapitel zu verstehen, sollten Sie den Anhang ?? zum Aufbau einesComputers gelesen haben.Um die Attribute unserer Objekte zu definieren, haben wir bisher Wertebereichewie ganze Zahl, reelle Zahl, Zeichenkette oder Vektor verwendet. Wenn wir inJava die Wertebereiche von Attributen beschreiben, kann man nicht einfacheinen umgangssprachlichen Ausdruck wie “ganze positivie Zahl” verwenden.Der Java-Compiler muß schon etwas genauer wissen, was für Zahlen zu verwen-den sind. Letztendlich muß ja jede Zahl in einem Java-Programm im Speicherdes Computers gespeichert werden. Es sollte einleuchtend sein, daß große Zahlenmehr Platz zur Speicherung benötigen als kleine Zahlen — um eine 20 stelligeZahl aufzuschreiben, benötigt man ja auch mehr Platz als für eine 2 stelligeZahl. Es wäre nun sehr unangebracht, wenn der Java-Compiler jede ganzzahligeZahl

C Probleme

C.1 Probleme bei Verwendung von javac

Beim Kompilieren einer Klassendatei

> javac MeineKlasse.java

142

Page 143: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

treten manchmal folgende Fehlermeldungen auf:

bash: MeineKlasse.java: command not found

Sie haben das “>” Zeichen mit eingegeben. Wenn wir

> javac MeineKlasse.java

schreiben, dann meinen wir damit, daß Sie auf der Kommandozeile den Textjavac MeineKlasse.java eingeben sollen. Das Größerzeichen verbildlicht alsodie Kommandozeile und darf nicht mit eingetippt werden.

error: Can’t read: MeineKlasse.java1 error

Der Compiler findet die Datei nicht. Möglicherweise befinden Sie sich im falschenVerzeichnis oder haben die Datei im Editor noch nicht oder unter einem anderenNamen abgespeichert. Prüfen Sie, ob die Datei vorhanden ist:

> ll MeineKlasse.java

javac: invalid argument: MeineKlasseuse: javac [-g][-O][-debug][-depend][-nowarn][-verbose]

[-classpath path][-nowrite][-deprecation][-d dir][-J<runtime flag>] file.java...

Sie haben statt

> javac MeineKlasse.java

den Befehl

> javac MeineKlasse

eingegeben. Wenn der Name, den Sie an javac übergeben, nicht auf .javaendet, denkt javac, sie wollten ihm besondere Hinweise zur Kompilation geben.

Unable to initialize threads: cannot find class java/lang/Thread

Der Compiler findet die zum Java-System gehörigen Klassen nicht. Ihr Java-Programmiersystem ist nicht korrekt installiert. Sie sollten die Umgebungsva-riable CLASSPATH prüfen. Siehe Anhang E

MeineKlasse.java:1: Class ak.Turtle.TurtleScreen not found in import.import ak.Turtle.TurtleScreen;

^MeineKlasse.java:2: Class ak.Turtle.Turtle not found in import.import ak.Turtle.Turtle;

^2 errors

Der Compiler findet die Turtle–Graphik nicht. Sie sollten die Turtle–Graphikinstallieren und die Umgebungsvariable CLASSPATH prüfen. Siehe Anhang E

143

Page 144: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

C.2 Probleme bei Verwendung von java

Beim Ausführen einer Klasse

> java MeineKlasse

treten möglicherweise folgende Fehler auf:

Can’t find class MeineKlasse.class

Sie haben statt

> java MeineKlasse

das Kommando

> java MeineKlasse.class

verwendet.

In class MeineKlasse: void main(String argv[]) is not defined

Sie versuchen eine Klasse auszuführen, in welcher die main-Methode fehlt. JedeKlasse, die Sie ausführen wollen, benötigt eine solche Methode. (siehe ??).

In class MeineKlasse: void main(String argv[]) is not defined

Sie versuchen eine Klasse auszuführen, in welcher die main-Methode fehlt. JedeKlasse, die Sie ausführen wollen, benötigt eine solche Methode. (siehe ??).

Can’t find class MeineKlasse

Entweder existiert im aktuellen Verzeichnis keine Datei MeineKlasse.class,oder die CLASSPATH–Variable enthält nicht das aktuelle Verzeichnis. Siehe An-hang E

Can’t find class MeineKlasse

Entweder existiert im aktuellen Verzeichnis keine Datei MeineKlasse.class,oder die CLASSPATH–Variable enthält nicht das aktuelle Verzeichnis. Siehe An-hang E

java.lang.NoClassDefFoundError: ak/Turtle/TurtleScreenat MeineKlasse.main(Compiled Code)

Die Turtle–Graphik ist nicht in über die CLASSPATH–Umgebungsvariable zu-gänglich. Siehe Anhang E

144

Page 145: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

D Goldene Regeln fürs ProgrammierenIhre erstellten Javaprogramme sollen nicht nur syntaktisch richtig, sondern auchleicht zu lesen sein. Deshalb sollen Sie von der ersten Zeile an auf einen gutenProgrammierstil achten. Dieser zeichnet sich vor allem dadurch aus, dass ihreProgramme gut gegliedert sind, Kommentare enthalten und von anderen leichtverständlich zu lesen sind. Dadurch vermeiden Sie beim Programmieren Fehlerund ihre Programme sind besser wartbar. Um ihnen von Anfang an einen gutenProgrammierstil beizubringen, möchten wir ihnen folgende Richtlinien mit aufden Weg geben, die für diese Lehrveranstaltung verbindlivh sind.

D.1 Allgemeines

Hier nun ein paar allgemein Regeln auf die in den nächsten Abschnitten nochnäher eingegangen wird.

• Benutzen Sie maximal einen Befehl pro Zeile!

• Verwenden Sie sprechende Bezeichner.

• Folgen Sie bei der Benennung von Bezeichnern vorhersehbaren Konven-tionen.

• Kommentieren Sie die einzelnen Programmteile.

• Benutzen Sie eine sinnvolle und einheitliche Einrückung.

• Trennen Sie Programmteile durch Leerzeilen.

• Teilen Sie ein Programm sinnvoll auf.

• Vermeiden Sie “magic numbers”.

Benennen Sie Klassen nach ihrem Zweck, Variablen nach ihrem Inhalt, Metho-den nach ihrer Aufgabe. Das Programm wird dadurch lesbarer, da es dann nichtmehr notwendig ist, bei jedem Vorkommen eines Bezeichners zu überlegen, wozuder Bezeichner da ist. Lassen Sie nach jedem Schlüsselwort und zwischen denbinären Operatoren ein Leerzeichen frei.

D.2 Quelldateien

Die Quelldateien sollen folgendes Aussehen besitzen:

• Übungskommentar

• package Anweisung

• import Anweisung

• Die als public deklarierte Klasse

• andere Klassen, falls erforderlich

145

Page 146: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Der Übungskommentar besteht aus dem Namen des Studenten, seiner Matri-kelnummer, dem Datum und der Aufgabenstellung. Dieser Kommentar sollteals spezieller “doc Kommentar” dargestellt werden, d. h. er beginnt mit einem/** und endet mit */. Diese werden vom javadoc Programm speziell ausgewer-tet, um eine einfache Onlinedokumentation aus dem Javaquellcode zu erstellen.Nutzen Sie auch die @author und @version tags. Hier ist kleines Beispiel:

/*** Die Klasse Kreise mit ihren Daten und Methoden* Hausaufgabe 3* @author: Harry Hacker* @version 1.2.3 31.04.00*/

Benutzen Sie maximal einen Befehl pro Zeile! Tritt im Programm ein Fehlerauf, kann man seinen Ort häufig schnell auf eine Programmzeile einschränken.Wenn dort dann mehrere Anweisungen stehen, ist eine Lokalisierung des Fehlersschwierig. Auch die Fehlermeldungen des Compilers beziehen sich auf eine Zeile.

D.3 Klassen

Es ist üblich, Klassennamen mit einem Grossbuchstaben beginnen zu lassen.Es empfiehlt sich, englischsprachige Bezeichner zu verwenden, da das gesamteJDK englischsprachig ist. Wo möglich, sollten Ihre Wahl von Bezeichnern denim JDK verwendeten Konventionen folgen.Schreiben Sie als erstes die Variablen und Methoden auf, die als public dekla-riert werden und dann die als private deklarierten.

D.4 Methoden

Jede Methode (ausser main) beginnt mit einem Kommentar im javadoc Format.

/*** Berechnet die Fakultaet von n*/

public int fakultaet(int fac){ . . .}

Vermeiden Sie Programmzeilen, die mehr als 80 Zeichen enthalten und Metho-den mit mehr als 50 Zeilen, da beides die Übersichtlichkeit reduziert. Manchmallässt es sich aber nicht vermeiden, wie z.B. bei langen if/else Anweisungen.Sie sollten jedoch immer komplexe Probleme in kleinere und einfachere Teilpro-bleme unterteilen.

D.5 Variablen, Konstanten und Literale

Benutzen Sie für Variablenbezeichner nur kleine Buchstaben. Setzt sich wegender besseren Lesbarkeit der Variablenbezeichner aus mehreren Wörtern zusam-

146

Page 147: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

men, so können Sie die nächstfolgenden Wörter auch mit einem grossen Buch-staben beginnen lassen, zum Beispiel firstPlayer. Definieren Sie nicht alleVariablen sofort am Anfang eines Blockes,

public static double sqrt(double a){ double xold;

double xnew;boolean more;

. . .}

sondern dann wenn sie das erste mal gebraucht werden.

public static double sqrt(double a){ . . .

while(more){ double xnew = (xold + a / xold) / 2;

. . .}

}

Benutzen Sie für Konstantenbezeichner nur Grossbuchstaben. Werden sie nichtvon anderen Klassen benötigt sollten als private deklariert werden.

privat static final int DAYS_PER_YEAR = 365

Vermeiden Sie im Programmtext die Verwendung von “magic numbers”. Eine“magic number” ist eine Zahl die sie ohne Erklärung in ihrem Quellcode be-nutzen. Definieren Sie statt dessen an einer zentralen Stelle Konstanten undverwenden Sie diese.Wenn Sie ein Array der Grösse 100 dimensionieren, schreiben Sie nicht

int[] daten_Arr = new int[ 100 ]

sondern definieren Sie am Klassenanfang eine Konstante z.B. als

final int SIZE_DATEN_ARR = 100;

und dimensionieren das Array dann als

int[] daten_Arr = new int[ SIZE_DATEN_ARR ];

Wenn sich die Variable SIZE_DATEN_ARR später ändern sollte, sind Sie so aufder sicheren Seite, ausserdem wird der Programmtext durch die Verwendungsprechender Namen besser lesbar.Wenn in einem Programmtext die Zahl π benötigt wird, schreiben Sie diesenicht als 3.14159265358979323846 sondern definieren Sie am Klassenanfang dieKonstante

147

Page 148: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

final static double PI = 3.14159265358979323846;

D.6 Kontrollstrukturen

Benutzen Sie eine sinnvolle und einheitliche Einrückung. Die Einrückung solldie Struktur des Programms deutlich machen. Die Lesbarkeit des Programmswird deutlich erhöht, wenn zusammengehörige Programmteile auch optisch zu-sammen gehören. Achten Sie darauf, dass die Einrückung konsistent ist. DieEinrücktiefe sollte jeweils drei Leerzeichen betragen. Benutzen Sie geschweifteKlammern um die entsprechenden Zugehörigkeiten anzuzeigen, oder um sie zuerzwingen. Bei diesem Beispiel ist nicht eindeutig wohin die else Anweisunggehört.

if (n > 0)if (a > b)

z = a;else

z = b;

Abhilfe erhält man durch das Benutzen von geschweiften Klammern.

if (n > 0){ if (a > b)

z = a;else

z = b;} /* {...} sind hier nicht erforderlich */

if (n > 0){ if (a > b)

z = a;}else

z = b; /* hier sind {...} erforderlich */

Die offene geschweifte und die dazugehörige geschlossene geschweifte Klammersollten entweder in der gleichen Spalte (vertikal) oder in der gleichen Zeile (ho-rizontal) angeordnet sein. Dies erleichtert die Überprüfung ob alle Klammernordentlich gesetzt wurden.

while (i < n) { print(a[i]); i++; }

while (i < n){ print(a[i]);

i++;}

148

Page 149: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

E Installation von Java und Turtle–Graphik

E.1 Installation von Java

Wenn Sie im CIP–Pool arbeiten, ist dies schon für Sie erledigt. Falls Sie zuhausearbeiten wollen, holen Sie sich bitte von Sun24 das JDK 1.2 für Ihr Betriebssy-stem und folgen den Installationsanweisungen.

E.2 Der CLASSPATH

Das JDK besteht aus sehr vielen Programmbausteinen (Klassen), die in auf dieZeichenfolge .class endenden Dateien enthalten sind. Der Name einer Java–Klasse besteht aus einer Pfadangabe und einem Klassennamen. Beispielsweisebezeichnet der Klassenname

eip.TurtleScreen

eine Klasse namens TurtleScreen, welche unter der Pfadangabe eip zu findenist. Da jeder Benutzer die Dateien auf seiner Festplatte unterschiedlich organi-siert, muß Java irgendwie mitgeteilt werden, wo auf der Festplatte nach einerderartigen Klasse gesucht werden soll.Hierzu verwendet Java die CLASSPATH–Umgebungsvariable. Eine Umgebungs-variable ist ein Mittel des Betriebssystems zur Konfiguration von Programmen.Die CLASSPATH–Variable enthält beliebig viele, durch Doppelpunkte getrenn-te Pfadangaben:

CLASSPATH=pfad1:pfad2:pfad3:...:pfadN

Dabei ist eine Pfadangabe entweder ein Verzeichnispfad oder der Name eines.zip–Archives. Ein .zip–Archiv ist eine Datei, welche viele andere Dateienenthält.

Beispiel: Unter Windows könnte eine CLASSPATH–Variable, welche aufdie Verzeichnissse c:\java\jdk\classes.zip, c:\java\turtle und . ver-weist, so ausssehen:

CLASSPATH=.:C:\java\jdk\classes.zip:C:\java\turtle

Unter Unix könnte die CLASSPATH–Variable so aussehen:

CLASSPATH=.:/usr/local/java/jdk/classes.zip:/usr/local/java/turtle/

Wenn Java nach der Klase eip.TurtleScreen sucht, geht es wie folgt vor: Esschaut in jedem im CLASSPATH angegebene Verzeichnis nach, ob es eine Dateiak/Turtle/TurtleScreen.class enthält (unter Windows würde Java schauen,ob es eine Datei ak\Turtle\TurtleScreen.class findet). Die erste derartigeDatei, die in einem Verzeichnis des CLASSPATH gefunden wird, wird dann be-nutzt.

24http://www.java.sun.com/products/

149

Page 150: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Beispiel: Wenn unter Unix der CLASSPATH wie oben angegeben ist, wür-de Java zuerst nachsehen, ob die Datei ak/Turtle/Turtle.class in der.zip–Datei /usr/local/java/jdk/classes.zip enthalten ist.Wenn dies nicht der Fall ist, würde Java nachschauen, ob die Datei/usr/local/java/turtle/ak/Turtle/Turtle.class existiert.Falls auch dies nicht der Fall ist, würde Java nachsehen, ob im aktu-ellen Verzeichnis das Unterverzeichnis ak/Turtle/ und darin die DateiTurtleScreen.class existiert.

Der CLASSPATH wird immer benutzt, wenn Java eine Datei sucht. Ob Sie Javainnerhalb eines Programms durch den Befehl

import eip.TurtleScreen;

anweisen, die Klasse eip.TurtleScreen zu verwenden, oder ob Sie auf der Kom-mandozeile ein Javaprogramm per

> java MeineKlasse

starten — immer wird die Klasse mit Hilfe des CLASSPATH gesucht.Dies kann zu verwirrenden Effekten führen, wenn im CLASSPATH nicht auch dasaktuelle Arbeitsverzeichnis namens „.“ enthalten ist. Denn dann kann Java IhreKlassendatei selbst dann nicht finden, wenn Sie im aktuellen Arbeitsverzeichniszu finden ist.Wenn im Arbeitsverzeichnis die Datei MeineKlasse.java existiert und „.“ nichtim CLASSPATH enthalten ist, so erhalten Sie auf den Befehl java MeineKlassedie Meldung

Can’t find class MeineKlasse

In solch einem Fall nehmen Sie das aktuelle Arbeitsverzeichnis in Ihren CLASSPATHauf.Weiter unten beschreiben wir, wie man den CLASSPATH erweitern kann.

E.3 Installation der Turtle–Graphik

• Um die Turtle–Graphik unter Unix zu installieren, holen Sie sich bittevon unseren WWW–Seiten25 die Datei Turtle.tgz und legen Sie sie inIhr Homeverzeichnis.Legen Sie dann bitte ein Verzeichnis für die Turtle an (z.B. ~/turtle).Dies geht auf der Unix–Kommandozeile per

> mkdir ~/turtle

Dann entpacken Sie die Datei Turtle.tgz wie folgt:

> cd ~> gzip -d Turtle.tgz> cd ~/turtle> tar xvf ~/Turtle.tar

25http://www.tu-bs.de/institute/wir/eip/

150

Page 151: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Prüfen Sie nun, ob die Datei ~/turtle/ak/Turtle/Turtle.java existiert.Anschließend setzen Sie bitte, wie im nächsten Kapitel beschrieben, denCLASSPATH und testen die Turtle durch den Befehl

> java eip.TurtleDemo

• Um die Turtle–Graphik unter Windows zu installieren, holen Sie sich bittevon unseren WWW–Seiten26 die Datei Turtle.zip.Sie benötigen außerdem den Entpacker unzip27 oder Winzip28 (Winzip isteine kommerzielle Software — es ist üblich, daß fast alle unter Unix freierhältliche Software unter Windows Geld kostet).Legen Sie bitte ein Verzeichnis für die Turtle an (z.B. C:\java\turtle).Dies geht entweder mit Hilfe des Explorers oder auf der Windows–Kommandozeileper

> mkdir C:\java\turtle

anschließend entpacken Sie bitte die Datei Turtle.zip hier hinein. AchtenSie dabei darauf, daß beim Entpacken alle Pfade wiederhergestellt werden.Wie das geht, ist in der Dokumentation des Entpackers beschrieben.Sehen Sie nach dem Entpacken nach, ob die Datei

c:\java\turtle\ak\Turtle\Turtle.java

existiert — sonst ist irgendwas schief gegangen.Anschließend setzen Sie bitte, wie im nächsten Abschnitt beschrieben, denCLASSPATH und testen die Turtle durch den Befehl

> java eip.TurtleDemo

E.4 Erweitern des CLASSPATH

Sie können den CLASSPATH wie folgt um weitere Suchpfade erweitern.

• Wenn Sie unter Unix arbeiten und die bash–Shell verwenden, können Sieauf der Kommandozeile eingeben

export CLASSPATH=$CLASSPATH:neuerPfad

Angenommen, Sie haben die Turtle–Graphik im Verzeichnis ~/turtle in-stalliert, so sollten Sie den CLASSPATH wie folgt erweitern:

export CLASSPATH=$CLASSPATH:~/turtle

26http://www.tu-bs.de/institute/wir/eip/27http://www.cdrom.com/pub/infozip/UnZip.html28http://www.winzip.com/

151

Page 152: Begleittext: Einführung in das Programmieren in Java … · Zentraleinheit (CPU) Dateneingabe Arbeitsspeicher Nicht-flüchtiger Speicher: ROM RAM Festplatte Diskette Tastatur Maus

Diesen Befehl müssen Sie jedesmal erneut eingeben, wenn Sie eine Kom-mandozeile öffnen. Sie können den Befehl statt dessen auch als letzte Zeilein die Datei ~/.profile aufnehmen. Dann wird der CLASSPATH bei jedemanmelden automatisch gesetzt.

• Unter Windows können Sie dazu auf der Kommandozeile eingeben

set CLASSPATH=%CLASSPATH%:neuerPfad

Angenommen, Sie haben die Turtle–Graphik im Verzeichnis C:\java\turtle\installiert, so sollten Sie den CLASSPATH wie folgt erweitern:

set CLASSPATH=%CLASSPATH%:C:\java\turtle

Diese Zeile müssen Sie jedesmal eingeben, wenn Sie eine Kommandozeileöffnen. Wenn Sie die obige Zeile als letzte Zeile in die Datei C:\autoexec.bataufnhemen, wird der CLASSPATH bei jedem Neustart von Windows auto-matisch gesetzt.

152