Folge 9: Arraylisten

In dieser Folge wollen wir uns vornehmen, eine Sparkasse zu simulieren. Die Klasse Bank soll aus einer endlichen Menge von Konten bestehen; ein Objekt der Klasse Konto wiederum besteht aus einer Kontonummer und einem Betrag.

Wichtige Vorbemerkungen:

Ich habe die Folge 9 für meine Buch-Version völlig neu erstellt; von einer Bearbeitung kann nicht die Rede sein, das Kapitel wurde ganz neu geschrieben; und zwar ohne Verwendung von Arrayliste. Die Konten und die Kunden werden mithilfe einfacher Objekt-Arrays verwaltet. Aus reiner Bequemlichkeit werde ich diese Web-Version der Folge 9 nicht mehr überarbeiten. Wer will, kann diese Folge gern im eigenen Unterricht einsetzen. In der Buch-Version findet sich jedenfalls die überarbeitete Version mit Exkursen zum Thema "UML" und "Klassendiagramme in UML" sowie "HAT- und KENNT-Beziehungen". Auf das Thema "Arraylisten" werde ich in der Folge 10 der Buch-Version eingehen, die ich aber noch schreiben muss...


Schritt 1

Die Klasse Konto

Bitte starten Sie BlueJ und legen Sie ein neues Projekt an, das zum Beispiel "Volksbank" heißen könnte. Erzeugen Sie dann eine neue Klasse mit dem Namen Konto. Doppelklicken Sie dann auf die Klasse und geben Sie folgenden Quelltext ein:

1 Der Quelltext der Klasse Konto

Die Klasse Konto umfasst zwei Attribute sowie den Konstruktor und drei Methoden:

Die verändernden Methoden

Mit einzahlen() wird ein Betrag auf das Konto eingezahlt. Eine Überprüfung findet hier nicht statt, so dass theoretisch auch negative Beträge eingezahlt werden können.

Mit abheben() erreichen wir genau das Gegenteil. Auch hier findet keine Überprüfung statt, so dass das Konto durchaus in die roten Zahlen rutschen kann.

Die abfragenden Methoden

Die Methode gibStand() liefert uns den Kontostand zurück. Natürlich könnte man auch den Attributwert von stand direkt abfragen, das widerspräche aber dem Prinzip der Datenkapselung.

Schritt 2

Übersetzen Sie den Quelltext, erzeugen Sie ein Objekt der Klasse Konto (Kontonummer festlegen, z.B. 10010) und zahlen Sie dann einen Betrag auf das Konto ein.

2 Die Klasse Konto wird intensiv getestet.

Rufen Sie anschließend gibStand() auf, um zu testen, ob der Kontostand korrekt aktualisiert wurde. Testen Sie einzahlen(), abheben() und gibStand() mehrmals, bevor Sie mit der Übung weitermachen.

Wenn man eine größere Anwendung mit mehreren Klassen programmiert, sollte man jede Klasse zunächst intensiv testen, bevor man die nächste Klasse in Angriff nimmt.

Übung 9.1 (2 Punkte)

Verändern Sie einzahlen() so, dass das Einzahlen negative Beträge verhindert wird.

Verändern Sie abheben() so, dass nicht mehr Geld vom Konto abgehoben werden kann, als den Kreditrahmen von 5000 Euro übersteigt. Mit anderen Worten: es können maximal 5000 Euro Schulden gemacht werden.

Übung 9.2 (2 Punkte)

Ergänzen Sie die Klasse Konto um eine Methode setzeKreditrahmen(int rahmen), welche den Kreditrahmen auf den angegebenen Betrag, z.B. 5000, setzt. Ergänzen Sie die Klasse um ein entsprechendes Attribut, so dass auch die anderen Methoden auf den Kreditrahmen zugreifen können.

Verzweigungen

Schritt 3

Die Klasse Bank

Erzeugen Sie eine neue Klasse Bank und geben Sie dann folgenden Quelltext ein:

3 Der Quelltext der Klasse Bank

Was eine ArrayList genau ist, wird weiter unten erklärt. Bitte haben Sie Geduld!

Schritt 4

