Aufgabenblock — AFB I
Zehn Standardaufgaben zum Reproduzieren, bunt gemischt aus allen elf Unterkapiteln: Programme Zeile für Zeile verfolgen, Typen und Werte angeben, Klassenkarten zeichnen, Arrays und Listen auslesen. Das sind die sicheren Punkte in jeder Arbeit — eine der zehn Aufgaben ist allerdings eine Trickaufgabe.
Das Programm einer Kinokasse liegt in der Datei Kinokasse.java:
public class Kinokasse {
public static void main(String[] args) {
System.out.print("Saal ");
System.out.println(3);
System.out.print("Reihe ");
System.out.print(7);
System.out.println(", Platz 12");
System.out.println("Viel Spaß im Film!");
}
}
Nenne den Befehl zum Übersetzen, den Namen der Datei, die dabei entsteht, und den Befehl zum Starten. Wie viele Zeilen erscheinen in der Konsole?
javac übersetzt die ganze Datei vorab in Bytecode. Die Bytecode-Datei trägt den Klassennamen und die Endung .class.println beendet die Zeile. print schreibt in derselben Zeile weiter.Vollständige Lösung
Übersetzen: javac Kinokasse.java → es entsteht Kinokasse.class (Bytecode). Starten: java Kinokasse — ohne Endung, die JVM führt den Bytecode aus.
Ausgabe (3 Zeilen):
Saal 3 Reihe 7, Platz 12 Viel Spaß im Film!
Wer 5 Zeilen zählt, hat jedes print als eigene Zeile gewertet.
Fünf Freunde teilen 47 Sammelkarten gleichmäßig auf. Außerdem will das Programm wissen, was „die Hälfte aller Karten“ ist.
int karten = 47; int spieler = 5; int proKopf = karten / spieler; int rest = karten % spieler; double haelfte = karten / 2;
Berechne die Werte der drei Variablen, so wie Java sie speichert.
/ zwischen zwei int-Werten ist eine Ganzzahldivision: Nachkommastellen werden abgeschnitten. % liefert den Rest.karten und 2? Das Umwandeln in double passiert erst danach.Vollständige Lösung
47 / 5 → 9 (9 · 5 = 45), 47 % 5 → 2 Karten bleiben übrig.
Die Falle: karten / 2 ist int / int = 23. Erst dieses Ergebnis wird automatisch zu double erweitert: haelfte = 23.0, nicht 23.5. Richtig wäre karten / 2.0 oder (double) karten / 2.
Ein Modellraketen-Club zählt beim Start in Dreierschritten herunter:
int durchlaeufe = 0;
for (int i = 20; i > 0; i -= 3) {
if (i % 2 == 0) {
System.out.println(i + " gerade");
} else {
System.out.println(i);
}
durchlaeufe++;
}
System.out.println("Start!");
Wende die Schleife Schritt für Schritt an: Wie oft läuft sie, welche Zahl steht in der letzten Zahlenzeile, und wie viele Zeilen enden mit „gerade“?
i untereinander: Start 20, dann jeweils 3 weniger, solange i > 0 gilt.i % 2 == 0 ist genau dann wahr, wenn i ohne Rest durch 2 teilbar ist.Vollständige Lösung
i durchläuft 20, 17, 14, 11, 8, 5, 2 → 7 Durchläufe. Danach wäre i = −1, die Bedingung i > 0 ist falsch. Letzte Zahl: 2.
Gerade sind 20, 14, 8 und 2 → 4 Zeilen mit „gerade“. In Python hieße der Kopf for i in range(20, 0, -3):.
Beim Sportfest bekommt man ab 2 m Weite für je 10 cm einen Punkt:
public static int punkte(int weiteCm) {
if (weiteCm < 200) {
return 0;
}
return (weiteCm - 200) / 10;
}
In main steht: int summe = punkte(356) + punkte(190) + punkte(410);
Gib den Rückgabetyp, den Parameter mit Typ und den Wert von summe an.
156 / 10 ist in Java 15 — der Rest fällt weg. Und return beendet die Methode sofort.Vollständige Lösung
Rückgabetyp int, Parameter int weiteCm.
punkte(356) → 156 / 10 = 15; punkte(190) → 190 < 200, also 0; punkte(410) → 210 / 10 = 21. summe = 15 + 0 + 21 = 36.
Ein Outdoorladen verwaltet seine Zelte mit dieser Klasse:
public class Zelt {
private String marke;
private int personen;
private boolean aufgebaut;
private double gewichtKg;
public Zelt(String marke, int personen) {
this.marke = marke;
this.personen = personen;
}
public Zelt(String marke) {
this.marke = marke;
personen = 2;
gewichtKg = 1.8;
}
}
Erzeugt werden Zelt z1 = new Zelt("Nordwind", 4); und Zelt z2 = new Zelt("Kiesel");
Entnimm dem Quelltext die Attributwerte der beiden Objekte direkt nach dem Erzeugen.
0, 0.0, false bzw. null.Vollständige Lösung
- marke = "Nordwind"
- personen = 4
- aufgebaut = false
- gewichtKg = 0.0
- marke = "Kiesel"
- personen = 2
- aufgebaut = false
- gewichtKg = 1.8
z1 nutzt den Konstruktor mit zwei Parametern; gewichtKg wird dort nicht gesetzt und bleibt beim Standardwert 0.0. z2 nutzt den überladenen Konstruktor mit einem Parameter: personen = 2. aufgebaut setzt keiner der beiden — also jeweils false.
- marke = ?
- personen = ?
- aufgebaut = ?
- gewichtKg = ?
Eine App erinnert ans Trinken. Sie enthält diese Klasse:
public class Trinkflasche {
private String farbe;
private int kapazitaetMl;
private int fuellungMl;
private boolean isoliert;
public Trinkflasche(String farbe, int kapazitaetMl) {
this.farbe = farbe;
this.kapazitaetMl = kapazitaetMl;
fuellungMl = kapazitaetMl;
isoliert = false;
}
public void trinken(int ml) {
int rest = fuellungMl - ml;
if (rest >= 0) {
fuellungMl = rest;
}
}
public int getFuellungMl() {
return fuellungMl;
}
public boolean istLeer() {
return fuellungMl == 0;
}
public void setIsoliert(boolean isoliert) {
this.isoliert = isoliert;
}
}
Zeichne die zugehörige Klassenkarte in der Notation aus dem Unterricht.
private wird -, public wird +, der Konstruktor bekommt ein c.rest ist eine lokale Variable in trinken — kein Attribut. void lässt du weg, Typen übersetzt du: int → Ganzzahl, boolean → Wahrheitswert, String → Zeichenkette.Vollständige Lösung
- - farbe: Zeichenkette
- - kapazitaetMl: Ganzzahl
- - fuellungMl: Ganzzahl
- - isoliert: Wahrheitswert
- c Trinkflasche(farbe: Zeichenkette, kapazitaetMl: Ganzzahl)
- + trinken(ml: Ganzzahl)
- + getFuellungMl(): Ganzzahl
- + istLeer(): Wahrheitswert
- + setIsoliert(isoliert: Wahrheitswert)
Vier Attribute, ein Konstruktor, vier Methoden. Die Anweisungen in den Rümpfen (return fuellungMl;, int rest = …) gehören nicht ins Diagramm.
Der Ladestand eines E-Bike-Akkus darf nur 0 bis 100 % betragen. Ungültige Werte weist der Setter ab.
public class Akku {
private int ladung;
public Akku() {
ladung = 50;
}
public int getLadung() {
return ladung;
}
public void setLadung(int ladung) {
if (ladung >= 0 && ladung <= 100) {
this.ladung = ladung;
}
}
public void laden(int prozent) {
setLadung(ladung + prozent);
}
}
Akku a = new Akku(); a.setLadung(120); a.setLadung(35); a.laden(40); a.laden(40); a.setLadung(-5);
Bestimme den Wert von ladung nach allen Aufrufen und die Anzahl der abgewiesenen Aufrufe.
ladung danach. Der Startwert kommt aus dem Konstruktor.laden(40) ruft intern setLadung(ladung + 40) auf — auch dieser Wert geht also durch die Prüfung. Abgewiesen heißt: Der alte Wert bleibt, er wird nicht auf 100 gekappt.Vollständige Lösung
50 → setLadung(120) abgewiesen: 50 → setLadung(35): 35 → laden(40): 75 → laden(40) will 115, abgewiesen: 75 → setLadung(-5) abgewiesen: 75 %.
3 Aufrufe wurden abgewiesen. Ein direkter Zugriff a.ladung = 90; würde gar nicht übersetzt: ladung has private access in Akku.
- - ladung: Ganzzahl
- c Akku()
- + getLadung(): Ganzzahl
- + setLadung(ladung: Ganzzahl)
- + laden(prozent: Ganzzahl)
Eine Handball-AG speichert die Tore der ersten sechs Spiele in einem Array. Die Werte entstehen so:
int[] tore = new int[6];
tore[0] = 2;
for (int i = 1; i < tore.length; i++) {
tore[i] = tore[i - 1] + i;
}
tore[4] = tore[4] % 3;
Trage die Werte der Fächer 3, 4 und 5 nach dem Programmende in die Fächerreihe ein.
tore[1] = tore[0] + 1, tore[2] = tore[1] + 2 usw.tore[5] wurde also mit dem alten Wert von tore[4] berechnet.Vollständige Lösung
Schleife: 2 → 2 + 1 = 3 → 3 + 2 = 5 → 5 + 3 = 8 → 8 + 4 = 12 → 12 + 5 = 17. Danach tore[4] = 12 % 3 = 0. tore[5] bleibt 17.
| 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
| 2 | 3 | 5 | 8 | 0 | 17 |
tore.length ist 6, der größte Index also 5. Ein Zugriff auf tore[6] würde eine ArrayIndexOutOfBoundsException auslösen.
| 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
| 2 | 3 | 5 | ? | ? | ? |
tore mit Index darüberDas Fundbüro der Schule führt eine Liste. Die Methode finde sucht von vorne und zählt ihre Vergleiche mit equals.
ArrayList<String> fund = new ArrayList<>();
fund.add("Schal");
fund.add("Brotdose");
fund.add("Turnbeutel");
fund.add("Regenschirm");
fund.remove(1);
fund.set(2, "Handschuh");
fund.add("Fahrradhelm");
Stelle den Inhalt der Liste nach jeder Anweisung in einer Tabelle dar. Trage unten fund.size() am Ende ein und wie viele Vergleiche die Suche nach „Handschuh“ bzw. nach „Brotdose“ braucht.
remove(1) entfernt das Element an Index 1, die folgenden rücken nach vorne. set(2, …) überschreibt, ohne die Größe zu ändern.Vollständige Lösung
4 × add: [Schal, Brotdose, Turnbeutel, Regenschirm]
remove(1): [Schal, Turnbeutel, Regenschirm]
set(2, "Handschuh"): [Schal, Turnbeutel, Handschuh]
add("Fahrradhelm"): [Schal, Turnbeutel, Handschuh, Fahrradhelm] → size() = 4
„Handschuh“ steht an Index 2 → Vergleiche mit Schal, Turnbeutel, Handschuh = 3. „Brotdose“ wurde entfernt → alle 4 Einträge werden verglichen, die Suche meldet „nicht gefunden“.
Eine Musikschule verwaltet ihre Instrumente:
public class Instrument {
private String name;
public Instrument(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String klang() {
return "...";
}
}
public class Trommel extends Instrument {
private int durchmesserCm;
public Trommel(String name, int durchmesserCm) {
super(name);
this.durchmesserCm = durchmesserCm;
}
public int getDurchmesserCm() {
return durchmesserCm;
}
@Override
public String klang() {
return "Bumm";
}
}
Ordne jede Methode, die ein Trommel-Objekt aufrufen kann, einer Gruppe zu: geerbt, neu oder überschrieben. Was liefert new Trommel("Cajon", 30).klang()?
extends heißt: Alles Öffentliche aus Instrument hat die Trommel auch. Steht eine Methode mit gleicher Signatur in beiden Klassen, ist sie überschrieben.Trommel.Vollständige Lösung
geerbt: getName() · neu: getDurchmesserCm() · überschrieben: klang() (mit @Override).
new Trommel("Cajon", 30).klang() liefert "Bumm". Das Attribut name besitzt die Trommel zwar auch, sie darf es aber nicht direkt lesen: t.name ergibt name has private access in Instrument — deshalb super(name) im Konstruktor und getName() zum Lesen.
