Pflanzen im Schulgewächshaus
AFB I–IIDie Garten-AG simuliert das Wachstum ihrer Pflanzen im Schulgewächshaus. Jede Pflanze hat einen Wasserstand in Prozent (0 bis 100) und eine Höhe in Zentimetern. Je nach Art verbraucht sie pro Tag unterschiedlich viel Wasser. Eine neue Pflanze startet mit einem Wasserstand von 50 und einer Höhe von 5,0 cm.
Die Methoden sollen sich so verhalten: giessen(menge) erhöht den Wasserstand um die angegebene Menge, jedoch höchstens auf 100; nicht positive Mengen bleiben ohne Wirkung. tagVergeht() verringert den Wasserstand um den Tagesverbrauch, jedoch nicht unter 0. Liegt der Wasserstand danach bei mindestens 30, wächst die Pflanze um 0,5 cm. brauchtWasser() liefert genau dann true, wenn der Wasserstand unter 30 liegt.
- - name: Zeichenkette
- - wasserstand: Ganzzahl
- - hoehe: Fließkommazahl
- - verbrauch: Ganzzahl
- c Pflanze(name: Zeichenkette, verbrauch: Ganzzahl)
- + giessen(menge: Ganzzahl)
- + tagVergeht()
- + getWasserstand(): Ganzzahl
- + getHoehe(): Fließkommazahl
- + brauchtWasser(): Wahrheitswert
public class Pflanze {
private String name;
private int wasserstand;
private double hoehe;
private int verbrauch;
public Pflanze(String name, int verbrauch) {
this.name = name;
this.verbrauch = verbrauch;
wasserstand = 50;
hoehe = 5.0;
}
// hier fehlen die Methoden
}
Pflanze p = new Pflanze("Basilikum", 15);
p.tagVergeht();
p.tagVergeht();
System.out.println(p.brauchtWasser());
p.giessen(90);
p.tagVergeht();
System.out.println(p.getWasserstand() + " / " + p.getHoehe());
// Entwurf von Ben (Ausschnitt) public void Pflanze(String name, int verbrauch) { name = name; verbrauch = verbrauch; wasserstand = 50; hoehe = 5.0; } public int getWasserstand() { wasserstand; }
- Ergänzen Sie die Klasse aus Material 1 um die fünf im Diagramm angegebenen Methoden gemäß der Beschreibung.
- Ermitteln Sie die beiden Ausgaben des Testprogramms aus Material 2. Notieren Sie dazu nach jedem Aufruf den Wasserstand und die Höhe.
- Erklären Sie für jede markierte Stelle in Bens Entwurf, warum sie fehlerhaft ist und welche Folge sie hat, und geben Sie jeweils eine Korrektur an.
Hinweise
Hinweis zu Aufgabe a)
void; Ganzzahl → int, Wahrheitswert → boolean. Für „höchstens 100“ bzw. „nicht unter 0“ brauchst du nach der Rechnung eine if-Abfrage. Anfragen enden mit return.„Ergänzen“ heißt: die vorgegebene Lösung beibehalten und nach den Vorgaben erweitern – Attribute und Konstruktor nicht neu schreiben.Hinweis zu Aufgabe b)
tagVergeht() auf die Reihenfolge: erst Wasser abziehen, dann prüfen, ob gewachsen wird. Und beim Gießen: Gibt es eine Obergrenze?Hinweis zu Aufgabe c)
int immer enthalten?„Erklären“ heißt: den Fehler auf die zugrunde liegende Regel von Java zurückführen, nicht nur die Korrektur hinschreiben.Erwartungshorizont
Erwartungshorizont zu Aufgabe a)
public void giessen(int menge) {
if (menge > 0) {
wasserstand = wasserstand + menge;
if (wasserstand > 100) {
wasserstand = 100;
}
}
}
public void tagVergeht() {
wasserstand = wasserstand - verbrauch;
if (wasserstand < 0) {
wasserstand = 0;
}
if (wasserstand >= 30) {
hoehe = hoehe + 0.5;
}
}
public int getWasserstand() {
return wasserstand;
}
public double getHoehe() {
return hoehe;
}
public boolean brauchtWasser() {
return wasserstand < 30;
}
Bewertet werden korrekte Methodenköpfe (Sichtbarkeit, Rückgabetyp, Parameter), die Begrenzung auf 0 bis 100, die Wachstumsbedingung nach dem Abziehen und die return-Anweisungen. Gleichwertige Lösungen (z. B. Math.min oder if (…) { return true; } else { return false; }) sind zu akzeptieren.
Erwartungshorizont zu Aufgabe b)
Start: wasserstand = 50, hoehe = 5.0
1. tagVergeht(): 50 − 15 = 35 ≥ 30 → hoehe = 5.5
2. tagVergeht(): 35 − 15 = 20 < 30 → hoehe bleibt 5.5
Ausgabe 1: true (20 < 30)
3. giessen(90): 20 + 90 = 110 → begrenzt auf 100
4. tagVergeht(): 100 − 15 = 85 → hoehe = 6.0
Ausgabe 2: 85 / 6.0
Häufiger Fehler: Die Begrenzung auf 100 übersehen (Ergebnis dann 95).
Erwartungshorizont zu Aufgabe c)
void im Konstruktor: Ein Konstruktor hat keinen Rückgabetyp. Mit void entsteht eine gewöhnliche Methode, die zufällig wie die Klasse heißt. Java stellt dann nur den parameterlosen Standardkonstruktor bereit, und new Pflanze("Basilikum", 15) lässt sich nicht übersetzen. Korrektur: public Pflanze(String name, int verbrauch).
name = name; und verbrauch = verbrauch;: Der Parameter überdeckt das gleichnamige Attribut; beide Seiten bezeichnen den Parameter, er wird sich selbst zugewiesen. Die Attribute behalten ihre Standardwerte (null bzw. 0) – die Pflanze verbraucht dann nie Wasser. Korrektur: this.name = name; und this.verbrauch = verbrauch;.
wasserstand;: Eine Methode mit Rückgabetyp int muss einen Wert mit return zurückgeben; die bloße Nennung der Variablen ist keine gültige Anweisung, der Compiler meldet einen Fehler. Korrektur: return wasserstand;.
Reparaturaufträge in der Kfz-Werkstatt
AFB II–IIIDie Kfz-Werkstatt Kemper ersetzt ihre Auftragszettel durch ein Programm. Ein Reparaturauftrag wird bei der Fahrzeugannahme mit dem Kennzeichen und einer kurzen Fehlerbeschreibung angelegt und hat dann den Status „angenommen“. Sobald ein Mechaniker mit der Arbeit beginnt, wechselt der Status zu „in Arbeit“. Nur in diesem Status können Arbeitsstunden (Kommazahlen, z. B. 1,5) und Materialkosten in Euro gebucht werden; Buchungen mit Werten kleiner oder gleich 0 werden ignoriert. Ist die Reparatur beendet, wird der Auftrag abgeschlossen und erhält den Status „fertig“. Holt die Kundin das Fahrzeug ab, wechselt der Status zu „abgeholt“; das Programm meldet dabei zurück, ob die Abholung zulässig war.
Andere Statuswechsel als die beschriebenen sind nicht erlaubt und bleiben wirkungslos. Der Rechnungsbetrag ergibt sich aus den gebuchten Stunden multipliziert mit dem Stundensatz von 85,00 Euro zuzüglich der Materialkosten. Kennzeichen, Beschreibung, Status und Rechnungsbetrag müssen abgefragt werden können.
Reparaturauftrag a = new Reparaturauftrag("OS-KM 412", "Bremsen quietschen");
a.stundenBuchen(1.5);
a.beginnen();
a.stundenBuchen(2.0);
a.materialBuchen(120.0);
a.abschliessen();
a.stundenBuchen(0.5);
System.out.println(a.getStatus() + ": " + a.getRechnungsbetrag());
fertig: 417.5.- Erstellen Sie eine Klassenkarte der Klasse
Reparaturauftrag, die alle Anforderungen erfüllt. Verwenden Sie die Methodennamen aus Material 3. - Implementieren Sie die Klasse
Reparaturauftragvollständig in Java. - Weisen Sie anhand Ihrer Implementierung nach, dass die Erwartung des Auszubildenden in Material 3 falsch ist, und geben Sie die tatsächliche Ausgabe an.
- Der Werkstattleiter schlägt vor, den Status statt als Zeichenkette als Ganzzahl (0 = angenommen, 1 = in Arbeit, 2 = fertig, 3 = abgeholt) zu speichern. Ein Mechaniker möchte stattdessen vier Wahrheitswerte
angenommen,inArbeit,fertig,abgeholt. Nehmen Sie zu beiden Vorschlägen im Vergleich mit Ihrer Lösung Stellung.
Hinweise
Hinweis zu Aufgabe a)
Hinweis zu Aufgabe b)
equals, nicht mit ==. Für „nur in Arbeit und positiv“ verknüpfst du zwei Bedingungen mit &&.„Implementieren“ heißt: lauffähiger Java-Quelltext – Attribute, Konstruktor und alle Methoden.Hinweis zu Aufgabe c)
Hinweis zu Aufgabe d)
Erwartungshorizont
Erwartungshorizont zu Aufgabe a)
- - kennzeichen: Zeichenkette
- - beschreibung: Zeichenkette
- - status: Zeichenkette
- - stunden: Fließkommazahl
- - material: Fließkommazahl
- - stundensatz: Fließkommazahl
- c Reparaturauftrag(kennzeichen: Zeichenkette, beschreibung: Zeichenkette)
- + beginnen()
- + stundenBuchen(h: Fließkommazahl)
- + materialBuchen(betrag: Fließkommazahl)
- + abschliessen()
- + abholen(): Wahrheitswert
- + getKennzeichen(): Zeichenkette
- + getBeschreibung(): Zeichenkette
- + getStatus(): Zeichenkette
- + getRechnungsbetrag(): Fließkommazahl
Der Rechnungsbetrag wird berechnet, nicht gespeichert. Der Stundensatz kann auch als fester Wert in der Methode stehen; ein Attribut ist aber übersichtlicher. abholen() liefert laut Text eine Rückmeldung und hat daher den Rückgabetyp Wahrheitswert.
Erwartungshorizont zu Aufgabe b)
public class Reparaturauftrag {
private String kennzeichen;
private String beschreibung;
private String status;
private double stunden;
private double material;
private double stundensatz;
public Reparaturauftrag(String kennzeichen, String beschreibung) {
this.kennzeichen = kennzeichen;
this.beschreibung = beschreibung;
status = "angenommen";
stunden = 0.0;
material = 0.0;
stundensatz = 85.0;
}
public void beginnen() {
if (status.equals("angenommen")) {
status = "in Arbeit";
}
}
public void stundenBuchen(double h) {
if (status.equals("in Arbeit") && h > 0) {
stunden = stunden + h;
}
}
public void materialBuchen(double betrag) {
if (status.equals("in Arbeit") && betrag > 0) {
material = material + betrag;
}
}
public void abschliessen() {
if (status.equals("in Arbeit")) {
status = "fertig";
}
}
public boolean abholen() {
if (status.equals("fertig")) {
status = "abgeholt";
return true;
}
return false;
}
public String getKennzeichen() {
return kennzeichen;
}
public String getBeschreibung() {
return beschreibung;
}
public String getStatus() {
return status;
}
public double getRechnungsbetrag() {
return stunden * stundensatz + material;
}
}
Wesentlich: private Attribute, Initialisierung im Konstruktor mit this, Statusprüfung mit equals in allen Übergängen, Prüfung auf positive Werte, return in allen Anfragen.
Erwartungshorizont zu Aufgabe c)
Ablauf: stundenBuchen(1.5) bei Status „angenommen“ → ignoriert. beginnen() → „in Arbeit“. 2,0 Stunden und 120,00 Euro Material werden gebucht. abschliessen() → „fertig“. stundenBuchen(0.5) bei „fertig“ → ignoriert.
Rechnungsbetrag: 2,0 · 85,00 + 120,00 = 290,00 Euro. Tatsächliche Ausgabe: fertig: 290.0.
Der Auszubildende hat mit 3,5 Stunden gerechnet (3,5 · 85,00 + 120,00 = 417,50): Er hat die Buchung vor beginnen() mitgezählt und damit übersehen, dass Buchungen nur im Status „in Arbeit“ wirken. Die Erwartung ist damit widerlegt.
Erwartungshorizont zu Aufgabe d)
Zeichenkette (eigene Lösung): gut lesbar, die Ausgabe ist direkt verständlich; aber anfällig für Tippfehler („in arbeit“), die der Compiler nicht erkennt, und Vergleiche müssen mit equals erfolgen.
Ganzzahl: Vergleiche mit == sind einfach, die Reihenfolge ist als Zahl ausdrückbar (z. B. „status < 2“). Der Quelltext wird aber schwer lesbar („Was bedeutet 2?“), und ungültige Werte wie 7 sind möglich. Durch die Kapselung (Status privat, Änderung nur über Methoden) bleibt die Umstellung auf die Klasse beschränkt; getStatus() kann weiterhin eine Zeichenkette liefern.
Vier Wahrheitswerte: ungeeignet, weil es 16 Kombinationen, aber nur 4 gültige Zustände gibt; bei jedem Wechsel müssen zwei Attribute konsistent geändert werden. Ein weiterer Status („wartet auf Teile“) erfordert ein neues Attribut und Änderungen in allen Methoden.
Mögliche Stellungnahme: Zeichenkette und Ganzzahl sind beide vertretbar, solange der Status gekapselt bleibt und nur die Methoden der Klasse ihn ändern; aus Gründen der Lesbarkeit ist die Zeichenkette vorzuziehen. Der Vorschlag mit vier Wahrheitswerten ist abzulehnen.