Erstellen Sie jetzt die Objekte konto1, konto2 und volksbank, zahlen Sie Beträge auf die beiden Konten ein und fügen Sie dann der volksbank das konto1 hinzu:

4 Hinzufügen eines Konto-Objektes zur Bank

Arraylisten

Jetzt wollen wir den Quelltext der Klasse Bank näher untersuchen. Das Besondere ist hier die Verwendung einer Arrayliste.

1. Was ist eine Arrayliste?

Die Klasse ArrayList dient zum Speichern von Objekten. In einer ArrayList kann man viele Objekte ein- und derselben Klasse speichern (aber auch Objekte, die verschiedenen Klassen angehören).

Unsere Klasse Bank soll viele Konten verwalten - genauer gesagt: soll viele Objekte der Klasse Konto verwalten. Dazu könnte man die Objekt in einem Array speichern. Noch einfacher ist es aber, wenn wir die vordefinierte Klasse ArrayList einsetzen.

2. Was müssen wir tun, um Konto-Objekte in einer ArrayList zu speichern?

Eine ArrayList ist eine Klasse. Damit unsere eigene Klasse Bank die Konten in einer ArrayList speichern kann, muss Bank erst einmal ein Attribut vom Typ ArrayList besitzen. Daher deklarieren wir:

private ArrayList kontoliste;

Die Arrayliste, in der wir die Konten speichern wollen, heißt jetzt also kontoliste. Wie jedes Objekt, muss auch kontoliste initialisiert werden. Dies geschieht durch die Anweisung

kontoliste = new ArrayList();

die wir im Konstruktor der Klasse Bank unterbringen. Nachdem diese Anweisung ausgeführt wurde, existiert die Kontoliste zwar, hat aber noch die Länge 0, ist also leer.

3. Wie bekommen wir ein Konto in die Arrayliste hinein?

Den Objekten der Klasse ArrayList stehen eine ganze Reihe von Methoden zur Verfügung. Eine dieser Methoden ist add(), mit dieser Methode können wir ein beliebiges Objekt zur Arrayliste hinzufügen:

kontoliste.add(k);

Diese Zeile fügt das Konto k der Arrayliste kontoliste hinzu. Wie das im Einzelnen geschieht, braucht uns hier nicht zu interessieren (Prinzip der Datenkapselung).

Die Deklaration eines Objektes erzeugt Speicherplatz für eine Referenz auf das Objekt.




Der new-Befehl erzeugt dann erst das Objekt.

Datenkapselung

Schritt 5

Erzeugen Sie in Ihrer BlueJ-Umgebung weitere Konten, überweisen Sie Geld auf diese Konten und fügen Sie sie dann in das Bank-Objekt ein, indem Sie die Methode hinzufuegenKonto() mehrmals aufrufen.

Mit Objekten der Klasse ArrayList kann man andere Objekte verwalten, zum Beispiel Objekte der Klasse Konto. Eine ArrayList ist also eine Art Container für andere Objekte.

Man könnte auch Objekte anderer Klassen in dieser ArrayList verwalten.

Die Zahl der Objekte, die eine ArrayList aufnehmen kann, ist - zumindest theoretisch - unbegrenzt.

Mit der Methode add() können der ArrayList neue Objekte hinzugefügt werden.

Die Länge einer Arrayliste kann mit dem Befehl size() ermittelt werden.

Schritt 6

Ergänzen Sie die Klasse Bank um folgende Methode:

public int gibAnzahlKonten()
{
   return kontoliste.size();   
}

Testen Sie die Methode anschließend, indem Sie zwei Konten konto1 und konto2 sowie eine bank1 anlegen und die beiden Konten dann der Bank hinzufügen. Wenn Sie jetzt gibAnzahlKonten() aufrufen, muss die zurückgegebene Zahl den Wert 2 haben.

Übung 9.3 (2 Punkte)

Wenn es einen Befehl zum Hinzufügen neuer Objekte zu einer ArrayList gibt, so existiert sicherlich auch ein Befehl zum Löschen von Elementen. Erkundigen Sie sich in der Java-Hilfe oder im Internet, wie der Lösch-Befehl der Klasse ArrayList heist und wie er korrekt aufgerufen wird. Ergänzen Sie dann die Klasse Bank um eine Methode zum Löschen eines bestimmten Kontos:

