Schritt 8 - Validierungen
Bisher konnte man für das Gewicht einer Person ohne Weiteres unsinnige Werte wie -12 oder 1200 eingeben. Wir wollen die Setter-Methode setGewicht(...) nun so verändern, dass solche Eingaben automatisch korrigiert werden.
Für Jugendliche und Erwachsene soll das zulässige Gewicht zwischen 30 kg und 300 kg liegen. Dazu ergänzen wir die Setter-Methode und lernen gleichzeitig ein neues wichtiges Konzept kennen: die Fallunterscheidung.
Betrachten wir zunächst die neue Version der Setter-Methode:
public void setGewicht(double gewicht)
{
if (gewicht < 30) gewicht = 30;
if (gewicht > 300) gewicht = 300;
this.gewicht = gewicht;
}
Die Methode enthält zwei Fallunterscheidungen.
Erste Fallunterscheidung
if (gewicht < 30) gewicht = 30;
Hier wird überprüft, ob der übergebene Parameter gewicht kleiner als das zulässige Minimalgewicht von 30 kg ist. Ist das der Fall, erhält der Parameter einfach den Wert 30. Andernfalls geschieht nichts, der Parameter behält also seinen ursprünglichen Wert.
Zweite Fallunterscheidung
Die zweite Fallunterscheidung funktioniert ganz genauso. Hier wird geprüft, ob das zulässige Maximalgewicht von 300 kg überschritten wird. Ist das der Fall, erhält der Parameter den Wert 300. Andernfalls bleibt sein Wert unverändert.
Nach diesen beiden Fallunterscheidungen besitzt der Parameter gewicht garantiert einen Wert innerhalb des zulässigen Bereichs. Erst jetzt wird dieser Wert der Instanzvariablen this.gewicht zugewiesen.
⇒ Ergänzen Sie den Quelltext der Methode setGewicht(...) um diese beiden Fallunterscheidungen.
⇒ Ergänzen Sie dann das Testprogramm so, dass Sie überprüfen können, ob setGewicht(...) nun korrekt arbeitet und Falscheingaben korrigiert.
Flussdiagramm
Die Arbeitsweise der validierenden Setter-Methode setGewicht(...) kann man durch ein Flussdiagramm sehr übersichtlich darstellen:
Flussdiagramm zur Setter-Methode setGewicht(double gewicht)
Autor: Ulrich Helmich 07/2026, Lizenz: Public domain
Fallunterscheidungen werden in einem Flussdiagramm durch sogenannte Entscheidungsrauten dargestellt. In jeder Raute steht eine Bedingung, die entweder wahr (true) oder falsch (false) ist.
Im ersten Schritt wird die Bedingung gewicht < 30 überprüft. Ist sie wahr, erhält die Variable gewicht den Wert 30. Anschließend wird das Programm mit der letzten Anweisung this.gewicht = gewicht fortgesetzt.
Ist die erste Bedingung dagegen falsch, wird die zweite Bedingung gewicht > 300 überprüft. Ist diese wahr, wird der Wert der Variablen auf 300 gesetzt. Andernfalls bleibt der Wert unverändert.
In beiden Fällen wird anschließend die letzte Anweisung ausgeführt und der (gegebenenfalls korrigierte) Wert in der Instanzvariablen gespeichert.
Theorie: Fallunterscheidungen mit if
Mit einer Fallunterscheidung kann ein Java-Programm auf unterschiedliche Situationen reagieren. Ob eine bestimmte Anweisung ausgeführt wird oder nicht, hängt von einer Bedingung ab.
Die allgemeine Form einer einfachen Fallunterscheidung lautet:
if (Bedingung)
Anweisung;
Zunächst wird die Bedingung in den Klammern überprüft. Ist sie erfüllt, wird die folgende Anweisung ausgeführt. Ist die Bedingung nicht erfüllt, wird diese Anweisung einfach übersprungen.
Betrachten wir ein Beispiel:
if (gewicht < 30)
gewicht = 30;
Zunächst wird geprüft, ob der Wert der Variablen gewicht kleiner als 30 ist.
- Ist die Bedingung erfüllt (true), wird der Variablen der Wert 30 zugewiesen.
- Ist die Bedingung nicht erfüllt (false), geschieht nichts.
Vergleichsoperatoren
Für Bedingungen werden häufig die folgenden Vergleichsoperatoren verwendet:
| Operator | Bedeutung |
|---|---|
| < | kleiner als |
| <= | kleiner oder gleich |
| > | größer als |
| >= | größer oder gleich |
| == | gleich |
| != | ungleich |
Merke:
if-Anweisungen
Eine if-Anweisung entscheidet, ob eine Anweisung ausgeführt wird oder nicht. Die Entscheidung hängt davon ab, ob die Bedingung in den Klammern true (wahr) oder false (falsch) ergibt.
Aufgabe 3.3-1
A) Recherchieren Sie, welche Körpergrößen für Jugendliche und Erwachsene sinnvoll sind.
B) Werten Sie dann die Setter-Methode setGroesse(...) zu einer validierenden Setter-Methode auf, analog zu setGewicht(...).
Schritt 9 - Besseres Idealgewicht
Bisher wurde das Idealgewicht nur aus der Körpergröße berechnet. Diese Formel ist allerdings sehr grob. In vielen Tabellen wird zwischen Männern und Frauen unterschieden. Deshalb ergänzen wir unsere Klasse um das neue Attribut Geschlecht und passen anschließend die Methode getIdealgewicht() entsprechend an.
Wenn das Geschlecht der Person weiblich ist, soll das Normalgewicht (Körpergröße - 100) nicht mit 0,9 multipliziert werden, sondern mit 0,85.
Um dies zu erreichen, müssen wir
1.) Die Klasse Person um das Attribut Geschlecht ergänzen
2.) Die Getter-Methode getIdealgewicht() um eine Fallunterscheidung ergänzen, die je nach Geschlecht einen anderen Faktor für die Berechnung benutzt, bei Männern 0,9 und bei Frauen 0.85.
Das Attribut Geschlecht
Grundsätzlich könnte man dieses Attribut auf verschiedene Weisen als Instanzvariable deklarieren:
- int geschlecht (1 = männlich, 2 = weiblich)
- String geschlecht ("m" = männlich, "w" = weiblich)
- char geschlecht ('m' bzw. 'w')
Hier lernen wir einen neuen Datentypen kennen:
char steht für einzelne Zeichen (Buchstaben, Zahlen, Sonderzeichen), die Zeichen werden dabei in einfache Anführungszeichen gesetzt, nicht in doppelte wie bei Strings.
In diesem Kurs entscheiden wir uns jetzt für die dritte Variante:
private char geschlecht;
Die Setter-Methode für das Geschlecht
Schauen wir uns nun die Setter-Methode setGeschlecht() näher an:
public void setGeschlecht(char g)
{
if (g == 'm' || g == 'M')
geschlecht = 'm';
if (g == 'w' || g == 'W')
geschlecht = 'w';
if (g == 'd' || g == 'D')
geschlecht = 'd';
}
Wenn als Parameter ein 'm' oder ein 'M' übergeben wird, erhält die Instanzvariable geschlecht den Wert 'm'. Entsprechendes gilt für 'w' und 'W' sowie für 'd' und 'D'.
Neu ist hier die Verknüpfung von zwei Bedingungen mit dem ODER-Operator:
if (g == 'w' || g == 'W')
Die Gesamtbedingung ist erfüllt, wenn eine der beiden Teilbedingungen g == 'w' oder g == 'W' true ist. Wenn beide Teilbedingungen false sind, ist auch die Gesamtbedingung false. Der ODER-Operator wird in Java durch zwei senkrechte Striche || realisiert, die man auf der Tastatur erst mal finden muss.
Was passiert, wenn keines der sechs erlaubten Zeichen als Parameter übergeben wird?
Diese Situation kann man auf zwei verschiedene Weisen regeln.
1. Default-Wert bereits im Konstruktor setzen:
public Person(String name, String vorname, int alter)
{
this.name = name;
etc ...
geschlecht = 'u'; // unbekannt
}
2. Default-Wert in der Setter-Methode festlegen:
public void setGeschlecht(char g)
{
geschlecht = 'u';
if (g == 'm' || g == 'M')
geschlecht = 'm';
if (g == 'w' || g == 'W')
geschlecht = 'w';
if (g == 'd' || g == 'D')
geschlecht = 'd';
}
Beide Lösungen funktionieren. In diesem Skript wird der Standardwert bereits im Konstruktor gesetzt, weil dort alle Instanzvariablen ihren Anfangswert erhalten.
Die Getter-Methode für das Geschlecht
Die Methode getGeschlecht() ist recht schnell implementiert, allerdings liefert diese Methode nur einen einfachen Buchstaben vom Typ char zurück. Schöner wäre es, wenn die Methode einen besser lesbaren Text wie "männlich", "weiblich", "divers" oder "unbekannt" zurückliefern würde.
Eine solche Methode lässt sich mit wenigen Fallunterscheidungen implementieren:
public String getGeschlechtString()
{
if (geschlecht == 'm')
return "männlich";
if (geschlecht == 'w')
return "weiblich";
if (geschlecht == 'd')
return "divers";
return "unbekannt";
}
Sobald eine der Bedingungen erfüllt ist, wird der entsprechende Text mit return zurückgegeben. Dabei wird gleichzeitig die Methode beendet, sodass die übrigen Bedingungen nicht mehr überprüft werden. Ist keine Bedingung erfüllt, liefert die Methode den Text "unbekannt" zurück.
Die Methode getIdealgewicht()
Man könnte diese Methode nun folgendermaßen implementieren:
public double getIdealgewicht()
{
double normalgewicht, faktor;
normalgewicht = groesse - 100;
faktor = 0.875;
if (geschlecht == 'm')
faktor = 0.9;
if (geschlecht == 'w')
faktor = 0.85;
return normalgewicht * faktor;
}
Zunächst werden hier zwei lokale Variablen angelegt, normalgewicht und faktor.
Lokale Variablen sind Variablen, die nur innerhalb einer Methode gültig sind. Außerhalb der Methode getIdealgewicht() kann man weder auf normalgewicht noch auf faktor zugreifen; außerhalb dieser Methode existieren beide Variablen nicht.
Dann wird das sogenannte Normalgewicht berechnet: Körpergröße in Zentimetern minus 100. Für die Variable faktor wird zunächst der Default-Wert 0.875 festgelegt. Er entspricht dem Mittelwert aus 0.9 (für Männer) und 0.85 (für Frauen).
Als Nächstes wird überprüft, ob es sich um eine männliche Person handelt. In diesem Fall wird faktor auf 0.9 gesetzt, andernfalls behält faktor den Default-Wert 0.875.
Im nächsten Schritt wird gefragt, ob die Person weiblich ist. Sollte das der Fall sein, erhält faktor den Wert 0.85.
Ist die Person weder männlich noch weiblich, wird faktor nicht verändert und behält seinen Default-Wert von 0.875. Am Ende der Methode wird das Normalgewicht mit diesem Faktor multipliziert. Das Ergebnis wird anschließend mit return als Idealgewicht zurückgegeben.
Bisher haben Sie Folgendes gelernt
Es wird Zeit, dass wir einmal zusammenfassen, was Sie in den bisherigen drei Abschnitten der Folge 3 alles gelernt haben und was Sie jetzt können (sollten). Ich habe diese Zusammenfassung von einer KI (ChatGPT) erstellen lassen und bin jetzt selbst einmal gespannt, was dabei herausgekommen ist.
- Sie können eigene Klassen erstellen und Objekte dieser Klassen erzeugen.
- Sie können Instanzvariablen mit geeigneten Datentypen deklarieren.
- Sie können Konstruktoren schreiben und Instanzvariablen mithilfe von Parametern initialisieren.
- Sie kennen die Bedeutung des Schlüsselwortes this.
- Sie können Getter- und Setter-Methoden implementieren.
- Sie kennen den Zweck des Schlüsselwortes private und wissen, wie dadurch eine einfache Datenkapselung erreicht wird.
- Sie können berechnende Getter-Methoden schreiben, die einen Wert berechnen und mit return zurückgeben.
- Sie kennen lokale Variablen und können sie innerhalb von Methoden verwenden.
- Sie können mithilfe von Fallunterscheidungen (if) Eingabewerte überprüfen und gegebenenfalls korrigieren.
- Sie kennen die wichtigsten Vergleichsoperatoren sowie den ODER-Operator ||.
- Sie kennen die Datentypen char und boolean und können sie in einfachen Programmen einsetzen.
- Sie können eine Testklasse schreiben, mit der sich Objekte einer Klasse automatisch erzeugen und testen lassen.
Ich würde noch einen letzten Punkt ergänzen, weil er den roten Faden der gesamten Folge 3 schön zusammenfasst:
- Sie können Klassen schrittweise erweitern, indem Sie neue Attribute und Methoden hinzufügen und vorhandene Methoden verbessern.
Dieser letzte Punkt macht deutlich, dass Softwareentwicklung ein schrittweiser Prozess ist – genau das haben Sie in Folge 3 praktisch erlebt.
Das ist eigentlich eine sehr treffende Zusammenfassung; besser hätte ich es auch nicht machen können. Auch der von ChatGPT generierte Zusatz am Ende, dass die Softwareentwicklung ein schrittweiser Prozess ist, ist völlig richtig. Und mit BlueJ haben Sie ein tolles Werkzeug, mit dem Sie ohne aufwendige Versionsverwaltung ein Projekt Schritt für Schritt entwickeln können, indem Sie einfach vor jeder größen Änderung die alte Version sichern und dann mit "Speichern unter" die nächste Version anlegen.
Ausblick
In dem nächsten Teil der Folge 3 werden wir uns näher mit if- und vor allem mit if-else-Bedingungen beschäftigen.
Seitenanfang -
Weiter mit der Folge 3.4 - if-else-Bedingungen...