JAVA Einführung in die Programmiersprache - BlueJ unter Verwendung der Entwicklungsumgebung
←
→
Transkription von Seiteninhalten
Wenn Ihr Browser die Seite nicht korrekt rendert, bitte, lesen Sie den Inhalt der Seite unten
Einführung in die
Programmiersprache
JAVA
unter Verwendung der Entwicklungsumgebung
BlueJ
Text von K.Spier (2004),
überarbeitet von B.Spier (2009-2014)JAVA-Einführung, Seite 2 Inhaltsverzeichnis Kapitel 1: Vorstellung der Entwicklungsumgebung BlueJ und erstes Projekt ................................ 3 Installation ..................................................................................................................................... 3 Projekt Beispiel_1 (Quader) ........................................................................................................... 4 Der Editor von BlueJ für JAVA-Quelltexte ...................................................................................... 5 Kapitel 2: Zweites Projekt: Bankkonto (Bank_1) ........................................................................... 8 Erstellen einer vollständigen Übersicht zur Klasse 'Konto' (Dokumentation) ............................. 10 Kapitel 3: Drittes Projekt: Bank_2 ............................................................................................... 11 Informationen zu private und public ........................................................................................... 15 Kapitel 4: Viertes Projekt: Fahrkartenautomat ............................................................................ 16 Zahlen formatieren ..................................................................................................................... 17 Kapitel 5: Fünftes Projekt: Person (Vererbung / GregorianCalendar) ......................................... 18 Vererbung .................................................................................................................................... 21 Überschreiben von Methoden ...................................................................................................... 22 Kapitel 6: Sechstes Projekt: Wir programmieren ein Applet ........................................................ 24 Aufbau eines HTML-Quelltextes .................................................................................................. 25 Kapitel 7: Siebentes Projekt: Das Applet reagiert auf eine Maus-Aktion ..................................... 27 Kapitel 8: Achtes Projekt: Das Puzzle mit 25 Feldern ................................................................. 32 Klassenvariablen und Instanzvariablen ....................................................................................... 32 Array ............................................................................................................................................ 33 For-Schleife ................................................................................................................................. 34 Start und Stop ............................................................................................................................. 34 While-Schleife .............................................................................................................................. 35 Kapitel 9: Was haben wir jetzt gelernt? (Wdh. und kleine Ergänzungen) .................................... 37 (Klassen, Variablen, Methoden, Konstruktoren, Fallunterscheidung, Schleifen) Kapitel 10: Schlussbemerkung ................................................................................................... 39 Anhang ....................................................................................................................................... 40 JAVA-Programm ohne Entwicklungsumgebung erstellen ............................................................ 40 Listen, die nur Instanzen einer einzigen Klasse verwalten............................................................ 41 Formatierungen von numerischen Werten (2 Beispiele für String.format)..................................... 42
JAVA-Einführung, Seite 3
Vorbemerkung
Mit JAVA wurde eine objektorientierte Programmiersprache entwickelt, die unabhängig vom
Betriebssystem des Computers ist, auf dem die Programme laufen. Es gibt viele so genannte
Entwicklungsumgebungen, um JAVA-Programme zu erstellen. Eine Entwicklungsumgebung ist
zwar nicht Voraussetzung zum Programmieren – JAVA-Programme ließen sich auch mit einem
einfachen Texteditor erstellen. Mit einem Compiler können daraus Dateien erstellt werden, die ein
JAVA-Runtime-Environment ausführen kann, solche Datei kann also ein fertiges Programm aufge-
fasst werden. Mit Hilfe einer Entwicklungsumgebung können Quelltexte sowohl erstellt als auch
kompiliert und ausgeführt werden, dadurch sind die Arbeitsschritte erheblich einfacher und
übersichtlicher. Außerdem ist der Editor dann üblicherweise mit Syntaxhervorhebung (s. S. 5)
versehen, so dass die Programmstruktur besonders gut sichtbar wird. Interessierte finden im Anhang
eine kurze Beschreibung, wie man auch ohne Entwicklungsumgebung ein JAVA-Programm
erstellen kann.
Für den Einstieg in das Programmieren mit JAVA ist BlueJ besonders gut geeignet.
1. Vorstellung der Entwicklungsumgebung BlueJ und erstes Projekt
JAVA installieren
JAVA wird durch Ausführen der Datei jdk-7u25-windows-i586.exe1 oder auf 64-Bit-Systemen
jdk-7u25-windows-x64.exe installiert. (Ein Java-Runtime-Environment jre..., das mit OpenOffice,
Geogebra oder anderen Programmen vielleicht bereits installiert ist, genügt nicht – für BlueJ wird
ein Java-Development-Kit jdk... benötigt. Für Download nach java se downloads oder jdk suchen!)
JAVA muss vor BlueJ installiert werden.
BlueJ installieren
BlueJ darf für Bildungszwecke verwendet werden ohne dass Lizenzgebühren zu zahlen sind. (Siehe
Homepage von BlueJ, http://www.bluej.org, Download der Version 3.1.02 von dort.)
Zur Installation wird die Datei bluejsetup-308.msi2 ausgeführt. Beim ersten Programmstart sucht
BlueJ die zu verwendende JAVA-Version und zeigt eventuell ein Auswahlfenster, wenn die
Zuordnung nicht automatisch erfolgen kann.
Spracheinstellung: Deutsch
Wenn die Entwicklungsumgebung in deutscher Sprache erscheinen soll, muss die Datei BlueJ.defs
mit einem Text-Editor bearbeitet werden, geeignet ist z.B. WordPad (Startmenü/Zubehör). Dieser
Editor muss bei aktuellen Windows-Versionen als Administrator ausgeführt werden, damit im
Installationsordner (vermutlich: C:\Programme(x86)\BlueJ\) Schreibberechtigung erreicht wird.
BlueJ.defs liegt im Unterverzeichnis lib des Installationsordners von BlueJ. Zum Öffnen muss als
Dateityp „Alle Dokumente (*.*)“ eingestellt werden.
In dieser Datei findet man (ungefähr Zeile 31) die Festlegung der bluej.language=english
Sprache: Hier kann bluej-language=english in bluej.language=german wird zu:
geändert werden. Danach wird die Datei gespeichert.
bluej.language=german
1 Aktuelle Version im August 2013
2 Aktuelle Version im August 2013JAVA-Einführung, Seite 4
Ein Projekt beginnen: Projekt Beispiel_1
Wir starten BlueJ und wählen den Menüpunkt
Projekt/Neues Projekt. Info:
Es erscheint das Dialogfenster, in dem wir angeben, In der objektorientierten Programmierung
wo das Projekt gespeichert werden soll. Ein Projekt arbeitet man mit Objekten. (logisch)
Objekte können Eigenschaften haben.
besteht immer aus mehreren Dateien, deshalb wird Beispiel:
für jedes Projekt ein eigener Ordner angelegt. Ein Quader hat die Eigenschaften Länge,
Ordner, die ein BlueJ-Projekt enthalten, werden von Breite, Höhe. Diesen Eigenschaften können
BlueJ durch ein spezielles Symbol gekennzeichnet verschiedene Werte zugeordnet sein. Ein
(siehe Abbildung). zweiter Quader hat die gleichen Eigenschaf-
ten, aber mit anderen zugeordneten Werten.
Ein Zylinder hat dagegen andere Eigenschaf-
ten, denn er ist durch Radius und Höhe
bestimmt.
Alle Quader können wir zu einer Klasse
zusammenfassen:
Wenn wir eine Klasse 'Quader' definieren,
dann legen wir darin eine Art „Bauplan“ fest.
Alle Quader sind Objekte, die nach diesem
Bauplan konstruiert werden.
In der Definition der Klasse 'Quader' wird
außer den Eigenschaften Länge, Breite, Höhe
auch eine Methode zum Erzeugen von
Quader-Objekten festgelegt, sie wird als
Konstruktor oder Constructor bezeichnet.
Anmerkungen:
1. Die genannten Begriffe werden allgemein
bei der objektorientierten Programmierung
verwendet – unabhängig davon, ob man z.B.
mit JAVA oder mit Delphi arbeitet.
2. Gelegentlich sagt man auch, in der
Mit dem Schalter „Erzeugen“ wird der Ordner mit Definition einer Klasse wird der Objekt-Typ
dem eingegebenen Namen angelegt und die beschrieben, und das danach konstruierte
Objekt wird auch als Objekt-Instanz
Projektdateien werden darin gespeichert. bezeichnet.
Die Arbeitsfläche von BlueJ enthält zunächst nur
ein Symbol für eine Readme-Datei, die für eine
Beschreibung des Projekts vorgesehen ist. Nicht
nur im Schulunterricht macht es Sinn, in einer
solchen Datei eine ganz knappe Beschreibung des
Projektes anzugeben. Die Datei wird mit einem
Doppelklick auf das Symbol geöffnet, dann
bearbeitet, gespeichert und wieder geschlossen.
Nun werden wir als erstes Beispiel eine Klasse
mit Namen 'Quader' erstellen (wie im Info-Kasten
oben rechts).
Eine Klasse im Projekt erstellen
Wir klicken auf den Schalter Neue Klasse und geben als Namen für
diese Klasse Quader ein. Daraufhin erscheint ein neues Symbol für
diese Klasse in der Projektübersicht. Wir klicken doppelt auf dieses
Symbol, um die Klasse zu bearbeiten. Zunächst sehen wir schon einige Zeilen vorgegebenen Text
im Editor für unseren Java-Quelltext, den wir nach unseren Erfordernissen anpassen werden (einige
Zeilen löschen, andere ergänzen).JAVA-Einführung, Seite 5
Der Editor von BlueJ für JAVA-Quelltexte
Der Editor arbeitet mit
sogenannter Syntax-
Hervorhebung, d.h.
dass z.B. reservierte
Wörter oder Kom-
mentare in bestimmter
Weise farblich hervor-
gehoben werden.
Die Tatsache, dass hier
der größte Teil des
Textes in blau dar-
gestellt ist, zeigt bereits,
wie wichtig Kommen-
tare in Computerpro-
grammen sind.
Bei genauem Hinsehen
können wir sogar zwei
verschiedene Arten von
Kommentaren unter-
scheiden:
Einfache Kommentare
werden mit zwei
Schrägstrichen einge-
leitet und dienen oft
dem Programmierer als
Notiz.
Die anderen, die mit
/** eingeleitet, mit *
fortgesetzt und mit */
beendet werden, dienen
zusätzlich zur Informa-
tion für andere – darauf
wird später näher einge-
gangen (Seite 10). Auf
die Begriffe public und
private wird ebenfalls
später eingegangen
(Seite 15). Wir sehen,
dass die Klassendefi-
nition mit dem Wort
class eingeleitet wird,
gefolgt vom Namen der
Klasse.
Dann folgt eine öffnende geschweifte Klammer, die zugehörige schließende Klammer steht in der
letzten Zeile.
Der BlueJ-Editor gestaltet nicht nur den Schriftstil, er hebt auch die Struktur durch die Hinter-
grundfarbe hervor (z.B. Texte innerhalb eines {}-Klammerpaares).JAVA-Einführung, Seite 6
Zum Aufbau dieses Programm-Quelltextes:
Nach dem Klassennamen werden im obigen Beispiel die Eigenschaften (hier: Variablen) für die
Instanzen festgelegt: Jede Instanz, die wir gemäß diesem „Bauplan“ erzeugen, soll je eine Variable
für Länge, Breite und Höhe besitzen. Der Variablentyp wird in JAVA immer dem Variablennamen
vorangestellt. Hier wird int als Variablentyp angegeben, d.h. die aufgeführten Variablen sind vom
Typ „integer“, sie können nur ganzzahlige Werte aufnehmen. (Wir folgen damit dem Vorschlag von
BlueJ für die Variablentypen, andere lernen wir später kennen.).
Da diese Variablen hier den Instanzen zugeordnet sind, heißen sie auch Objektfelder oder
Datenfelder oder auch Instanzvariablen.
In Java sind auch Umlaute in Variablennamen zugelassen. Umlaute werden jedoch nicht in allen
Entwicklungsumgebungen (bzw. Betriebssystemen, z.B. Linux) gleich codiert. Die BlueJ-Version 3.0.5 kann
zwar Quelltexte übersetzen, in denen Methoden- oder Klassen-Bezeichner Umlaute enthalten, jedoch führen
Methodenaufrufe dann zu Fehlern. Variablen-Bezeichner können Umlaute enthalten, ohne dass es zu
Fehlern kommt. Version 3.0.8 kann offenbar gut mit Umlauten umgehen. Die Vermeidung von Umlauten und
anderen Sonderzeichen ist dennoch zu empfehlen.
Es folgt die Festlegung des Standard-Konstruktors. Der Name des Konstruktors stimmt in JAVA
immer mit dem Namen der Klasse überein. Dieser Konstruktor ist hier sehr einfach aufgebaut: Er
legt nur Werte für die Variablen eines Quaders fest, der mit ihm erzeugt wird. Alle Quader-
Instanzen, die mit diesem Konstruktor erzeugt werden, haben die gleichen Werte für die Höhe, die
Länge und die Breite. Für die Zuweisung von Werten an eine Variable wird in JAVA ein einfaches
Gleichheitszeichen verwendet (wie in BASIC, C++, aber anders als in PASCAL u. DELPHI). Auch
für den Konstruktor werden Anfang und Ende durch öffnende bzw. schließende geschweifte
Klammer gekennzeichnet. Beachten Sie die übersichtlichen Positionen aller {}-Klammerpaare!
Das Beispiel zeigt außerdem, dass eine Klasse mehrere Konstruktoren besitzen kann: Ein zweiter
Konstruktor dient dazu, Quader zu konstruieren, bei denen mit Aufruf des Konstruktors Werte für
die Länge, die Breite und die Höhe erfragt und übernommen werden.
Zum Schluss zeigt das Beispiel, dass die Klasse außer Konstruktoren auch noch andere Methoden
besitzen kann, hier zur Berechnung des Volumens. Diese Methode berechnet aus Länge, Breite und
Höhe der Quader-Instanz ihr Volumen. Durch die Angabe von return wird festgelegt, welcher Wert
bei Aufruf dieser Methode zurückgegeben wird. Bei allen Methoden, die einen Wert zurückgeben,
muss vor dem Namen der Methode – ähnlich wie bei Variablen – der Typ des Rückgabewertes
angegeben werden, hier also int für integer (ganzzahlig).
Wenn wir die Klasse 'Quader' so wie oben beschrieben festgelegt haben, lassen wir diesen Text
übersetzen (auch als compilieren bezeichnet, Schalter links oben, Shortcut Strg-k). Dabei wird
dieser Text in einen vom Computer interpretierbaren Code übersetzt. Beim Compilieren zeigen sich
(nicht nur bei Anfängern) oft kleine Fehler, die eine Übersetzung verhindern, z.B. eine fehlende
Klammer, ein fehlendes Semikolon oder ähnliches.
Tipp 1:
Da zu jeder öffnenden geschweiften Klammer eine schließende gehört, ist es vernünftig, nach der
öffnenden auch gleich die schließende (in der nächsten Zeile) zu tippen. Den weiteren Text kann man
dann dazwischen einfügen.
Tipp 2:
Einrückungen wie im Beispiel sind für die Interpretation des Quelltextes zwar nicht erforderlich, sie werden
aber für die Übersichtlichkeit (auch von Profis) vorgenommen. Da die Programme mit zunehmendem
Lernfortschritt komplizierter werden, sollte man sich diesen Stil von Anfang an zu Eigen machen.
Beobachten Sie, wie BlueJ nach der öffnenden Klammer automatisch einrückt und die schließende
Klammer an die passenden Position setzt! (Editor-Menü Bearbeiten, Befehl Auto-Layout, Shortcut Strg-
Umschalt-I!) Die Einrückposition für Kommentare erreicht man am einfachsten mit der TAB-Taste.
Nach dem Kompilieren der Klasse 'Quader' werden wir mit Hilfe von BlueJ Instanzen zu dieser
Klasse erzeugen und untersuchen.JAVA-Einführung, Seite 7
Instanzen der Klasse Quader erzeugen
Wenn die Klasse 'Quader' erfolgreich com-
piliert wurde, ist das Symbol für diese
Klasse nicht mehr schraffiert. Um nun eine
Instanz von dieser Klasse zu erzeugen,
klicken wir mit der rechten Maustaste auf
das Klassensymbol. Aus dem sich öffnen-
den Kontextmenü wählen wir zunächst new
Quader() aus. Der (Standard-) Konstruktor
wird ausgeführt, nachdem wir einen Namen
für die Instanz festgelegt haben. Auf dem
Hauptfenster erscheint unten ein Symbol
für das soeben erzeugte Objekt. Wir können
den Vorgang wiederholen und somit wei-
tere Instanzen derselben Klasse erzeugen.
Wählen wir das nächste Mal
aus dem Kontextmenü new
Quader(la,br,ho) aus, so werden
wir zum Ausführen des
zweiten Konstruktors nach
den Werten für die Parameter
la, br und ho gefragt: Im
oberen Abschnitt des
Dialogfensters wird der Kom-
mentar angezeigt, der im
Quelltext dem Konstruktor
vorangestellt worden war.
Klicken wir nun mit der rech-
ten Maustaste auf ein rotes
Objektsymbol, so können wir
u.a. aus dem Kontextmenü
auswählen, ob wir das Objekt löschen oder
untersuchen (inspizieren) wollen. Das Inspi-
zieren zeigt uns, welche Werte die Variablen
laenge, breite und hoehe besitzen. Außerdem
können wir über das Kontextmenü die Methode zur Volumenberechnung aufrufen. (Dort gezeigte
geerbte Methoden interessieren an dieser Stelle nicht.)
Fragen und Aufgaben zum Text
1. Braucht man BlueJ, um Programme in JAVA zu schreiben?
2. Der Begriff Objekt wird manchmal sowohl für Klasse als auch für Instanz verwendet. Erläutern
Sie diese Begriffe an dem hier vorgestellten und an einem anderen selbst gewählten Beispiel.
3. Muss eine Klasse einen Konstruktor besitzen? (Probieren Sie es mit einem Testprojekt aus!)
4. Kann eine Klasse verschiedene Konstruktoren besitzen?
5. Was ist im Quader-Quelltext der Unterschied zwischen la und laenge?
6. Ergänzen Sie in der Klasse 'Quader' ein Datenfeld rauminhalt und eine Methode public void
berechneRauminhalt(), die aus laenge, breite und hoehe den Rauminhalt berechnet und in
das Datenfeld rauminhalt einträgt. [Erläuterungen zu void folgen im nächsten Kapitel.]
7. Testen Sie die Methode von Aufgabe 6, indem Sie eine Quaderinstanz vor und nach Ausführen
dieser Methode untersuchen (inspizieren).JAVA-Einführung, Seite 8
2. Zweites Projekt: Bankkonto (Bank_1)
In diesem Projekt werden wir eine Klasse 'Konto' erstellen. Dann werden zwei Instanzen dieser
Klasse erzeugt, die Girokonten darstellen sollen. Mit Hilfe geeigneter Methoden sollen
Einzahlungen und Abhebungen vom Girokonto möglich sein, aber auch Überweisungen von einem
Konto auf das andere.
Vorüberlegungen zur Klasse 'Konto' Modell der Klasse 'Konto':
Zunächst überlegen wir uns, welche Eigenschaften für Konto- Klasse:
Instanzen in dieser Klasse festgelegt werden müssen: Ein Konto
Konto besitzt auf jeden Fall eine Kontonummer, einen Felder:
Kontoinhaber und einen Kontostand. Wir benötigen eine ktoNummer (int)
Methoden zum Einzahlen, eine zum Abheben, eine zum ktoInhaber (String)
Überweisen. Aber auch zum Auslesen des Kontostands werden ktoStand (double)
wir eine Methode verwenden. Diese Vorüberlegungen Konstruktor:
(„Entwurf eines Modells“) sind von der Programmiersprache Konto(ktoNr,ktoInh)
noch weitgehend unabhängig. Methoden:
einzahlen()
Erstellen des Konto-Projekts in BlueJ: abheben()
getKontoStand()
Wir starten BlueJ und beginnen ein neues Projekt, dem wir den überweisen(kto, betrag)
Namen Bank_1 geben (ein weiteres Bank-Projekt werden wir
dann Bank_2 nennen). Beachten Sie die Hinweise zur Readme.txt–Datei sowie zu den Kommentaren
vom ersten Beispiel.
Bei den Variablen (Datenfelder) lernen wir neue Datentypen kennen (bisher wurde nur int
verwendet): Der Typ double lässt zu, dass Zahlen mit Dezimalkomma (bzw. Dezimalpunkt) als
Wert zugewiesen werden können. Für den Kontoinhaber soll ein Name zugewiesen werden und
nicht eine Zahl oder Nummer. Hier wird der Typ String verwendet. Genau genommen ist String
gar kein Variablentyp, sondern eine Java-Klasse, damit wird auch der Großbuchstabe am
Wortanfang gerechtfertigt. In JAVA wird im Gegensatz zu einigen anderen Programmiersprachen
zwischen Groß- und Kleinbuchstaben unterschieden. Klassennamen beginnen üblicherweise immer
mit einem Großbuchstaben. Variablen- und Methodennamen beginnen üblicherweise mit einem
Kleinbuchstaben. Zur Verbesserung der Lesbarkeit werden bei Wortzusammensetzungen oft mitten
im Bezeichner Großbuchstaben verwendet (zum Beispiel getKontoStand ).
Die Datenfelder werden am Beginn der Klasse festgelegt (wie auch bei der Klasse 'Quader'). Der
einfachste Konstruktor könnte als Kontonummer und Kontostand jeweils den Wert 0 zuweisen, als
Kontoinhaber "" oder "dummy". Das ist für das Erzeugen mehrerer Konto-Instanzen natürlich nicht
sinnvoll – also wird man dafür sorgen, dass gleich beim Erzeugen einer Konto-Instanz nach dem
Namen und der Kontonummer gefragt wird. Der Kontostand kann mit 0 initialisiert werden, aber
auch die Kontoeinrichtung mit einem Startguthaben könnte vorgesehen werden.
'Konto' besitzt nach diesen Überlegungen 3 Datenfelder und 5 Methoden (eine davon ist der
Konstruktor), vergl. Kasten oben links. Es folgt der Quelltext für dieses Projekt (im folgenden
werden Quelltexte nicht als Screenshot dargestellt, sondern als Text mit Syntax-Hervorhebung; hier
außerdem mit Zeilenummern):
1: /**
2: * Es wird eine Klasse 'Konto' programmiert.
3: *
4: * @author B. Spier
5: * @version 15.11.2009
6: */
7: public class Konto
8: { // Instanzvariablen (Datenfelder)JAVA-Einführung, Seite 9
9: private int ktoNummer;
10: private String ktoInhaber;
11: private double ktoStand;
12: /**
13: * Konstruktor für Objekte der Klasse 'Konto'
14: *
15: * @param ktoNr Parameter für Kontonummer
16: * @param ktoInh Parameter für Kontoinhaber
17: */
18: public Konto(int ktoNr, String ktoInh)
19: { // Initialisieren der Datenfelder
20: ktoNummer = ktoNr;
21: ktoStand = 0;
22: ktoInhaber = ktoInh;
23: }
24:
25: /**
26: * Auslesen des Kontostands
27: *
28: * @return Wert des Kontostands
29: */
30: public double getKontoStand()
31: {
32: return ktoStand;
33: }
34:
35: /**
36: * Einzahlung vornehmen
37: *
38: * @param betrag Betrag der Einzahlung
39: */
40: public void einzahlen(double betrag)
41: {
42: ktoStand = ktoStand + betrag;
43: }
44:
45: /**
46: * Auszahlung vornehmen, falls Kontostand ausreichend
47: *
48: * @param betr Betrag der Auszahlung
49: */
50: public void auszahlen(double betr)
51: {
52: if (ktoStand >= betr)
53: einzahlen(-betr);
54: else // Meldung ausgeben, wenn Konto nicht gedeckt:
55: System.out.println("Das Guthaben reicht nicht aus!");
56: }
57:
58: /**
59: * Überweisung auf ein anderes Konto vornehmen
60: *
61: * @param empfaenger Konto des Empfängers
62: * @param geldBetrag Betrag der Überweisung
63: */
64: public void ueberweisen(Konto empfaenger, double geldBetrag)
65: {
66: auszahlen(geldBetrag);
67: empfaenger.einzahlen(geldBetrag);
68: }
69: }
Auf die Eigenschaft private der Instanzvariablen dieser Klasse wird auf Seite 15 eingegangen.
Es werden jetzt die 5 Methoden der Klasse 'Konto' erläutert:
1. Die Methode Konto ist ein Konstruktor, denn sie heißt genauso wie die Klasse. Sie trägt die
als Parameter übergebenen Werte in die Datenfelder der jeweiligen Instanz ein.JAVA-Einführung, Seite 10
2. Mit der Methode getKontoStand wird der aktuelle Kontostand ausgelesen.
3. Die Methode einzahlen hat keinen Rückgabewert, deshalb muss sie mit dem reservierten
Wort void deklariert werden.
Beim Einzahlen eines Betrages wird der Kontostand um diesen Betrag erhöht. Bei der
Schreibweise ktoStand = ktoStand + betrag muss man sich klar machen, dass es sich
nicht um eine Gleichung handelt, sondern um eine Wertzuweisung: Zuerst wird der Wert
von ktoStand + betrag ermittelt, dann wird dieser wieder dem Datenfeld ktoStand
zugewiesen.
Die Schreibweise ist professionellen Programmierern noch zu umständlich, deshalb ist auch
die kürzere – aber besonders für den Anfänger erheblich schwerer lesbare – Schreibweise
zugelassen, die dasselbe bewirkt: ktoStand += betrag
4. Das Auszahlen entspricht dem Einzahlen eines negativen Betrags, deshalb kann man die
Methode zum Einzahlen verwenden. Hier im Beispiel wurde einmal angenommen, dass man
das Konto nicht überziehen darf; falls man mehr abheben möchte als der Kontostand beträgt,
wird eine entsprechende Meldung ausgegeben. Der Vergleichsoperator >= steht für größer
oder gleich. Die weiteren sindJAVA-Einführung, Seite 11
Wenn Programmierer Java-Klassen austauschen oder weitergeben, geben sie in der Regel auch die
Dokumentation mit. Die Klassen können als Quelltext (Datei mit der Extension „.java“) oder als
compilierte Klasse (Extension „.class“) weitergegeben werden. Sie finden diese Dateien, wenn Sie
mit dem Windows-Explorer den Ordner aufsuchen, in dem Sie Ihr Projekt gespeichert haben.
Die Dokumentation zeigt Ihnen außer den Bezeichnungen der öffentlichen Methoden auch die
Bedeutung der Kommentare, die Sie mit '/**' eingeleitet haben: Sie finden nicht nur die Kom-
mentare zu den Methoden in der Method Summary wieder, sondern bei der differenzierten
Beschreibung der einzelnen Methoden (weiter unten) auch die Bedeutung der Parameter (siehe
@param) oder die Bedeutung des Rückgabewerts (siehe @return) der Methode getKontostand.
Klicken Sie in der Constructor Summary auf den Klassenbezeicher 'String': Sie werden auf eine
völlig gleichartig aufgebaute Webseite geführt, welche die Klasse 'String' beschreibt. Auf diesen
Typ von Webseiten trifft man (fast) immer, wenn man Erklärung zu JAVA-Klassen sucht.
Kommentare, die dagegen mit // eingeleitet wurden (einzeilige Kommentare), sind als Notizen
aufzufassen, die der Programmierer für sich selbst (oder einen Leser des Quelltextes) angefertigt
hat. Das gilt auch für die mehrzeiligen Kommentare, die zwischen '/*' und '*/' stehen.
Fragen und Aufgaben zum Text
10. Untersuchen Sie, wie sich die Dokumentation der Klasse ändert, wenn Sie vor einem der
Datenfelder das Schlüsselwort private durch public ersetzen! (Siehe auch Seite 15.)
11. Untersuchen Sie, wie sich die Dokumentation der Klasse ändert, wenn Sie vor einem der
Datenfelder das Schlüsselwort private (bzw. public) entfernen (machen Sie dies anschließend
für die weitere Verwendung des Projekts rückgängig!). Testen Sie auch den Shortcut Strg-j.
Dieses Beispiel hat gezeigt, dass Instanzen auch auf Methoden anderer Instanzen zugreifen können:
Beim Überweisen ruft das überweisende Konto die Methode einzahlen des empfangenden Kontos
auf. Die Syntax dafür erfordert die Angabe des Objekts, dessen Methode aufgerufen werden soll,
sowie den Namen der Methode – als Trennzeichen steht dazwischen ein Punkt.
Es mag als unbefriedigend erscheinen, dass beim Überweisen von einem Konto auf ein anderes
jeweils der Name des Kontos eingegeben werden muss, und dass es hier nicht über die Eingabe der
Kontonummer geht. Die Ursache liegt darin, dass es kein „übergeordnetes“ Objekt gibt, das die
Fähigkeit besitzt, aus der Kontonummer zu ermitteln, welche Kontoinstanz dazu gehört. Wenn man
bei einer Überweisung eine Kontonummer als Parameter übergeben möchte, müssten alle vorhan-
denen Kontoinstanzen daraufhin durchsucht werden, ob sie die betreffende Kontonummer besitzen.
Wenn das Konto nicht gefunden wird, muss die Überweisung abgelehnt werden.
Dieser anspruchsvollen Aufgabe widmet sich das folgende Kapitel.
3. Drittes Projekt: Bank_2
Legen Sie ein neues Projekt mit dem Namen 'Bank_2' an. Dieses Projekt verwendet wieder eine
Klasse 'Konto', dessen Quelltext fast vollständig mit dem des vorigen Projekts übereinstimmen
wird. Klicken Sie nicht auf „Neue Klasse“, sondern wählen Sie im Menü „ Bearbeiten / Klasse aus
Datei hinzufügen ...“! So können Sie aus Bank_1 die Klasse „Konto“ ins Projekt Bank_2 kopieren.
Bearbeiten Sie jetzt in 2 Punkten den Quelltext dieser Klasse:
Als erstes löschen Sie die Methode ueberweisen der Klasse 'Konto' im Projekt Bank_2, denn
Überweisungen wird die noch zu erstellende Klasse 'Bank' übernehmen.
Die Klasse 'Konto' benötigt aber noch eine kurze Methode getKontoNummer():
public int getKontoNummer()
{
return ktoNummer;
}
Ergänzen Sie diese Methode, gern auch mit den Kommentaren für die Dokumentation!JAVA-Einführung, Seite 12
Anschließend erstellen wir eine weitere Klasse in diesem
Projekt mit dem Namen 'Bank' – dies wird damit unser erstes Modell der Klasse 'Bank':
Projekt, in dem wir zwei Klassen definieren. Klasse
Die Konten, die im Bankmodell verwaltet werden sollen, Bank
müssen in irgendeiner Form gespeichert werden. JAVA stellt Felder:
dafür die Klasse ArrayList zur Verfügung. Instanzen dieser Liste der Konten
Konstruktor
Klasse sind Listen-Objekte, sie besitzen Methoden zum Bank()
Verwalten der Listenelemente. Die wichtigste ist die zum Methoden
Hinzufügen. Natürlich kann eine solche Liste eingetragene neuesKonto()
Elemente auch wieder löschen, eine „Kontoauflösung“ ist aber einzahlen()
hier bei unserem Bankmodell nicht vorgesehen. Damit solche abheben()
Listen-Objekte vielseitig sind, verwalten sie nur Zeiger auf die getKontoStand()
eingetragenen Elemente, aber keine Information darüber, von ueberweisen()
welchem Typ die eingetragenen Elemente sind. Die Liste merkt
sich also in unserem Beispiel nicht, ob ein Konto oder ein Quadrat eingetragen ist – die
Konsequenzen zeigen sich, wenn man ein Element aus der Liste verwenden will (s.u.).
Der Quelltext der Klasse 'Bank' wird nun in Abschnitten erläutert:
1: import java.util.*; // macht ArrayList verfügbar!
2: /**
3: * Die Klasse Bank kann in einer Liste mehrere Konten verwalten,
4: * zwischen denen Überweisungen ausgeführt werden können.
5: *
6: * @author B.Spier
7: * @version 17.11.09
8: */
9: public class Bank
10: {
11: // einzige Instanzvariable
12: private ArrayList kontoListe;
13:
14: /**
15: * Konstruktor für Objekte der Klasse Bank
16: */
17: public Bank()
18: {
19: // Instanzvariable initialisieren
20: kontoListe = new ArrayList();
21: }
Da ArrayList nicht ein gewöhnlicher Typ wie z.B. int ist, sondern eine Klasse, muss von dieser
Klasse erst eine Instanz (kontoListe) erzeugt werden, bevor sie verwendet werden kann. Das
geschieht mit der Zeile 20 im Konstruktor für das Bankobjekt: Hier wird der Konstruktor von
ArrayList aufgerufen. Diese Syntax (new ...) haben Sie vielleicht auch schon bei der Erzeugung
der Quadrate oder Konten „von Hand“ bei BlueJ bemerkt.
22: /**
23: * Einrichten eines neuen Kontos:
24: * Es ist kein Parameter für den Inhaber vorgesehen, weil das Testen
25: * des Programms dann einfacher ist. Alle Konten gehören "Meier"!
26: * @param kontoNr für die Kontonummer
27: */
28: public void neuesKonto(int kontoNr)
29: {
30: Konto neuKto; // Variable neuKto vom Typ Konto
31: neuKto = new Konto(kontoNr,"Meier"); // Konto-Objekt erzeugen
32: kontoListe.add(neuKto); // Konto in die Liste eintragen
33: }JAVA-Einführung, Seite 13
Anders als im vorigen Beispiel werden neue Konten jetzt nicht mehr durch BlueJ nach Rechtsklick
auf das Klassensymbol für 'Konto' erzeugt, sondern durch die Methode neuesKonto eines
Bankobjekts. Wir müssen also erst ein Bankobjekt erzeugen, dann können wir nach Rechtsklick auf
das Objektsymbol dessen Methode neuesKonto() aufrufen, die den Konstruktor der Klasse 'Konto'
verwendet. Das neu erzeugte Konto – besser eine Referenz darauf (auch „Zeiger“ genannt) – wird
dann mit add in die Liste eingetragen. Eine Bankinstanz verwaltet so jedes erzeugte Konto in seiner
Liste der Konten.
35: /**
36: * Suchen des Konto-Objekts an Hand seiner Kontonummer
37: *
38: * @param num für die Kontonummer
39: * @return Referenz auf das (hoffentlich!) gefundene Konto(-Objekt)
40: */
41: private Konto findByNumber(int num)
42: {
43: int i; // Zähler für die Schleife, Referenzen
44: Konto einKto, dasKto; // Zeiger für laufendes bzw. gefundenes Kto.
45: // (in der Schleife benötigte Variablen)
46: i = 0; // Initialisierung für die Schleife
47: dasKto = null; // Null-Zeiger, steht für ungültiges Konto
48: while (i < kontoListe.size()) // Schleifenkopf
49: { // Alle Konten in der Liste werden geprüft.
50: einKto = (Konto) kontoListe.get(i); // Ein Konto aus der Liste
51: if (einKto.getKontoNummer() == num) // KtoNr. prüfen
52: dasKto = einKto; // hier: Konto gefunden!
53: i++; // entspricht i = i + 1;
54: }
55: if (dasKto == null)
56: System.out.println("ungültige Kontonummer!");
57: return dasKto; // Referenz auf das gefundene Konto (oder null)
58: }
Mit Hilfe der Methode findByNumber kann das Bankobjekt alle Konten, die in die Liste
eingetragen sind, nach der Kontonummer durchsuchen. Wir verwenden hier eine while-Schleife,
weil dies die einfachste Schleifenprogrammierung ist; die Kommentare erklären schon fast alles:
Wenn in der Liste z.B. 5 Konten eingetragen sind, wird die Schleife 5-mal durchlaufen, wobei i
nacheinander die Werte 0, 1, …, 4 annimmt. Die Schleife wird auch dann 5 mal durchlaufen, wenn
das gesuchte Konto schon früher gefunden wurde – das ist zwar keine optimale Programmierung,
erlaubt aber eine leicht verständliche Form unserer ersten Schleife (mehr zu while s.S. 39).
Zeile 50: Weil die Liste mit get(i) nur einen untypisierten Zeiger auf das Listenelement am Platz i
zurück gibt, muss dieser vor der Zuweisung an die Variable einKonto eine Typumwandlung
erfahren. Das geschieht durch das vorangestellte (Konto) – der Fachmann spricht dabei von einem
„Cast-Operator“. Eine unpassende Typumwandlung kann schlimme Fehler verursachen, deshalb
gibt es beim Übersetzen eine Warnmeldung! (Ergänzende Information siehe Anhang, Seite 41)
Die Methoden einzahlen und abheben verwenden diese Methode findByNumber:
60: /**
61: * Einzahlen auf ein Konto unter Angabe der Parameter
62: *
63: * @param kontoNr für die Kontonummer
64: * @param betrag für den Geldbetrag
65: */
66: public void einzahlen(int kontoNr, double betrag)
67: {
68: Konto dasKonto;
69: dasKonto = findByNumber(kontoNr);
70: if (dasKonto != null) dasKonto.einzahlen(betrag);
71: }JAVA-Einführung, Seite 14
Zeile 70 prüft, ob überhaupt eine Konto mit der angegebenen Nummer gefunden wurde: In JAVA
steht das Ausrufezeichen für die Negation, != heißt also „ungleich“. Die if-Anweisung ist hier ohne
else verwendet worden. Bei ungültiger Kontonummer wurde ein Hinweis bereits von
findByNumber ausgegeben. Weil die Anweisung in Zeile 70 bzw. 83 so kurz ist, wird auf den sonst
bei if-Anweisungen üblichen Zeilenumbruch verzichtet.
73: /**
74: * Abheben von einem Konto unter Angabe der Parameter
75: *
76: * @param kontoNr für die Kontonummer
77: * @param betrag für den Geldbetrag
78: */
79: public void abheben(int kontoNr, double betrag)
80: {
81: Konto dasKonto;
82: dasKonto = findByNumber(kontoNr);
83: if (dasKonto != null) dasKonto.auszahlen(betrag);
84: }
Abrufen des Kontostands (können Sie eine Prüfung auf gültige Kontonummer ergänzen?):
86: /**
87: * Abrufen des Kontostands unter Angabe der Kontonummer
88: *
89: * @param kontoNr für die Kontonummer
90: * @return Kontostand
91: */
92: public double kontostandAbrufen(int kontoNr)
93: {
94: Konto dasKonto = findByNumber(kontoNr);
95: return dasKonto.getKontoStand();
96: }
Haben Sie bemerkt, dass die Deklaration einer Variablen (dasKonto) und die Zuweisung an diese
in einem einzigen Schritt erfolgen kann? Hier wird der Zeiger auf das gefundene Konto zugewiesen.
Nun zur Methode zum Überweisen von einem Konto auf ein anderes:
98: /**
99: * Überweisen unter Angabe der Parameter
100: *
101: * @param ktoNrA Konto des Absenders
102: * @param ktoNrB Konto des Empfängers
103: * @param betrag Betrag der Überweisung
104: */
105: public void ueberweisen(int ktoNrA, int ktoNrB, double betrag)
106: {
107: Konto empf, absd; // Konto-Objekte
108: absd = findByNumber(ktoNrA);
109: empf = findByNumber(ktoNrB);
110: if ((absd != null) & (empf != null))
111: {
112: absd.auszahlen(betrag);
113: empf.einzahlen(betrag);
114: }
115: }
116: }
Hier muss die Gültigkeit beider Kontonummern geprüft werden. Nur wenn Absender-Konto absd
und Empfänger-Konto empf gültig sind, wird die Überweisung ausgeführt. Die logische UND-
Verknüpfung wird in JAVA durch das &-Zeichen dargestellt. Da im WENN-Fall zwei Anweisungen
stehen, sind geschweifte Klammern zur Kennzeichnung von Anfang und Ende des Blocks
erforderlich. Dasselbe gilt auch für den SONST-Fall, wenn er aus mehreren Anweisungen besteht.JAVA-Einführung, Seite 15
(Die Klammern dürfen selbstverständlich auch gesetzt werden, wenn sie nur eine einzige Anwei-
sung einschließen).
Wenn sich der Quelltext für die Klasse 'Bank' fehlerfrei übersetzen ließ, können wir jetzt unser
Bankinstitut eröffnen und Kundenkonten einrichten, um
die von uns programmierten Klassen und deren
Instanzen zu testen! Also: Bankinstanz mit Rechtsklick
erstellen, Bank-Namen wählen (z.B. "JGiro", "DieBank"
o.ä.) und dann in dieser Bank mindestens 2 Konten
einrichten. Nach einer Einzahlung sollte dann auch eine
Überweisung möglich sein.
Die Klasse 'Konto' wird jetzt nicht mehr von uns,
sondern nur von dem Bank-Objekt benutzt. Diese
Beziehung „Bank verwendet Konto“ (allgemein
„ verwendet “) stellt BlueJ
durch einen gestrichelten Pfeil in der Projektübersicht
dar.
Fragen und Aufgaben zum Text
12. Ergänzen Sie in einem der Bank-Projekte eine Methode, die zur Kontonummer den Namen des
Kontoinhabers zurück gibt.
13. Ein Objekt A soll die Methode tuIrgendWas() eines Objekts B aufrufen. Wie ist der Aufruf zu
schreiben?
14. Im Projekt Bank seien zwei Instanzen erzeugt: HASPA und DEUTSCHE_BANK. Mit beiden
Instanzen wurden mehrere Konten erzeugt. Welche Überweisungen sind möglich?
Informationen zu private und public
Bisher wurden alle Datenfelder als private deklariert. Das ist üblich, wenn keine fremde Instanz
direkten Zugriff auf den Wert einer solchen Variablen zu haben braucht.
Stellen wir uns vor, von der Klasse 'Konto' haben wir keinen eigenen Quelltext, sondern nur die
compilierte Klassendatei und die Dokumentation. Wir erstellen eine Klasse 'Bank', welche
Instanzen der Klasse 'Konto' verwalten soll. Dadurch, dass ktoStand als private deklariert ist,
kann nur über öffentliche Methoden (getKontoStand, auszahlen, einzahlen) auf den Kontostand
zugegriffen werden. Der Programmierer der Klasse 'Konto' könnte diese Methoden so erweitern,
dass erst eine Geheimnummer eingegeben werden muss, bevor der Kontostand ausgelesen oder eine
Auszahlung/Überweisung vorgenommen werden kann. Methoden, die den Kontostand ändern,
könnten auch jeweils einen Text ausgeben, der einem Kontoauszugs-Eintrag entspricht. Wäre
ktoStand jetzt public, so könnten wir in der Klasse 'Bank' die folgende Methode programmieren,
die eine Berechtigungsprüfung umgeht, indem sie auf den Kontostand direkt zugreift:
public void ueberweisen(int ktoNrA, int ktoNrB, double betrag)
{
Konto empf, absd; // Konto-Objekte
absd = findByNumber(ktoNrA);
empf = findByNumber(ktoNrB);
if ((absd != null) & (empf != null))
{
absd.ktoStand -= betrag; // Kontostand verringern
empf.ktoStand += betrag; // Kontostand erhöhen
}
}
Nicht nur Variablen, auch Methoden können private oder public sein. Unsere Klasse Bank
benötigt die Methode findByNumber, die wir aber beim simulierten Zahlungsverkehr mit der Maus
im BlueJ-Fenster nie aufzurufen brauchen und deshalb als private deklariert haben.JAVA-Einführung, Seite 16
Hätten wir sie als public deklariert,
wäre die Auswahl der möglichen
Methoden beim Rechtsklick auf ein
Bankinstanzsymbol um eine unnötige
Zeile unübersichtlicher geworden, wie
die Abbildung zeigt.
Grundsätzlich sollten also nur die Me-
thoden und Datenfelder öffentlich sein,
auf die der Zugriff „von außen“
tatsächlich benötigt wird.
4. Viertes Projekt:
Fahrkartenautomat
Mit diesem Projekt testen Sie sich, wie weit Sie eigenständig (nach wenigen Vorgaben)
programmieren können. Fast alles, was Sie benötigen, wurde in den bisherigen Kapiteln genannt:
• Namen für das Projekt festlegen (also einen Ordner einrichten),
• neue Klasse erzeugen (wieder einen Namen überlegen),
• private Datenfelder deklarieren, diese mit dem Konstruktor initialisieren,
• weitere Methoden programmieren (siehe folgende Punkte 1, 2, 3, 5).
Orientieren Sie sich dabei an den bisher erstellten Programmen!
Unser virtueller Fahrkartenautomat soll folgendes können:
1. Der Anwender muss einen Fahrpreis für die gewünschte Fahrkarte eingeben können
(Festlegung des zu zahlenden Betrags, z.B. 4.3 für 4,30€), die Klasse benötigt dafür eine
sinnvoll benannte Methode. Ein Datenfeld fahrPreis vom Typ double muss dann den
gewünschten Fahrpreis speichern. Zum Testen des Automaten ist es zweckmäßig, bereits im
Konstruktor den Fahrpreis mit z.B. 3.8 zu initialisieren – dann muss man nicht bei jedem
Neustart erst einen Fahrpreis eingeben.
2. Der Anwender muss nach der Festlegung des Fahrpreises „Geld einwerfen“ können (z.B.
mehrmals 1€ oder 0,50€ o.ä.), eine Prüfung auf tatsächlich möglichen Münzwert entfällt. Die
Klasse benötigt im Prinzip also eine Methode einzahlen(betrag) wie im vorigen Projekt.
Ein weiteres Datenfeld einwurf vom Typ double muss den bereits gezahlten Betrag
speichern.
3. Eine Methode druckeFahrkarte soll einen von der bisherigen Zahlung abhängigen Text aus-
geben: Zuerst wird der gewählte Fahrpreis „ausgedruckt“, dann der bisher gezahlte Betrag.
Wenn dieser noch nicht reicht, wird der Fehlbetrag ausgegeben. Wurde genug gezahlt, ist der
Kauf abgeschlossen, und die Höhe des Wechselgeldes wird ausgegeben. Außerdem muss der
eingeworfenen Betrag auf 0 zurückgesetzt werden. Info zum „Drucken“:
System.out.println (print line) System.out.println("BlueJ-Bahngesellschaft");
gibt eine Zeile, also Text mit an- System.out.print("Fahrkahrte zu "); // Text
schließendem Zeilenumbruch aus. System.out.println(fahrPreis); // Wert
... (u.s.w.)
Neu ist hier: System.out.print
(ohne ln) gibt Text aus, ohne dass sich ein Zeilenumbruch anschließt. Sie können die beiden
letzten Zeilen aber auch zu einer einzigen zusammenfassen:
System.out.println("Fahrkarte zu " + fahrPreis);
Mit + können Strings aneinander gehängt werden, in diesem Fall wandelt JAVA die Zahl
fahrPreis dazu in einen String um.
4. Diesen Punkt können Sie ergänzen, nachdem alles andere fehlerfrei läuft:JAVA-Einführung, Seite 17
Die Klasse soll ein drittes Datenfeld gesamtEinnahmen besitzen, in dem die Einnahmen bei
jedem Kauf eines Fahrscheins aufsummiert werden. Es genügt, dass dieses Datenfeld durch
„Inspizieren“ geprüft werden kann – oder möchten Sie eine Methode getGesamteinnahmen()
schreiben?
5. Optional können Sie den Fahrkartenautomaten verbessern, indem Sie eine Methode zum
Abbrechen des Fahrkartenkaufs ergänzen. Sie sollte als Text die Rückzahlung des bisher
eingeworfenen Betrags melden. Was muss sie sonst noch tun?
Die Abbildung zeigt ein
mögliches Ergebnis des
Projekts: Sie können den
Namen des Projekts, den
Namen der Klasse und den
aktuell gewählten Namen
für die Instanz dieser Klasse
herauslesen.
Ein Fahrpreis wurde fest-
gelegt, Geld wurde „einge-
worfen“.
Das Bild zeigt das Fenster
nach Aufruf der Methode
druckeFahrkarte.
Mit Sicherheit wird Ihr Ergebnis noch nicht so
wie hier aussehen können, denn hier wurde die
Ausgabe auf 2 Nachkommastellen und mit
Dezimalkomma formatiert. Diese Formatierung rundet zugleich, so dass Rechenfehler ausgeglichen
werden. Es folgen hierzu weitere Informationen:
Wie entstehen Rechenfehler beim Computer?
1 1 1 5
Computer rechnen im Zweiersystem. Brüche wie 2 , 4 , 8 , 8 sind in diesem System abbrechende
Dualbrüche. Brüche, deren Nenner jedoch keine Zweierpotenz sind, sind periodische Dualbrüche.
Der Grund ist der, den wir aus dem Dezimalsystem kennen: Wenn der Nenner sich nicht aus
Potenzen von 2 oder 5 zusammensetzt, wird der Dezimalbruch periodisch. 2 und 5 sind Teiler der
3 3 12 4
Basis 10, daher ist z.B. 25 = 5 = 100 =0,12 abbrechend. 11 =0, 36 ist dagegen periodisch. Da die
2
Basis 2 nur die 2 als echten Teiler hat, können im Zweiersystem nur Brüche wie die oben genannten
1 1
abbrechend sein, 5 oder 10 sind in diesem System dagegen periodisch, also unendlich lang. Da
der Computer aber Zahlen nur in wenigen Bytes speichert, muss er die Darstellung abbrechen.
Selbst wenn dabei richtig gerundet wird, entstehen Ungenauigkeiten. Die Ungenauigkeit zeigt sich
beim Fahrkartenautomaten z.B. bei einem Fahrschein zu 3,80€, wenn 0,10€ bezahlt sind. Als
Restbetrag werden 3,699999999999997€ berechnet! (Probieren Sie es aus!)
Zahlen formatieren
JAVA stellt verschiedene Methoden zum Formatieren von Zahlen zur Verfügung. In JAVA sind alle
Methoden an Klassen gebunden, wir verwenden hier die Methode format der Klasse String.
String.format("Noch zu zahlen: %.2f €",(fahrPreis – einwurf))
liefert einen formatierten String für den Wert von (fahrPreis – einwurf), er
enthält am Beginn
den Text „Noch zu zahlen: “. Das %-Zeichen kennzeichnet das Einfügen aus nachfolgend
angegebenen Parametern. „.2“ kennzeichnet die Genauigkeit von 2 Nachkommastellen, „f“
kennzeichnet die Umwandlung eines float- oder double-Werts (Fließkommazahl). Die weiteren
Zeichen „ €“ folgenden dem eingefügten String, sodass das Ergebnis z.B. im Falle des WertsJAVA-Einführung, Seite 18
0.1999999994 der String „Noch zu zahlen: 0,20 €“ wird, weil die Methode zugleich auch rundet.
Die Umwandlung des Dezimalpunkts in ein Komma erfolgt auf Grund der Spracheinstellung des
Betriebssystems.
Die format-Methode der Klasse String ist sehr vielseitig, mit ihr können z.B. auch Datumswerte
formatiert werden (siehe nachfolgendes Kapitel). Ein weiteres Beispiel für die Formatierung auf 2
Nachkommastellen:
System.out.println(String.format("Fahrkahrte zu %.2f €",fahrpreis));
Diese Art der Formatierung können Sie überall dort verwenden, wo ein Euro-Wert mit 2
Nachkommastellen ausgeben werden soll.
5. Fünftes Projekt: Person (Vererbung / GregorianCalendar)
Ein bedeutendes Merkmal objektorientierter Programmierung (und darum geht es bei JAVA) ist die
Möglichkeit, bereits programmierte Klassen als Ausgangsbasis für weitere Klassen mit zusätzlichen
Datenfeldern und Methoden zu verwenden. Die so von einer Basisklasse „abgeleiteten“ Klassen
erben die Datenfelder und Methoden der Basisklasse, wodurch der Quelltext der neuen Klasse
weniger umfangreich ist. Die Verwendung fertiger Basisklassen ist für den Programmierer eine
deutliche Arbeitserleichterung.
Dieses Prinzip werden wir in Kapitel 6 nutzen, um mit Hilfe bereits in JAVA vorgegebener Klassen
„Applets“ (Anwendungen) zu programmieren, die in einem Browser ablaufen können.
Erzeugen Sie das neue Projekt mit dem Namen „ Vererbung“. Erstellen Sie in diesem Projekt eine
Klasse mit der Bezeichnung Person. Eine Person hat einen Vornamen, einen Nachnamen, ein
Geburtsdatum. Außerdem soll
vermerkt werden können, ob
die Person Informatiker ist oder
nicht. Vor- und Nachname sind
Strings, das Geburtsdatum
müssen wir als Instanz der in
JAVA vordefinierte Klasse
GregorianCalendar festlegen
(die Bezeichnung bezieht sich
auf den Gregorianischen
Kalender, der seit dem 15.
Oktober 1582 regelt, welche
Jahre Schaltjahre sind). Die
Informatiker-Eigenschaft kann
nur die Werte true oder false
annehmen, dieser Typ heißt
boolean. Wenn eine Person
geboren wird, steht das
Geburtsdatum fest – darum
wird hier vorgeschlagen, dass
der Konstruktor beim Erzeugen
einer Instanz der Klasse Person
Tag, Monat und Jahr der Geburt
erfragt.JAVA-Einführung, Seite 19
Wenn wir jetzt eine Instanz erzeugen, müssen wir also Werte für t, m, j eingeben. Da
GregorianCalendar die Monate als Zahlen von 0 bis 11 verwaltet, muss die Eingabe für m um 1
vermindert werden!
Beim Inspizieren der Person werden Sie
feststellen, dass Sie das Geburtsdatum
nicht in der Form von Tag, Monat und
Jahr auslesen können. Möchten Sie eine
Methode getGeburtsdatum() schrei-
ben, die dieses Datum als String zu-
rückgibt? Dazu müssen Sie heraus-
finden, wie aus der Instanz
geburtsDatum ein Datumsstring gewon-
nen werden kann! Sie müssen jetzt keine
Suchmaschine oder Foren bemühen,
holen Sie sich mit BlueJ (siehe Abb.) die Hilfe über Klassenbibliotheken! Sie führt auf die Webseite
(Stand vom September 2014)
http://docs.oracle.com/javase/7/docs/api/
Sie finden dann in der
Beschreibung der Klasse String
etwas weiter unten die Beschrei-
bung der beiden format-Metho-
den.
Klicken Sie wie in der Abbildung
angedeutet auf „format“, von dort
können Sie zu einer so umfang-
reichen Beschreibung gelangen,
wie ein „format string“ aussehen
kann, dass Sie erleichtert sein
dürften, einen Weg zur formatier-
ten Ausgabe eines Datums auch
im folgenden Absatz zu finden:JAVA-Einführung, Seite 20
Die folgende Methode gibt das in geburtsDatum gespeicherte Datum formatiert als String zurück:
public String getGeburtsdatum()
{
return String.format("%1$td.%1$tm.%1$tY", geburtsDatum);
}
Vielleicht gelingt es Ihnen ja, mit Hilfe der angegebenen Webseite das Datum auch so zu
formatieren, dass zusätzlich noch der Wochentag ausgegeben wird (Aufgabe 22)!
Anmerkungen: Methoden, die Daten auslesen, beginnen üblicherweise mit get. Daran lehnt sich
hier der Vorschlag für den Methodennamen zum Auslesen des Geburtsdatums an. Wenn Sie solche
Sprachvermischungen vermeiden wollen, können Sie getDayOfBirth oder holeGeburtsdatum
verwenden. Ein Vorteil deutscher Wortanteile ist der, dass sofort erkennbar ist, ob vordefinierte oder
eigene Bezeichner verwendet sind.
Zur Übung – und damit unsere „Person“ etwas mehr zu vererben hat (darum geht es ja in diesem
Kapitel), folgen zunächst noch einige Aufgaben:
Fragen und Aufgaben zum Text
15. Wie ändert sich die formatierte Datumsausgabe, wenn Sie im format-String für das Jahr ein
kleines „y“ verwenden?
16. Damit die Person einen Namen bekommt, wird eine Methode setName(String v, String n)
benötigt, mit der Vor- und Nachname festgelegt werden. Schreiben Sie diese.
17. Schreiben Sie eine Methode setInfomatikerYes(), die das Datenfeld informatiker auf
true setzt.
18. Schreiben Sie eine Methode setInfomatikerNo(), die informatiker auf false setzt.
19. Schreiben Sie eine Methode setInfomatiker(boolean x), die informatiker auf einen Wert
setzt, den der Anwender eingibt.
20. Schreiben Sie eine Methode getGanzerName(), die die Kombination aus Vor- und Nachnamen
als String zurück gibt.
21. Schreiben Sie eine Methode druckeGanzenNamen(), die mit System.out.println den
vollständigen Namen auf das Konsolenfenster ausgibt. Diese Methode sollte getGanzerName
verwenden!
22. Schaffen Sie es, das Geburtsdatum einschließlich Wochentag auszugeben?
Berechnung des Alters einer Person
Wir ergänzen jetzt noch eine Methode, die das Alter der Person liefert. Dafür brauchen wir eine
Instanz von GregorianCalender, die das aktuelle Datum enthält. Wir nennen sie heute und
erhalten sie, indem wir den Konstruktor ohne Parameter aufrufen. Dann schließt sich die
Berechnung des Alters an, die nicht ganz einfach ist, weil zunächst festgestellt werden muss, ob die
Person im laufenden Jahr bereits Geburtstag hatte (oder gerade hat). Die Verwendung einer
Hilfsvariablen hatteSchonGeburtstag macht den folgenden Quelltext (hoffentlich) leicht
verständlich:JAVA-Einführung, Seite 21
public int getAlter()
{
boolean hatteSchonGeburtstag = false; // wird nach Prüfung evt. true
GregorianCalendar heute = new GregorianCalendar(); // Kalenderobjekt für
// heutiges Datum
if (heute.get(Calendar.MONTH) > geburtsDatum.get(Calendar.MONTH))
// Person hatte in diesem Jahr
hatteSchonGeburtstag = true; // schon Geburtstag. Weitere Prüfung
else // bei gleichem Monat:
if (heute.get(Calendar.MONTH) == geburtsDatum.get(Calendar.MONTH)
& heute.get(Calendar.DAY_OF_MONTH) >=
geburtsDatum.get(Calendar.DAY_OF_MONTH)) // Tag vergleichen
hatteSchonGeburtstag = true;
if (hatteSchonGeburtstag)
return heute.get(Calendar.YEAR) - geburtsDatum.get(Calendar.YEAR);
else
return heute.get(Calendar.YEAR) - geburtsDatum.get(Calendar.YEAR) - 1;
}
Vererbung
Jetzt sollen zwei weitere Klassen erstellt werden: Eine Klasse Schüler und eine Klasse Lehrer.
Da Schüler und Lehrer natürlich Personen sind, sollen auch sie Namen und Geburtsdatum besitzen.
Zusätzlich sollen Schüler aber ein Datenfeld für ihre Schulklasse (z.B. "11c", also vom Typ String)
besitzen. Lehrern geben wir keine Schulklasse, dafür aber zwei Unterrichtsfächer (weil das für die
meisten Lehrer am Gymnasium zutrifft).
Natürlich könnte man den Quelltext von Person kopieren, um alles zu übernehmen, und man
müsste nur die Klassenbezeichnung (Objektklasse, nicht Schulklasse – der Begriff „Klasse“ ist in
diesem Abschnitt leider nicht eindeutig!) im Konstruktor anpassen. Für den Zugriff auf
Unterrichtsfächer bzw. die Schulklasse wären noch wenige Methoden zu ergänzen. Dann hätten wir
aber einen großen Teil des Quelltextes 3 mal zu verwalten. Ein Fehler in der Berechnung des Alters
müsste in 3 Textdateien korrigiert werden. Um solche Nachteile zu vermeiden, wurde die
Möglichkeit geschaffen, von vorhandenen Klassen erweiterte Klassen abzuleiten. Die abgeleiteten
Klassen erben dann alle Eigenschaften und Methoden der Vorgängerklasse.
Zunächst erstellen wir in unserem Projekt eine neue
Klasse mit der Bezeichnung „Schüler“ (oder „Schueler“)
und eine weitere mit der Bezeichnung „Lehrer“.
Es gibt bei BlueJ zwei Verfahren, um diese Klassen als
Erweiterungen von Person zu deklariereren.
Methode 1:
Im BlueJ-Fenster wählen wir mit der Maus den Pfeil mit
durchgezogener Linie aus und ziehen damit einen Pfeil von
Lehrer zu Person.
Methode 2: Wir fügen in der public class Schüler extends Person
Klasse Schüler die zwei {
Wörter extends Person ein .... ...
(s. Abb.). }Sie können auch lesen