public void loescheKonto(int i)

Dabei ist der Parameter i der Index (nicht die Nummer) des zu löschenden Kontos.

Achtung:
Das erste Konto hat immer den Index 0, und nicht etwa 1. Also hat das zweite Konto den Index 1 und so weiter.
Programmieren Sie die Methode so, dass nur solche Konten gelöscht werden können, die vorhanden sind. Dazu sollten Sie die Methode size() der Klasse ArrayList verwenden.

Schritt 7

Jetzt wird es richtig kompliziert. Wir wollen wissen, wie viel Geld unsere Bank insgesamt besitzt. Dazu müssen die Guthaben aller Konten addiert werden. Da man mit der Methode size() die Zahl der Konten ermitteln kann, könnte man dies mit Hilfe einer FOR-Schleife recht einfach erledigen. Wir wollen hier aber eine raffiniertere Verfahrensweise kennenlernen, nämlich mit Hilfe eines Iterators.

Ergänzen Sie die Klasse Bank bitte um folgende Methode:

5 Der Quelltext der Methode gibGuthaben()

Legen Sie zwei Konten an, zahlen Sie einmal 1000 Euro, einmal 2000 Euro ein und fügen SIe dann beide Konten zur Bank hinzu, die Sie natürlich auch wieder als Objekt anlegen müssen.

Rufen Sie dann die Methode gibGuthaben() auf. Es müsste jetzt der Betrag von 3000 Euro angezeigt werden.

Wie funktioniert die Methode?

Iteratoren

Mit der Zeile

Iterator it = kontoliste.iterator();

erzeugen wir einen so genannten Iterator. Achten Sie hier genau auf die Groß- und Kleinschreibung: Iterator ist eine Klasse, iterator() aber eine Methode der Klasse ArrayList.

Was passiert hier? Die Methode kontoliste.iterator() liefert einen Rückgabewert, und zwar ein Objekt it der Klasse Iterator.

Die Klasse Iterator ist übrigens Bestandteil der Bibliothek java.util.Iterator, die wir zu Beginn des Quelltextes einbinden müssen. Sie sollten also am Anfang des Bank-Quelltextes schreiben:

import java.util.ArrayList;
import java.util.Iterator;

Nun kommt eine WHILE-Schleife, die Sie auf Anhieb verstehen sollten:

while (it.hasNext() )

Hier wird die hasNext()-Methode des Iterator-Objektes it aufgerufen. Diese Methode liefert den Wert true zurück, falls noch nicht alle Objekte der Arrayliste besucht worden sind. Wenn die Bank zum Beispiel vier Konten hat und die WHILE-Schleife gerade das zweite Konto ausgewertet hat, müssen noch zwei weitere Konten abgearbeitet werden. Also liefert it.hasNext() den Wert true zurück, und die WHILE-Schleife wird ein weiteres Mal durchlaufen.

In der WHILE-Schleife wird jetzt der Stand des jeweiligen Kontos ausgelesen und zu dem Guthaben der Bank dazuaddiert. Dabei spielt der Befehl it.next() eine entscheidende Rolle. Dieser Befehl liefert nämlich das jeweils nächste Objekt der Liste.

Unser Objekt kontoliste enthält Objekte der Klasse Konto. Rein theoretisch könnten aber Objekte irgendeiner Klasse in dieser ArrayList enthalten sein. Mit Hilfe des Cast-Operators (Konto) wird nun dafür gesorgt, dass das Objekt, das it.next() zurückliefert, auf jeden Fall zu einem Konto-Objekt wird.

Schauen wir uns jetzt noch einmal die schwierig zu verstehende Zeile an:

Die next()-Methode des Iterators it liefert ein Objekt, das durch den Cast-Operator in ein Konto-Objekt umgewandelt wird, welches dann in der Variable konto gespeichert werden kann..

Wer das ganze bisher noch nicht so richtig verstanden hat schaut sich doch bitte mal den Theorieteil an, den ich extra für Sie geschrieben habe.

