Telefonbuch-Spielwiese
Lösung geprüft
Die Aufgabe der heutigen Stunde ist die Telefonbuch-Spielwiese! Alle Klassen stehen, jetzt bauen wir endlich einen echten Kontakt zusammen und lassen ihn ausgeben. Das ist der Moment, in dem man merkt, ob das Zusammenspiel der sechs Klassen wirklich funktioniert.
Schreibe eine Klasse Spielwiese und probiere und teste
die Klasse Kontakt aus. Zum Beispiel könnte die
Spielwiese die folgende Ausgabe auf der Konsole erzeugen.
Datei speichern: neue Zip-Datei
Telefonbuch_nachname.zip mit Code und UML.
Zusatz: Bringen Sie ihre Ausgabe der Spielwiese durch passende Methoden in eine schönere Formatierung.
Lösungsprozess der Aufgabe
/**
*
* Spielwiese fuer das Telefonbuch
*
* @version 1.0 vom 14.09.2025
* @meininfokurs.cmrg.site
*/
import java.time.LocalDate;
import java.time.LocalTime;
public class Spielwiese {
public static void main(String[] args) {
// Ein Kontakt, erstmal nur mit Namen
Kontakt firma = new Kontakt("Muster GmbH");
// Adresse, Telefon und E-Mail nachtragen
firma.setAdresse(new Adresse("Hauptstr.", "1", "65183",
"Wiesbaden", "DE",
Adresse.Typ.GESCHAEFTLICH));
firma.setTelefon(new Telefon("+49 611 123456", Telefon.Typ.FESTNETZ));
firma.setEmail(new Email("info@muster.de", Email.Typ.GESCHAEFTLICH));
// Zwei Termine: einer mit Uhrzeit, einer ohne
firma.fuegeTerminHinzu(new Termin(LocalDate.of(2025, 9, 1),
LocalTime.of(14, 30),
Termin.Art.GESCHAEFTLICH));
firma.fuegeTerminHinzu(new Termin(LocalDate.of(2025, 12, 24),
Termin.Art.GEBURTSTAG));
// Zwei Gruppen
firma.fuegeGruppeHinzu(new Gruppe("Lieferanten"));
firma.fuegeGruppeHinzu(new Gruppe("Newsletter"));
// Ausgeben - ruft intern toString() auf
System.out.println(firma);
} // end of main
} // end of class Spielwiese
Und das kommt dabei raus
=== Kontakt ===
Name : Muster GmbH
Adresse{
strasse='Hauptstr.'
, hausnummer='1'
, plz='65183'
, ort='Wiesbaden'
, land='DE'
, typ='GESCHAEFTLICH'
'}
Telefon : Telefon{nummer='+49 611 123456', typ=FESTNETZ}
E-Mail : Email{adresse='info@muster.de', typ=GESCHAEFTLICH}
=== Termine ===
Termin{datum=2025-09-01, uhrzeit=14:30, art=GESCHAEFTLICH}
Termin{datum=2025-12-24, uhrzeit=null, art=GEBURTSTAG}
=== Gruppen ===
Gruppe{name='Lieferanten'}
Gruppe{name='Newsletter'}
Ein einziges println für all das
Im ganzen main steht genau ein
System.out.println(firma);. Alles andere passiert von
selbst, weil toString() automatisch aufgerufen wird – und
zwar kettenweise: die toString() von Kontakt
hängt adresse an einen String, dadurch wird die
toString() von Adresse aufgerufen, und so
weiter durch alle sechs Klassen.
Das ist der Grund, warum wir in jeder Klasse eine
toString() geschrieben haben. Hättest du eine vergessen,
stünde an der Stelle Gruppe@6d06d69c statt
Gruppe{name='Lieferanten'}. Damit findest du auch schnell
die Klasse, in der sie fehlt.
uhrzeit=null ist kein Fehler
Beim zweiten Termin steht uhrzeit=null. Das ist genau so
gewollt: der Geburtstag wurde über den Konstruktor ohne Uhrzeit angelegt,
also gibt es keine. null heißt hier „bewusst nicht
gesetzt".
Aufpassen musst du nur, wenn du damit weiterrechnest.
firma.getTermine().get(1).getUhrzeit().getHour() würde eine
NullPointerException werfen, weil man von
null keine Stunde erfragen kann. Beim Ausgeben ist es
harmlos – da macht Java daraus einfach den Text „null".
Warum erst der Konstruktor mit einem Argument
Der Kontakt wird mit new Kontakt("Muster GmbH") angelegt
und alles Weitere danach über Setter nachgetragen. Das könnte man auch
mit dem großen Konstruktor auf einmal machen – nur müsste man dafür die
beiden Listen vorher selbst bauen und befüllen, und der Aufruf hätte sechs
Argumente. So ist es lesbarer, und es entspricht auch dem, was die App
macht: erst den Namen eintippen, dann Stück für Stück ergänzen.
Möglich ist das nur, weil der kleine Konstruktor die Listen anlegt.
Ohne das würde der erste fuegeTerminHinzu sofort abstürzen.
Zur Zusatzaufgabe: schöner formatieren
Die Ausgabe der Adresse ist ehrlich gesagt nicht schön – die Kommas
stehen am Zeilenanfang und am Ende hängt ein einsames '}.
Das kommt daher, dass die toString() automatisch erzeugt und
dann mit Zeilenumbrüchen versehen wurde.
Für die Zusatzaufgabe schreibt man eine eigene Methode daneben, statt
toString() zu verbiegen:
// in der Klasse Adresse
public String formatiert() {
return strasse + " " + hausnummer + "\n"
+ plz + " " + ort + " (" + land + ")" + "\n"
+ "Typ: " + typ;
}
Damit wird aus dem Klammergewirr:
Hauptstr. 1
65183 Wiesbaden (DE)
Typ: GESCHAEFTLICH
Warum nicht einfach toString() umschreiben? Weil die beiden
verschiedene Zwecke haben. toString() soll beim Debuggen
zeigen, was wirklich im Objekt steht – mit allen Attributnamen,
auch wenn es hässlich aussieht. formatiert() ist für den
Benutzer. Beides in eine Methode zu stopfen geht meistens schief.
.java- und alle .uml-Dateien zu
Kontakt, Telefon, Email, Adresse, Termin, Gruppe und Spielwiese. Wer nur
die Java-Dateien einpackt, hat die halbe Abgabe vergessen.