Iteratoren sind Hilfsmittel, um alle Objekte einer ArrayList zu besuchen.


Zwei wichtige Methoden der Klasse Iterator sind
hasNext() und
next()


hasNext() liefert true, falls noch ein Eintrag in der ArrayList existiert.


next() liefert den nächsten Eintrag der ArrayList zurück, allerdings als undefiniertes Objekt.


Der Cast-Operator wandelt das undefinierte Objekt dann in ein Objekt der gewünschten Klasse um.




1. Arraylisten enthalten Arrays

2. Arraylisten können Element für Element durchlaufen werden

Übung 9.4 (5 Punkte)

Ergänzen Sie die Klasse Bank um eine Methode, die eine Übersicht über sämtliche in der Bank vorhandenen Konten anzeigt. Dazu müssen Sie den System.out.println()-Befehl einsetzen. Ihre Ausgabe könnte zum Beispiel so aussehen:

6 Eine mögliche Ausgabe der Methode zeigeUebersicht()

Das Beispiel in Abbildung 6 gibt den Index und den Kontostand aus. Noch besser wäre es natürlich, statt des Index die Kontonummer auszugeben.

Übung 9.5 - A (7 Punkte)

Ergänzen Sie das Programm um eine Klasse Kunde, welche zwei Attribut hat, nämlich name und vorname, beide vom Typ String. Dem Konstruktor Kunde() übergeben Sie den Namen und den Vornamen als Parameter, und außerdem schreiben Sie eine Methode zeigeDaten(), welche die beiden Attribute über System.out.println() anzeigt.

Verändern Sie dann den Konstruktor der Klasse Konto wie folgt:

public Konto(int nummer, Kunde kunde)

Beim Erzeugen eines neuen Konto-Objektes soll also die Kontonummer und ein Kunden-Objekt als Parameter übergeben werden.

Schreiben Sie dann eine Methode Konto.zeigeDaten(), die so aussieht:

  
public void zeigeDaten()
{
   System.out.println("Kontonr : " + nummer);
   System.out.println("Stand   : " + stand);
   kunde.zeigeDaten();
}
                    

Die zeigeDaten()-Methode von Konto ruft also die zeigeDaten()-Methode von Kunde auf. Eine einfache Form der Delegation einer Aufgabe.

Nun müssen Sie nur noch die Klasse Bank bearbeiten. Nennen Sie die Ausgabe-Methode jetzt auch zeigeDaten() und delegieren Sie den größten Teil der Ausgabe an die zeigeDaten()-Methode der Klasse Konto.

Übung 9.5 - B (7 Punkte)

Schreiben Sie eine BlueJ-Anwendung mit den beiden Klassen Person und Gruppe. Die Klasse Person soll über die Attribute koerpergroesse und gewicht verfügen, die Klasse Gruppe soll ein Attribut personenliste enthalten, welche eine ArrayList ist, in der Person-Objekte gespeichert werden können.

Statten Sie die Klassen mit Methoden aus, die zum Beispiel erlauben, dass eine Person sich wiegt und ihre Körpergröße misst. Die Klasse Gruppe muss eine Methode zum Hinzufügen von Personen haben. Außerdem sollte die Klasse Gruppe zwei Methoden besitzen, die das Durchschnittsgewicht und die Durchschnittsgröße aller in der Gruppe vorhandenen Personen berechnen.

Die Übungen 8.2 - A und B sind alternativ gedacht. Suchen Sie sich eine von den beiden Übungen aus! Sie können zwar beide Übungen machen, es wird Ihnen dann aber nur eine angerechnet (die, für die Sie die meisten Punkte erreicht haben). Eine dritte Alternative - hier können Sie sogar 10 Punkte erreichen - finden Sie auf der Adventuregame-Seite.

Die Klasse ArrayList

Weitere Übungen zur Folge 9

Diese HTML-Seite wurde erstellt von Ulrich Helmich am 27. Februar 2005 mit Golive 6 und neu bearbeitet am 18. September 2006. Eine weitere Bearbeitung ist nicht geplant.






IMPRESSUM