Abstrakte Klassen dienen dazu, zwischen konkreten Klassen, die eine gewisse Ähnlichkeit besitzen, durch die Einführung einer gemeinsamen Oberklasse
eine Beziehung herzustellen. Damit können die Konzepte der → Polymorphie und des → Dynamischen Bindens
besser genutzt werden.
Abstrakte Klassen sind bewusst unvollständige Klassen. Sie enthalten Methoden, die zwar definiert sind, aber nicht mit Inhalt gefüllt (implementiert) werden.
abstract class LaufHamster extends Hamster { LaufHamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } abstract void laufe(); }
Im Unterschied zu "normalen" Klassen wird die Definition einer abstrakten Klasse mit dem Schlüsselwort abstract eingeleitet.
Die Klasse enthält eine → Konstruktor, der auf die Klasse Hamster zugreift und die Methode laufe().
Der Methode wird das Schlüsselwort abtract vorangestellt, sie wird mit einem Semikolon abgeschlossen.
Von Abstrakten Klassen können keine Objekte erzeugt werden. Die Anweisung ...
LaufHamster paul = new LaufHamster(0, 0, Hamster.OST, 0);
... wird mit der Fehlermeldung LaufHamster is abtract: cannot be instantiated versehen.
Abstrakten Klasse machen dann erst Sinn, wenn von ihnen weitere Klassen abgeleitet werden, die die abstrakten Methoden überschreiben und mit Inhalt füllen.
class RennHamster extends LaufHamster { RennHamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } // überschriebene Methode laufe() void laufe() { while (this.vornFrei()) this.vor(); } }
class DummerHamster extends LaufHamster { DummerHamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, Hamster.OST, 0); } // überschriebene Methode laufe() void laufe() { if (this.vornFrei()) this.vor(); if (this.vornFrei()) this.vor(); if (this.vornFrei()) this.vor(); } }
Die Klassen RennHamster und DummerHamster sind konkrete Klassen, sie werden beide von der Abstrakten Klasse LaufHamster abgeleitet. Sie erben alle Methoden der Klasse Hamster
und alle Methoden der Klasse LaufHamster.
Sie überschreiben alle Methoden des LaufHamsters.
Nach den Regeln des → Dynamischen Bindens wird zwar die namentlich gleiche Methode laufe() ausgeführt, aber mit verschiedenen Anweisungen gefüllt.
Konkret heißt das:
void main() { RennHamster paul = new RennHamster(0, 0, Hamster.OST, 0); DummerHamster willi = new DummerHamster(1, 0, Hamster.OST, 0); // dynamisch gebundene Methode laufe() paul.laufe(); willi.laufe(); }
Siehe auch:
→ InterfacesMit Hilfe von Arrays können Daten eines einheitlichen Typs im Speicher abgelegt und jederzeit wieder hervor geholt werden. Jeder Position eines Datenfeldes wird ein Wert zugeordnet. Diese Werte können Variable vom Typ → int, → String, → char oder → Hamster sein.
Ein Array kann man sich wie einen Schrank mit Schubladen vorstellen. In jeder Schublade kann ein Wert abgelegt werden. Dieser Wert kann jederzeit gelesen werden:
Inhalt von Schublade Nummer 3? → Schublade[3]
Inhalt von Schublade Nummer 2? → Schublade[2]
Arrays sind immer statisch, sie haben eine festgelegte Anzahl von Elementen. Im Gegensatz zur dynamischen → ArrayList() kann dem Datenfeld
zur Laufzeit des Programms kein weiteres Element hinzugefügt werden.
Ein Überschreiten der Anzahl der Elemente zur Laufzeit des Programms führt zu einer → Fehlermeldung.
Den Elementen wird entweder bei der Initialisierung ein
Wert zugewiesen oder sie werden zur Laufzeit mit Werten gefüllt.
int[] zahlen = {3, 5, 2, 7, 9, 10};
// leere Liste mit 10 Elementen erzeugen int zahlen[] = new int [10]; // Liste mit Werten füllen for (int zaehler = 0; zaehler < 10; zaehler = zaehler + 1) { int maxZahl = 9; // → Zufallszahl ermitteln zahlen[zaehler]= (int) (Math.random() * maxZahl + 1); }→ int-Array
void main() { int[] zahlen = {3, 5, 2, 7, 9, 10}; }
Der Zugriff auf den Wert einer Position erfolgt mit:
int zahl1 = zahlen[0]; int zahl2 = zahlen[1]; int zahl3 = zahlen[2];
void main() { Hamster paul = new Hamster(); paul.init(0, 0, Hamster.OST, 0); // Array definieren int[] zahlen = {3, 5, 2, 7, 9, 10}; // Ausgabestring initialisieren String arrayZahlenZeigen ="Elemente des Arrays: "; // for-Schleife zur Zusammensetzung des Strings arrayZahlenZeigen for (int zaehler = 0; zaehler < 6;zaehler = zaehler + 1) { arrayZahlenZeigen = arrayZahlenZeigen + " " + zahlen[zaehler]; } paul.schreib(arrayZahlenZeigen); }
void main() { Hamster paul = new Hamster(); paul.init(0, 0, Hamster.OST, 0); // Array definieren String[] buchstaben = {"A","B","C","D","E","F"}; // Ausgabestring initialisieren String arrayBuchstabenZeigen ="Elemente des Arrays: "; // for-Schleife zur Zusammensetzung des Strings arrayBuchstabenZeigen for (int zaehler = 0; zaehler < 6; zaehler = zaehler + 1) { arrayBuchstabenZeigen = arrayBuchstabenZeigen + " " + buchstaben[zaehler]; } paul.schreib(arrayBuchstabenZeigen); }
void main() { Hamster paul = new Hamster(); paul.init(0, 0, Hamster.OST, 0); // leere Liste mit 10 Elementen erzeugen int zahlen[] = new int [10]; // Ausgabestring initialisieren String arrayZufallszahlenZeigen ="Zufallszahlen: "; // Liste mit Werten füllen for (int zaehler = 0; zaehler < 10; zaehler = zaehler + 1) { int maxZahl = 9; // → Zufallszahl ermitteln zahlen[zaehler]= (int) (Math.random() * maxZahl + 1); arrayZufallszahlenZeigen = arrayZufallszahlenZeigen +" " + zahlen[zaehler]; } paul.schreib(arrayZufallszahlenZeigen); }
void main() { char[] alphabet = new char[26]; String ausgabeBuchstaben = ""; // Start mit A char buchstabe = 65; for(int zaehler = 0; zaehler < alphabet.length; zaehler ++) { alphabet[zaehler] = buchstabe; ausgabeBuchstaben = ausgabeBuchstaben + alphabet[zaehler]; buchstabe ++; } schreib(ausgabeBuchstaben); }
Siehe auch:
→ char → ArrayListAuch die Hamster selbst können in einem Array abgelegt werden.
void main() { // Anzahl der Hamster int anzahlHamster = 4; // Array initialisieren Hamster[] familie = new Hamster[anzahlHamster];
Das Array familie umfasst 4 Hamster, die mit ...
for (int zaehler = 0; zaehler < anzahlHamster; zaehler = zaehler + 1) { familie[zaehler] = new Hamster(zaehler, 0, Hamster.OST, 0); } }
... initialisiert werden.
Ein Array kann auch an eine → Prozedur übergeben werden:
void main() { int zahl = 0; int zaehler = 0; int maxZahl = 20; // Array definieren int zahlen[] = new int [6]; // Array füllen while (zaehler < zahlen.length) { zahlen[zaehler] = zufallsZahl(maxZahl); zaehler ++; } // Zahlen ausgeben ausgabe(zahlen); } void ausgabe (int zahlen[]) { String text = ""; for (int zaehler = 0; zaehler < zahlen.length; zaehler ++) { text = text + " " + String.valueOf(zahlen[zaehler]); } schreib(text); } // Zufallszahl bestimmen int zufallsZahl(int maxZahl) { return (int) (Math.random() * maxZahl + 1); }
Ein Array kann auch an eine → Methode innerhalb einer → Klasse übergeben werden:
class ausgabeZahlen { String ausgabe (int zahlen[]) { String text = ""; for (int zaehler = 0; zaehler < zahlen.length; zaehler ++) { text = text + " " + String.valueOf(zahlen[zaehler]); } return text; } int zufallsZahl(int maxZahl) { return (int) (Math.random() * maxZahl + 1); } }
void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); int maxZahl = 20; // Array definieren int zahlen[] = new int[6]; int zaehler = 0; // neues Objekt der Klasse ausgabeZahlen erzeugen ausgabeZahlen zahlenZeigen = new ausgabeZahlen(); while (zaehler < zahlen.length) { // Zufallszahl ins Array schreiben zahlen[zaehler] = zahlenZeigen.zufallsZahl(maxZahl); zaehler ++; } // Methode zahlenZeigen der Klasse ausgabeZahlen aufrufen String text = zahlenZeigen.ausgabe(zahlen); paul.schreib(text); }
Siehe auch:
→ ArrayListGrundlagen:
→ Java-Klassen, → import,
→ ArrayList
ArrayList<>().toString() wandelt eine → ArrayList in einen → String um.
import java.util.ArrayList; import java.util.Random; void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // ArrayList mit int erstellen ArrayList<Integer> zahlen = new ArrayList<Integer>(); // neues Objekt der Klasse Random erstellen Random zufall = new Random(); int maxZahl = 10; // Liste mit Zufallszahlen füllen for (int zaehler = 0; zaehler < maxZahl; zaehler ++) { zahlen.add(zufall.nextInt(maxZahl)); } // ArrayList in String umwandeln String alleZahlen = new ArrayList<Integer>(zahlen).toString(); paul.schreib("Liste: " + alleZahlen); }
Zusätzlich können mit → replace() oder mit → replaceAll() die eckigen Klammern und die Kommata entfernt werden.
import java.util.ArrayList; import java.util.Random; void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // ArrayList mit int erstellen ArrayList<Integer> zahlen = new ArrayList<Integer>(); // neues Objekt der Klasse Random erstellen Random zufall = new Random(); int maxZahl = 10; // Liste mit Zufallszahlen füllen for (int zaehler = 0; zaehler < maxZahl; zaehler ++) { zahlen.add(zufall.nextInt(maxZahl)); } // ArrayList in String umwandeln String alleZahlen = new ArrayList(zahlen).toString(); paul.schreib("Liste: " + alleZahlen); // Lösung mit replace() alleZahlen = alleZahlen.replace(","," "); alleZahlen = alleZahlen.replace("["," "); alleZahlen = alleZahlen.replace("]"," "); // Lösung mit replaceAll() alleZahlen = alleZahlen.replaceAll("[\\[\\],]"," "); paul.schreib("Liste: " + alleZahlen); }
Grundlagen:
→ Java-Klassen, → import
→ Array
Arrays.toString() wandelt ein → Array in eine String um.
import java.util.Arrays; void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // int-Array int[] zahlen = new int[]{ 4, 6, 2, 7, 5, 8, 9, 3, 1 }; // String-Array String[] namen = new String[] {"Karin", "Gerda", "Karl", "Willi", "Paul"}; paul.schreib("Zahlen: " + Arrays.toString(zahlen)); paul.schreib("Namen: " + Arrays.toString(namen)); }
Grundlagen:
→ Java-Klassen, → import
→ Arrays haben den Nachteil, dass sie statisch sind: Du musst bei der Initialisierung festlegen, wie viele Elemente das Array haben soll.
Das Programm erfragt Zahlen und schreibt sie in ein Array, das drei Elemente enthalten soll.
Der Versuch ein viertes
Element in das Array zu schreiben führt zu einer Fehlermeldung.
Der Compiler kann den Fehler nicht entdecken, da er erst zur Laufzeit auftritt.
void main() { String zahlen [] = new String [3]; Hamster paul = new Hamster(0, 0, Hamster.OST, 0); int zaehler = 0; String eingabeZahl; do { eingabeZahl = paul.liesZeichenkette("Gib einen Zahl ein! (0 = Programmabbruch)"); zaehler ++; zahlen[zaehler] = eingabeZahl; } while (!eingabeZahl.equals("0")); }
ArrayList löst dieses Problem und bietet zudem eine Vielzahl von Methoden, eine Liste zu verändern. Elemente zu löschen oder zu suchen.
Voraussetzung ist der Import von → Java-Klassen
ArrayList<String> wochentage = new ArrayList<String>(); String alleTage = new ArrayList<String>(wochentage).toString();
import java.util.ArrayList; import java.util.Random; void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); ArrayList<Integer> zahlen = new ArrayList<Integer>(); Random zufall = new Random(); int maxZahl = 20; // Liste füllen for (int zaehler = 0; zaehler <= maxZahl; zaehler ++) { zahlen.add(zaehler); } String alleZahlen = new ArrayList<Integer>(zahlen).toString(); paul.schreib(alleZahlen); // Zahl entfernen int entfernen = paul.liesZahl("Welche Zahl aus der Liste entfernen?"); zahlen.remove(entfernen); alleZahlen = new ArrayList<Integer>(zahlen).toString(); paul.schreib(alleZahlen); // Zahl anhängen int hinzufuegen = paul.liesZahl("Eine Zahl an die Liste anhaengen:"); zahlen.add(hinzufuegen); alleZahlen = new ArrayList<Integer>(zahlen).toString(); paul.schreib(alleZahlen); // Zahl ersetzen int neueZahl = paul.liesZahl("Zahl in der Liste durch eine andere ersetzen:"); int position = paul.liesZahl("An welcher Position?"); zahlen.set(position, neueZahl); alleZahlen = new ArrayList<Integer>(zahlen).toString(); paul.schreib(alleZahlen); // Zahl einfügen neueZahl = paul.liesZahl("Zahl in die Liste einfuegen:"); position = paul.liesZahl("An welcher Position?"); zahlen.add(position, neueZahl); alleZahlen = new ArrayList<Integer>(zahlen).toString(); paul.schreib(alleZahlen); // Zahl zeigen position = paul.liesZahl("Zahl an einer Position zeigen?"); paul.schreib(" "+zahlen.get(position)); // Zahl suchen int sucheZahl = paul.liesZahl("Welche Zahl suchen?"); boolean gefunden = zahlen.contains(sucheZahl); if (gefunden) paul.schreib("Die Zahl "+ sucheZahl + " wurde gefunden"); int index = zahlen.indexOf(sucheZahl); if (index > 0) paul.schreib("Die Zahl " + sucheZahl + " wurde an Position " + index + " gefunden!"); // Liste leeren zahlen.clear(); boolean leereListe = zahlen.isEmpty(); if (leereListe) paul.schreib("Die Liste ist leer!"); }
import java.util.ArrayList; import java.util.Random; void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // ArrayList mit Strings // Liste füllen ArrayList<String> wochentage = new ArrayList<String>(); String tag; do { tag = paul.liesZeichenkette("Welches Wochentag hinzufuegen? (Ende mit e)"); if (!tag.equals("e")) wochentage.add(tag); } while (!tag.equals("e")); String alleTage = new ArrayList<String>(wochentage).toString(); paul.schreib(alleTage); // Wochentag ersetzen String neuerTag = paul.liesZeichenkette("Wochentag in der Liste durch einen anderen ersetzen:"); int position = paul.liesZahl("An welcher Position?"); wochentage.set(position, neuerTag); alleTage = new ArrayList<String>(wochentage).toString(); paul.schreib(alleTage); // Wochentag anhängen String hinzufuegenTag = paul.liesZeichenkette("Einen Wochentag an die Liste anhaengen!"); wochentage.add(hinzufuegenTag); alleTage = new ArrayList<String>(wochentage).toString(); paul.schreib(alleTage); // Wochentag einfügen neuerTag = paul.liesZeichenkette("Wochentag in die Liste einfuegen:"); position = paul.liesZahl("An welcher Position?"); wochentage.add(position, neuerTag); alleTage = new ArrayList<String>(wochentage).toString(); paul.schreib(alleTage); // Wochentag zeigen position = paul.liesZahl("Zahl an einer Position zeigen?"); paul.schreib(" " + wochentage.get(position)); // Wochentag suchen String sucheTag = paul.liesZeichenkette("Welchen Wochentag suchen?"); boolean gefunden = wochentage.contains(sucheTag); if (gefunden) paul.schreib("Der Wochentag "+ sucheTag + " wurde gefunden"); int index = wochentage.indexOf(sucheTag); if (index > 0) paul.schreib("Die Zahl " + sucheTag + " wurde an Position " + index + " gefunden!"); // Liste leeren wochentage.clear(); boolean leereListe = wochentage.isEmpty(); if (leereListe) paul.schreib("Die Liste ist leer!"); }
import javax.swing.JFrame; import javax.swing.JTextArea; import java.awt.Font; // globale Variable JTextArea infoTasten; void main() { JFrame fenster = new JFrame("ASCII"); String asciiTasten = "ASCII-Tabelle\n\n"; Font font = new Font("Verdana", Font.BOLD, 16); infoTasten = new JTextArea(); infoTasten.setFont(font); for(int zaehler = 65; zaehler < 123; zaehler++) { // Zeilenumbruch nach 5 Zeichen mit → modulo if((zaehler % 5) == 0) { asciiTasten = asciiTasten + "\n"; } asciiTasten = asciiTasten + (char)zaehler + " -> " + zaehler + "\t"; } infoTasten.setText(asciiTasten); infoTasten.setEditable(false); // Fensterposition fenster.setLocation(100, 200); fenster.add(infoTasten); // Fenstergröße festlegen fenster.setSize(500, 400); fenster.setVisible(true); }
Für die verschiedenen Sondertasten existieren ebenfalls Keycodes:
// Sonderzeichen ä, ö, ü, ß char[] sonderZeichen = {'\u00E4','\u00F6','\u00FC','\u00DF'}; for (int zaehler = 0; zaehler < sonderZeichen.length; zaehler ++) { if (infoTasten.getKeyChar() == sonderZeichen[zaehler]) { infoTasten.setText("sonderZeichen[zaehler]); } }
Attribute sind Variable (Eigenschaften), die innerhalb einer → Klasse definiert werden. Sie beschreiben die Eigenschaften eines jeden Objektes (z. B. eines Hamsters) dieser Klasse.
Jedes Objekt, das aus dieser Klasse abgeleitet wird, besitzt ein eigenes solches Attribut.
Mit dem Schlüsselwort static wird festgelegt, dass die Variable (das Attribut) für die gesamte Klasse gilt.
class AllesKoennerHamster extends Hamster { // Instanzenattribut - wird für jeden Hamster neu initialisiert int alleinGemachteSchritte; // Klassenattribut - gehört allen Hamstern gemeinsam static int gemeinsamGemachteSchritte = 0; AllesKoennerHamster(int reihe, int spalte, int blickrichtung, int koerner) { this.init(reihe, spalte, blickrichtung, koerner); this.alleinGemachteSchritte = 0; } }
Die Hamster sollen die gemeinsam gemachten Schritte zählen und sie als Mitteilung ausgeben.
class AllesKoennerHamster extends Hamster { int alleinGesammelteKoerner; static int gemeinsamGesammelteKoerner = 0; static int gemeinsamGemachteSchritte = 0; AllesKoennerHamster(int reihe, int spalte, int blickrichtung, int koerner) { this.init(reihe, spalte, blickrichtung, koerner); } void laufe() { while (this.vornFrei()) { this.vor(); this.gemeinsamGemachteSchritte = this.gemeinsamGemachteSchritte + 1; } } void mitteilung() { this.schreib("Wir sind zusammen " + gemeinsamGemachteSchritte + " Schritte gegangen"); } }
void main() { AllesKoennerHamster paul = new AllesKoennerHamster(0, 0, Hamster.OST, 0); AllesKoennerHamster karin = new AllesKoennerHamster(1, 0, Hamster.OST, 0); AllesKoennerHamster willi = new AllesKoennerHamster(2, 0, Hamster.OST, 0); AllesKoennerHamster heidi = new AllesKoennerHamster(3, 0, Hamster.OST, 0); paul.laufe(); karin.laufe(); willi.laufe(); heidi.laufe(); heidi.mitteilung(); }
→ for-Schleifen und → while-Schleifen
können unterbrochen werden, wenn eine besondere zusätzliche Bedingung eingetreten ist.
Im Beispiel wird die for-Schleife unterbrochen, wenn der Buchstabe "a" im String satz entdeckt wird.
void main() { String satz = ""; String neuerSatz = ""; String zeichen = ""; int zaehler = 0; satz = liesZeichenkette("Schreibe ein Wort oder einen Satz!"); for (zaehler = 0; zaehler < satz.length(); zaehler ++) { // Zeichen an der Position zaehler untersuchen if (satz.substring(zaehler, zaehler + 1).equals("a")) { schreib("Der Buchstabe a ist nicht erlaubt, das Wort wird an der Stelle abgeschnitten!"); break; } neuerSatz = neuerSatz + satz.substring(zaehler, zaehler + 1); } schreib(neuerSatz); }
import java.util.Calendar; class DatumAnzeigen { String datumErmitteln() { Calendar kalender = Calendar.getInstance(); String wochenTag = tagErmitteln(); String monat = monatErmitteln(); return wochenTag + ", " + kalender.get(Calendar.DAY_OF_MONTH) + ". " + monat + " " + kalender.get(Calendar.YEAR); } String tagErmitteln() { // neues Objekt der Klasse Calendar erzeugen // Methode getInstance() aufrufen Calendar kalender = Calendar.getInstance(); String wochenTag = ""; // Zählung der Wochentag beginnt mit 1 int aktuellerTag = kalender.get(Calendar.DAY_OF_WEEK); if (aktuellerTag == 1) wochenTag = "Sonntag"; if (aktuellerTag == 2) wochenTag = "Montag"; if (aktuellerTag == 3) wochenTag = "Dienstag"; if (aktuellerTag == 4) wochenTag = "Mittwoch"; if (aktuellerTag == 5) wochenTag = "Donnerstag"; if (aktuellerTag == 6) wochenTag = "Freitag"; if (aktuellerTag == 7) wochenTag = "Samstag"; return wochenTag; } String monatErmitteln() { Calendar kalender = Calendar.getInstance(); String monat = ""; // Zählung der Monate beginnt mit 0 int aktuellerMonat = kalender.get(Calendar.MONTH); if (aktuellerMonat == 0) monat = "Januar"; if (aktuellerMonat == 1) monat = "Februar"; if (aktuellerMonat == 2) monat = "Maerz"; if (aktuellerMonat == 3) monat = "April"; if (aktuellerMonat == 4) monat = "Mai"; if (aktuellerMonat == 5) monat = "Juni"; if (aktuellerMonat == 6) monat = "Juli"; if (aktuellerMonat == 7) monat = "August"; if (aktuellerMonat == 8) monat = "September"; if (aktuellerMonat == 9) monat = "Oktober"; if (aktuellerMonat == 10) monat = "November"; if (aktuellerMonat == 11) monat = "Dezember"; return monat; } }
void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); DatumAnzeigen datumLesen = new DatumAnzeigen(); String datum = datumLesen.datumErmitteln(); paul.schreib(datum); }
charAt() beschreibt das Zeichen eines Strings an einer bestimmten Position
void main() { String satz = "Java-Hamster"; for (int zaehler = 0; zaehler < satz.length(); zaehler ++) { schreib(" " + satz.charAt(zaehler)); } }
Grundlage:
→ import
Mit CLASSPATH kannst du dafür sorgen, dass ein → selbst erstelltes Paket für alle Programme verfügbar wird.
Wenn du deine Programme im Ordner Programme oder in einem Unterordner von Programme speicherst, musst du den CLASSPATH auf Programme setzen:
Leider wird dieser Eintrag nicht dauerhaft gespeichert. Um dies zu erreichen musst die die Datei hamster.properties öffnen und um einen Eintrag ergänzen:
CLASSPATH=Programme
contains prüft ob in einem vorhandenen String ein anderer String enthalten ist:
void main() { boolean ende = false; String textEingabe = ""; Hamster paul = new Hamster(0, 0, Hamster.OST, 0); /// solange ende false ist while (!ende) { textEingabe = textEingabe + paul.liesZeichenkette(" x = Ende") + "\n"; paul.schreib(textEingabe); /// prüfen ob e im String textEingabe enthalten ist if (textEingabe.contains("e")) ende = true; } }
Siehe auch:
→ compareTo(), → equals()Die continue-Anweisung ermöglicht es, den aktuellen Schleifendurchlauf zu beenden. Die Schleifenbedingung wird erneut ausgewertet.
Im Beispiel werden mit → modulo die Vielfachen der eingegebenen Zahl
ermittelt und ausgegeben.
void main() { String vielfache = ""; int zahl = liesZahl("Von welcher Zahl soll das Vielfache bestimmt werden?"); for (int zaehler = 1; zaehler <= 200; zaehler++) { // ist zaehler nicht ohne → Rest durch zahl teilbar // wird mit continue direkt der nächsten Schleifendurchlauf ausgeführt if (zaehler % zahl != 0) { continue; } // zaehler ist durch zahl ohne Rest teilbar // der Wert von zaehler wird dem String vielfache hinzugefügt vielfache = vielfache + String.valueOf(zaehler) + " "; } schreib ("Die Vielfachen von " + zahl +"\n" + vielfache); }
Siehe auch:
→ String, → for, → String.valueOf()Auch wenn das Programm einwandfrei kompiliert wurde ist manchmal die Ausführung des Programms nicht korrekt oder bricht mit einer Fehlermeldung ab (es kommt zu
einem Laufzeitfehler).
In diesem Fall ist es hilfreich, den Debugger einzuschalten und nach jedem Mausklick den Ablauf des Programms zu prüfen.
import java.text.DecimalFormat; import java.util.Random; class ZahlFormat { String zufallsZahl() { // Objekt der Klasse Random erzeugen Random zufall = new Random(); // Zufallszahl im Bereich bis 10000 ermitteln double kommaZahl = zufall.nextDouble() * 10000; /* neues Objekt der Klasse DecimalFormat erzeugen Zahl mit 2 Nachkommastellen formatieren # steht für eine Stelle, ist sie nicht belegt wird sie nicht angezeigt 0 repräsentiert eine Stelle, ist sie nicht belegt wird 0 angezeigt . trennt Vor- und Nachkommastellen , erzeugt Dezimalpunkte */ DecimalFormat zahlFormat = new DecimalFormat("#,###.##"); // Zahl formatieren und zurückgeben return zahlFormat.format(kommaZahl); } }
void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); ZahlFormat zahl = new ZahlFormat(); String zahlAnzeigen = zahl.zufallsZahl(); paul.schreib(zahlAnzeigen); }
import java.text.DecimalFormat; class ZahlFormatInt { String zahlFormat(int zahl) { /* neues Objekt der Klasse DecimalFormat erzeugen Zahl mit 2 Nachkommastellen formatieren # steht für eine Stelle, ist sie nicht belegt wird sie nicht angezeigt 0 repräsentiert eine Stelle, ist sie nicht belegt wird 0 angezeigt , erzeugt Dezimalpunkte */ DecimalFormat zahlFormat = new DecimalFormat("###,###,###,###"); // Zahl formatieren und als String zurückgeben return zahlFormat.format(zahl); } }
void main() { // berechnet 5 hoch 13 und gibt das Ergebnis mit Dezimalpunkten aus Hamster paul = new Hamster(0, 0, Hamster.OST, 0); int basis = 5; int exponent = 13; int ergebnis = (int) Math.pow(basis, exponent); // neues Objekt ZahlFormatInt erzeugen ZahlFormatInt zahl = new ZahlFormatInt(); String zahlAnzeigen = zahl.zahlFormat(ergebnis); paul.schreib(zahlAnzeigen); }
Als Schleife (Iteration) versteht man eine oder mehrere Anweisung(en), die solange wiederholt wird (werden), bis eine bestimmte Bedingung erfüllt ist.
Als Bedingung wird einer der → Sensoren verwendet:
do { nimm(); } while (kornDa());
Der Hamster nimmt solange Körner auf, bis auf seiner Position kein Korn mehr liegt.
Siehe auch:
→ while
Wenn in einer Klasse X eine Methode m definiert wird und in einer Unterklasse Y ebenfalls eine Methode m und die Anzahl und die Typen der Parameter in beiden Methoden gleich sind, dann überschreibt die Methode m der Klasse Y die gleichnamige Methode m der Klasse X.
Wenn nun einer Objektvariablen vom Typ X → polymorph ein Objekt der Klasse Y zugeordnet ist und die in beiden Klassen gleichnamige
Methode aufgerufen wird, dann wird tatsächlich die in der Klasse Y überschriebene Methode ausgeführt.
class DrehHamster extends Hamster { DrehHamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } void rechtsUm() { this.linksUm(); this.linksUm(); this.linksUm(); } }
class DummerHamster extends Hamster { DummerHamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } void rechtsUm() { this.linksUm(); this.linksUm(); this.linksUm(); this.linksUm(); this.linksUm(); this.linksUm(); } public void vor() { this.vor(); this.vor(); } }
void main() { DrehHamster paul = new DummerHamster(0, 0, Hamster.OST, 0); paul.rechtsUm(); paul.vor(); }
Dem DrehHamster paul wird polymorph ein Objekt der Klasse DummerHamster zugeordnet.
Wird nun die Methode rechtsUm() aufgerufen, wird die überschriebene Methode rechtsUm() der Klasse DummerHamster ausgeführt.
Soll eine Methode
der Klasse Hamster überschrieben werden muss der Methode das Schlüsselwort public vorangestellt werden.
Siehe auch:
→ Polymorphie, → Einschränkung des ProtokollsDateioperationen | Editierbefehle | Starten von Programmen | Fehlersuche |
---|---|---|---|
Der Debugger ist dann hilfreich, wenn das Programm mit einer Fehlermeldung bendet wird.
Schritt hinein führt dabei in einer → Prozedur jeden Schritt einzeln aus, Schritt über führt die Prozedur als Ganzes in einem Schritt aus.
endsWith() stellt das letzte Zeichen eines → Strings fest
void main() { String satz = "Java-Hamstern ist nicht schwer."; // Wenn das letzte Zeichen ein . ist, wird er durch ein ! ersetzt if (satz.endsWith(".")) { satz = satz.substring(0,satz.length() - 1) + "!"; } schreib(satz); }
Strings können nicht mit dem → Vergleichsoperator == verglichen werden, sondern mit der Methode equals().
void main() { String antwort = liesZeichenkette("Nach links drehen (j/n)?"); if (antwort.equals("j")) linksUm(); }
Siehe auch:
→ compareTo(), → contains(),Die Methode trim() entfernt die Leerstellen am Anfang und am Endes eines → Strings.
void main() { String stringMitLeerstellen = " String mit Leerstellen am Anfang und am Ende "; schreib (stringMitLeerstellen + stringMitLeerstellen.length() + " Zeichen"); String stringOhneLeerstellen = stringMitLeerstellen.trim(); schreib(stringOhneLeerstellen + " " + stringOhneLeerstellen.length() + " Zeichen"); }
Fehler lassen sich beim Programmieren nicht vermeiden. Bisher kennst du du drei verschiedene Typen von Fehlern:
Diese Laufzeitfehler können vermieden werden, indem eine Klasse VorsichtigerHamster definiert wird, die jeweils überprüft, ob die Ausführung des Befehls möglich ist
class VorsichtigerHamster extends Hamster { VorsichtigerHamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } void vorsichtigesVor() { if(this.vornFrei()) { this.vor(); } } }
void main() { VorsichtigerHamster paul = new VorsichtigerHamster(0, 0, Hamster.OST, 0); paul.vorsichtigesVor(); }
Der Nachteil dieses Programm ist aber, dass nicht festgestellt werden kann, ob der Hamster einen Schritt vorgegangen ist oder nicht.
An dieser Stelle können die Exceptions eingesetzt werden. Sie teilen dem Programm mit, dass eine bestimmte Ausnahmesituation (Exception)
oder ein bestimmter Fehler aufgetreten ist.
Exceptions sind Objekte einer vordefinierten Klasse Exception.
Mit Hilfe einer Fehlerklasse kann der Fehler nicht nur festgestellt werden, vielmehr kann der Hamster auch darauf reagieren.
Die einfachste Form einer Fehlerklasse besteht lediglich aus der Definition der Klasse:
class MauerIstDaFehler extends Exception { }
Die Oberklasse Exception kennt die Methoden:
class MauerIstDaFehler extends Exception { // Die Fehlermeldung wird an die Methode get.Message() der Oberklasse Exception übergeben MauerIstDaFehler() { super("Ich stehe vor einer Mauer!"); } String getFehlerMeldung() { return "Ich stehe vor einer Mauer!"; } }
In der Klasse VorsichtigerHamster wird mit Hilfe der throw-Anweisung angezeigt, dass der Fehler MauerIstDaFehler auftreten kann. Das "Werfen" von Fehler führt sofort zum Verlassen der Methode.
class VorsichtigerHamster extends Hamster { VorsichtigerHamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } void vorsichtigesVor() throws MauerIstDaFehler { if(this.vornFrei()) { this.vor(); } else { throw new MauerIstDaFehler(); } } }
Eine try catch-Anweisung übernimmt die Behandlung eines eventuell auftretenden Fehlers.
Der try-Block behandelt die Standardanweisungen. Tritt bei deren Ausführung ein Fehler auf, wird der Fehler "gefangen" und das
Programm mit dem catch-Block fortgesetzt.
void main() { VorsichtigerHamster paul = new VorsichtigerHamster(0, 0, Hamster.OST, 0); try { paul.vorsichtigesVor(); } catch (MauerIstDaFehler fehlerObjekt) { // Angabe der Fehlerklasse paul.schreib(fehlerObjekt.toString()); // selbst definierte Fehlermeldung anzeigen paul.schreib(fehlerObjekt.getMessage()); // Alternative: Aufruf der Methode getFehlerMeldung() paul.schreib(fehlerObjekt.getFehlerMeldung()); } }
Der try-Block versucht das Programm auszuführen, ohne sich um mögliche Fehler zu kümmern.
Tritt ein Fehler auf, wird die Methode VorsichtigesVor() verlassen und der Fehler im catch-Block "gefangen" und die dortigen Anweisungen werden ausgeführt.
Zusätzlich zu try catch kann auch noch ein finally-Block definiert werden.
Er stellt die weitere Ausführung des Programms nach einem Fehler sicher.
Der Hamster dreht nach einem Fehler (MauerIstDaFehler) um und läuft zur gegenüberliegenden Wand.
void main() { VorsichtigerHamster paul = new VorsichtigerHamster(0, 3, Hamster.OST, 0); try { paul.vorsichtigesVor(); } catch (MauerIstDaFehler fehlerObjekt) { paul.schreib(fehlerObjekt.toString()); } finally { paul.linksUm(); paul.linksUm(); while(paul.vornFrei()) paul.vor(); } }
Du kannst auf einer beliebigen Kachel einen neuen Hamster mit den → Attributen eines bestehenden Hamster erzeugen
void main() { Hamster paul = new Hamster(0, 0, Hamster.OST,0); while(paul.vornFrei()) paul.vor(); // willi wird mit den Attributen von paul initialisiert Hamster willi = new Hamster(paul); willi.linksUm(); willi.linksUm(); willi.linksUm(); while(willi.vornFrei()) willi.vor(); // karin wird mit den Attributen von willi initialisiert Hamster karin = new Hamster(willi); karin.linksUm(); karin.linksUm(); karin.linksUm(); while(karin.vornFrei()) karin.vor(); }
Wenn du eine eigene → Hamsterklasse erstellt hast, musst du diese um einen weiteren → Konstruktor ergänzen:
// neuen Hamster mit den Attributen eines bestehenden Hamsters erzeugen AllesKoennerHamster(Hamster existierenderHamster) { super(existierenderHamster); }
Jetzt kannst du das "Kopieren" der Attribute einsetzen:
void main() { AllesKoennerHamster paul = new AllesKoennerHamster(0, 0, Hamster.OST, 0); while(paul.vornFrei()) paul.vor(); // willi wird mit den Attributen von paul initialisiert AllesKoennerHamster willi = new AllesKoennerHamster(paul); willi.linksUm(); willi.linksUm(); willi.linksUm(); while(willi.vornFrei()) willi.vor(); // karin wird mit den Attributen von willi initialisiert AllesKoennerHamster karin = new AllesKoennerHamster(willi); karin.linksUm(); karin.linksUm(); karin.linksUm(); while(karin.vornFrei()) karin.vor(); }
Grundlage:
→ Klasse Hamster.
Wird ein Hamster mit zusätzlichen → Attributen oder → Methoden ausgestattet, spricht man von einer erweiterten Hamsterklasse. Erweiterte Hamsterklassen sind die "Erben" der Klasse Hamster. Sie besitzen ("erben") alle Attribute und Methoden der Klasse Hamster und es können noch weitere Attribute und Klassen hinzufügt werden.
class SammelHamster extends Hamster { // Definition von Attributen (Eigenschaften) int gesammelteKoerner = 0; // Definition von Methoden void sammle() { while (this.kornDa()) { this.nimm(); this.gesammelteKoerner = this.gesammelteKoerner + 1; } } void legeKoernerAb() { while (this.gesammelteKoerner > 0) { this.gib(); this.gesammelteKoerner = this.gesammelteKoerner - 1; } } } // Hauptprogramm void main() { // erweiterter Hamster vom Typ SammelHamster SammelHamster heidi = new SammelHamster(); heidi.init(2, 0, Hamster.OST, 0); heidi.vor(); heidi.sammle(); heidi.vor(); heidi.legeKoernerAb(); heidi.vor(); }
Von einer erweiterten Hamsterklasse (StufeHochHamster) kann wiederum eine neue Hamsterklasse (StufeAbHamster) abgeleitet werden.
Sie "erbt" dann die Methoden und Attribute der Klasse Hamster und die Methoden und Attribute der Klasse StufeHochHamster.
class StufeHochHamster extends Hamster { int zaehleStufe = 0; void erklimmeStufe() { while(!this.vornFrei()) { this.linksUm(); this.vor(); this.rechtsUm(); this.vor(); this.zaehleStufe = this.zaehleStufe + 1; } } void rechtsUm() { this.linksUm(); this.linksUm(); this.linksUm(); } } class StufeAbHamster extends StufeHochHamster { void steigeHerabStufe() { while(this.zaehleStufe > 0) // geerbtes Attribut { this.rechtsUm(); // geerbte Methode (von stufeHochHamster) this.vor(); // geerbte Methode (von Hamster) this.linksUm(); this.vor(); this.zaehleStufe = this.zaehleStufe - 1; } } } void main() { /* StufeAbHamster heidi kann die Stufen hinauf und herab steigen -> geerbte Methode stufeHoch() von StufeHochHamster -> geerbtes Attribut zaehleStufe von StufeHochHamster karin kann nur die Stufen hinauf steigen */ StufeAbHamster heidi = new StufeAbHamster(); StufeHochHamster karin = new StufeHochHamster(); heidi.init(5, 0, Hamster.OST, 0); heidi.erklimmeStufe(); heidi.vor(); heidi.steigeHerabStufe(); karin.init(5, 0, Hamster.OST, 0); karin.erklimmeStufe(); }
Siehe auch:
→ Konventionen für Bezeichner von Prozeduren, Methoden, Funktionen, Variablen, Klassen und Interfaces.Der Hamster kann verschiedene Farben annehmen.
Der → Konstruktor muss um eine Paramater erweitert werden:
void main() { AllesKoennerHamster paul = new AllesKoennerHamster(0, 0, Hamster.OST, 0, 0); AllesKoennerHamster karin = new AllesKoennerHamster(1, 0, Hamster.OST, 0, 1); AllesKoennerHamster willi = new AllesKoennerHamster(2, 0, Hamster.OST, 0, 2); AllesKoennerHamster heidi = new AllesKoennerHamster(3, 0, Hamster.OST, 0, 3); AllesKoennerHamster tom = new AllesKoennerHamster(4, 0, Hamster.OST,0, 4); AllesKoennerHamster luisa = new AllesKoennerHamster(5, 0, Hamster.OST,0, 5); AllesKoennerHamster karl = new AllesKoennerHamster(6, 0, Hamster.OST, 0, 6); AllesKoennerHamster susanne = new AllesKoennerHamster(7, 0, Hamster.OST, 0, <7); AllesKoennerHamster theo = new AllesKoennerHamster(8, 0, Hamster.OST,0, 8); AllesKoennerHamster karola = new AllesKoennerHamster(9, 0, Hamster.OST, 0, 9); }
Eine for-Schleife erwartet in der Klammer 3 Parameter:
Im Unterschied zu → while läuft die for-Schleife eine festgelegte Anzahl von Durchläufen.
void main() { int zaehler; for (zaehler = 1; zaehler < 6; zaehler ++) { vor(); } }
Siehe auch:
→ while, → break, → continueMit einer for each Schleife kann man für jedes Element eines → Arrays eine bestimmte Aktion
durchführen. Sie ähnelt der → for-Schleife.
In einer for each Schleife wird zunächst eine Schleifenvariable definiert. Dem Doppelpunkt folgt die Angabe des Arrays.
"Übersetzt" bedeutet for each:
Untersuche jedes Element im Array: Beginne mit dem Kleinsten und ende beim Größsten.
Die Schleifenvariable muss vom gleichen Typ wie das Array sein!
void main() { String buchstabenString = ""; Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // Array mit Buchstaben String[] buchstaben = new String []{"A","B","C","D","E"}; // Lösung mit for each for (String zaehler : buchstaben) { buchstabenString = buchstabenString + zaehler; } paul.schreib(buchstabenString); buchstabenString = ""; // Zum Vergleich: Lösung mit for for(int zaehler = 0; zaehler < buchstaben.length; zaehler ++) { buchstabenString = buchstabenString + buchstaben[zaehler]; } paul.schreib(buchstabenString); }
Mit Territorium.getAnzahlHamster wird die Anzahl der Hamster (einschließlich des Standardhamsters), die sich im Territorium befinden, ermittelt.
void main() { Hamster paul = new Hamster(1, 0, 0, 0); Hamster willi = new Hamster(2, 0, 0, 0); paul.schreib("Im Territorium befinden sich " + Territorium.getAnzahlHamster() + " Hamster!"); }Beispiel mit einem → Subobjekt:
class NachwuchsHamster extends Hamster { /* ein Subobjekt der Klasse NachwuchsHamster wird erzeugt jeder neue Hamster nachwuchs hat die gleichen Eigenschaften wie der NachwuchsHamster nachwuchs */ static int neueReihe = 1; // Konstruktor NachwuchsHamster nachwuchs; NachwuchsHamster() { // Start in der untersten Reihe int reihe = Territorium.getAnzahlSpalten() - neueReihe; int spalte = Territorium.getAnzahlReihen() - 1; int blickrichtung = NachwuchsHamster.WEST; this.init(reihe, spalte, blickrichtung, 0); this.nachwuchs = null; } void laufe() { // erst läuft paul while(this.vornFrei()) this.vor(); // es werden maximal 4 Hamster (inklusive paul) erzeugt while (Territorium.getAnzahlHamster() < 5) { while(this.vornFrei()) this.vor(); neueReihe = neueReihe + 1; // ein neuer Hamster wird erzeugt this.nachwuchs = new NachwuchsHamster(); // rekursiver Aufruf lauf() this.nachwuchs.lauf(); } } }
void main() { NachwuchsHamster paul = new NachwuchsHamster(); paul.laufe(); }
Territorium.mauerDa() stellt fest, ob sich an der angegebenen Position im Hamsterfeld eine Mauer befindet.
Es werden die Parameter reihe und spalte erwartet.
int zufallsZahl(int maxZahl) { return (int) (Math.random() * maxZahl + 1); } void main() { // reihe und spalte zufällig bestimmen int spalte = zufallsZahl(Territorium.getAnzahlSpalten() - 1); int reihe = zufallsZahl(Territorium.getAnzahlReihen() - 1); // der Hamster wird nur dann initialisiert, wenn sich an der Position keine Mauer befindet Hamster willi = new Hamster(); if (!Territorium.mauerDa(reihe, spalte)) willi.init(reihe, spalte, Hamster.OST, 0); }
getAnzahlKoerner() stellt fest, wie viele Körner der Hamster im Maul hat.
void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); while (paul.kornDa()) paul.nimm(); paul.schreib("Ich habe "+ paul.getAnzahlKoerner() + " Koerner im Maul!"); }
Grundlage:
→ Klasse Hamster
Diese Befehle liefern Informationen über die Position und die Blickrichtung eines namentlich bekannten Hamsters auf dem → Hamsterfeld.
getReihe gibt die Reihe zurück, getSpalte zählt die Spalten.
Die Zählung beginnt mit 0!
void main() { Hamster willi = new Hamster(); willi.init(2, 3, Hamster.OST, 0); willi.schreib("Ich befinde mich " + willi.getReihe() + " Spalte" + willi.getReihe()); }
getBlickrichtung() liefert eine Variable vom Typ int:
0 --> NORD
1 --> OST
2 --> SUED
3 --> WEST
void main() { Hamster paul = new Hamster(); paul.init(4, 0, Hamster.OST, 0); int drehung = 0; int blickRichtung; while (drehung < 4) { blickRichtung = paul.getBlickrichtung(); switch (blickRichtung) { case (0): { paul.schreib("Ich schaue nach Norden!"); paul.linksUm(); drehung = drehung + 1; break; } case (1): { paul.schreib("Ich schaue nach Osten!"); paul.linksUm(); drehung = drehung + 1; break; } case (2): { paul.schreib("Ich schaue nach Süden!"); paul.linksUm(); drehung = drehung + 1; break; } case (3): { paul.schreib("Ich schaue nach Westen!"); paul.linksUm(); drehung = drehung + 1; break; } } } }
→ Variable können lokal oder global definiert werden:
void main() { for (int zaehler = 1; zaehler < 10; zaehler ++) { /* Gültigkeitsbereich der Variablen zaehler und ergebnis nur innerhalb der geschweiften Klammern */ int ergebnis = zaehler * zaehler; } /* führt zu einer Fehlermeldung (cannot find symbol) -> die Variable ergebnis gilt nur lokal */ schreib(String.valueOf(ergebnis)); }
// globale Variable int anzahlSchritte = 0; void main() { bisZurMauer(); schreib(String.valueOf(anzahlSchritte)); } void bisZurMauer() { while (vornFrei()) { vor(); anzahlSchritte = anzahlSchritte + 1; } }
class LaufHamster extends Hamster { // globale Variable int anzahlSchritte = 0; LaufHamster(int reihe, int spalte, int blickrichtung, int koerner) { this.init(reihe, spalte, blickrichtung, koerner); } void bisZurMauer() { while (this.vornFrei()) { this.vor(); this.anzahlSchritte = this.anzahlSchritte + 1; } } void zeigeSchritte() { this.schreib(String.valueOf(anzahlSchritte)); } }
void main() { LaufHamster paul = new LaufHamster(0, 0, Hamster.OST, 0); paul.bisZurMauer(); paul.zeigeSchritte(); }
Siehe auch:
→ staticMit getStandardHamster() kann dem blauen Standardhamster ein Name zugeordnet werden.
void main() { Hamster paul = Hamster.getStandardHamster(); paul.init(0, 0, Hamster.OST, 0); while(paul.vornFrei()) paul.vor(); }
Wenn du in einer → Hamsterklasse den Standardhamster verwenden willst, musst du einen weiteren → Konstruktor erstellen
class AllesKoennerHamster extends Hamster { AllesKoennerHamster(int reihe, int spalte, int blickrichtung, int koerner) { this.init(reihe, spalte, blickrichtung, koerner); } AllesKoennerHamster(Hamster existierenderHamster) { super(existierenderHamster); } }
Jetzt kannst du den Standardhamster verwenden:
void main() { AllesKoennerHamste paul = new AllesKoennerHamste(Hamster.getStandardHamster()); }
void main () { . . . }
Wenn du einen → neuen Hamster erzeugt hast, musst du dem Befehl den Namen des Hamster → voranstellen.
Das Überschreiben von hamstereigenen Methoden erfordert zwei Besonderheiten:
class UeberschreibHamster extends Hamster { UeberschreibHamster (int reihe, int spalte, int blickrichtung, int koerner) { this.init(reihe, spalte, blickrichtung, koerner); } // "normale" Hamster-Methode -> Aufruf mit this möglich void kehrt() { this.linksUm(); this.linksUm(); } /* überschriebene Hamster-Methoden nimm(), gib() und vor() -> Aufruf mit super erforderlich kornDa(), maulLeer() und vornFrei() sind "normale" hamstereigene Sensoren -> Aufruf mit this möglich */ public void nimm() { while (this.kornDa()) super.nimm(); } public void gib() { while (!this.maulLeer()) super.gib(); } public void vor() { while (this.vornFrei()) super.vor(); } }
void main() { UeberschreibHamster paul = new UeberschreibHamster(3, 0, Hamster.OST, 6); paul.vor(); paul.gib(); UeberschreibHamster willi = new UeberschreibHamster(paul.getReihe(), paul.getSpalte(), Hamster.OST, 0); willi.nimm(); willi.kehrt(); willi.vor(); willi.gib(); }
Die Position, die der Hamster einnimmt, wird durch zwei → Integer-Variablen beschrieben:
Die Zählung beginnt immer mit 0!
Das Programm erzeugt mit Hilfe eines → Arrays in jeder Zeile des Territoriums in der ersten Spalte einen Hamster.
Ein durch → Zufall ermittelter Hamster wird als Sieger ermittelt und darf bis zur Wand laufen.
void main() { // Anzahl der Hamster festlegen int anzahlHamster = Territorium.getAnzahlReihen(); // Array initialisieren Hamster[] familie = new Hamster[anzahlHamster]; for (int zaehler = 0; zaehler < anzahlHamster; zaehler = zaehler + 1) { familie[zaehler] = new Hamster(zaehler, 0, Hamster.OST, 0); } Hamster sieger = liefereHamster(familie); while(sieger.vornFrei()) sieger.vor(); // der Sieger freut sich sieger.linksUm(); sieger.linksUm(); sieger.linksUm(); sieger.linksUm(); } // Hamster-Array familie an die Funktion liefereHamster übergeben Hamster liefereHamster(Hamster[] familie) { Hamster sieger = null; int zahl = (int) (Math.random() * familie.length); sieger = familie[zahl]; return sieger; }
void main() { // Anzahl der Hamster festlegen int anzahlHamster = Territorium.getAnzahlReihen(); // Array initialisieren Hamster[] familie = new Hamster[anzahlHamster]; // Hamster des Arrays erzeugen und initialisieren for (int zaehler = 0; zaehler < anzahlHamster; zaehler = zaehler + 1) { familie[zaehler] = new Hamster(zaehler, 0, Hamster.OST, 0); } // neues Objekt der Klasse Wettlauf erzeugen Wettlauf rennen = new Wettlauf(); // Funktion liefereHamster der Klasse Wettlauf aufrufen Hamster sieger = rennen.liefereHamster(familie); // der Sieger läuft zur gegenüberliegenden Wand while(sieger.vornFrei()) sieger.vor(); // der Sieger freut sich sieger.linksUm(); sieger.linksUm(); sieger.linksUm(); sieger.linksUm(); }
class Wettlauf { // Hamster-Array familie an die Funktion liefereHamster übergeben Hamster liefereHamster(Hamster[] familie) { Hamster sieger = null; // maximale Zufallszahl ist die Länge des Arrays familie int zahl = (int) (Math.random() * familie.length); // Sieger ist der Hamster zahl im Array sieger = familie[zahl]; return sieger; } }
if ist eine einfache Verzweigung oder Entscheidungsanweisung.
Wenn die mit if abgefragte Bedingung erfüllt ist, dann wird die darauf folgende Anweisung ausgeführt.
Ist diese Bedingung nicht erfüllt, wird die auf else folgende Anweisung befolgt.
Bedingungen können → Sensoren, der Rückgabewert einer → boolean-Funktion oder der Wert einer → Integer-Variable sein
Die if-Anweisung hat die allgemeine Form:
Wenn (if) die Bedingung wahr ist, wird diese Anweisung ausgeführt, ansonsten (else)
wird mit einem anderen Befehl fortgesetzt.
Der else-Zweig der Anweisung ist optional, d. h. er kann auch weggelassen werden.
if (Bedingung) { . . . . . . }
Wenn die Bedingung unwahr ist, wird dieser Programmteil ausgeführt.
else { . . . . . . }
Abfrage eines → Sensors ...
if (vornFrei()) { vor(); } else { linksUm(); }
Abfrage einer → Integer-Variable ...
int anzahlSchritte = 7; if (anzahlSchritte > 0) { anzahlSchritte = anzahlSchritte - 1; vor(); } else { linksUm(); }
Abfrage einer → boolean-Funktion ...
// boolean-Funktion linksFrei() boolean linksFrei() { linksUm(); if (vornFrei()) { linksUm(); linksUm(); linksUm(); return true; } else { linksUm(); linksUm(); linksUm(); return false; } if (linksFrei()==true) vor();
Der else-Zweig kann auch mit else if fortgesetzt werden.
Wenn (if) die Bedingung wahr ist, wird diese Anweisung ausgeführt, oder wenn (else if)
eine andere Bedingung wahr ist, wird mit einem anderen Befehl fortgesetzt.
if (linksFrei()) linksUm(); else if (rechtsFrei()) rechtsUm();
if-Abfragen können auch verschachtelt sein:
Mit einer verschachtelten if-Anweisung wird nacheinander getestet ob vorne frei ist, auf der Hamsterposition ein Korn liegt oder links frei ist.
void main() { if (vornFrei()) vor(); // vor dem Hamster befindet sich eine Mauer -> Bedingung ist nicht erfüllt -> weiter mit else else if (kornDa()) nimm(); // auf der Hamsterposition liegt kein Korn -> Bedingung ist nicht erfüllt -> weiter mit else else if (linksFrei()) // Bedingung ist erfüllt -> if ausführen { linksUm(); vor(); } } // Testen ob links frei ist boolean linksFrei() { linksUm(); boolean ist_frei = vornFrei(); rechtsUm(); return ist_frei; } void rechtsUm() { linksUm(); linksUm(); linksUm(); }
Siehe auch:
→ switchGrundlagen:
→ Zugriffsrechte
Alle → Methoden und → Funktionen, die außerhalb des Paketes verwendet werden sollen, müssen als public definiert werden.
public class AllesKoennerHamster extends Hamster { public AllesKoennerHamster (int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } // neuen Hamster mit den Attributen eines bestehenden Hamsters erzeugen public AllesKoennerHamster(Hamster existierenderHamster) { super(existierenderHamster); } public void kehrUm() { this.linksUm(); this.linksUm(); } public void rechtsUm() { this.kehrUm(); this.linksUm(); } }
Erstelle einen Ordner AllesKoennerHamster und speichere das Paket
in diesem Ordner unter AllesKoennerHamster.
Setze den → CLASSPATH so, dass du in jedem Programm innerhalb des Ordners Programme
das Paket AllesKoennerHamster mit ...
import AllesKoennerHamster.AllesKoennerHamster;
... einbinden kannst.
Grundlage:
→ Java-Klassenbibliothek
Mit der import-Anweisung bindest du eine oder mehrere Java-Klassen ein.
import java.util.ArrayList; import java.util.Random; void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); ArrayList<Integer> zahlen = new ArrayList<Integer>); Random zufall = new Random() }
Wenn du mehrere Klassen der jeweiligen Bibliothek verwenden willst kannst du das mit dem "*" signalisieren.
import java.util.*; void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); ArrayList<Integer> zahlen = new ArrayList<Integer>); Random zufall = new Random() }
indexOf() sucht nach der Position eines Strings in einer Zeichenkette.
Ist der zu suchende String nicht enthalten, wird -1 zurück gegeben.
Die Zählung beginnt mit 0!
Im Beispiel soll innerhalb der Zeichenkette die Position des . festgestellt werden.
An dieser Stelle soll ein Zeilenumbruch eingefügt werden.
void main() { String antwort = "Der Hamster kann sich nach links drehen. Der Befehl lautet linksUm()."; int index = antwort.indexOf("."); String satz = antwort.substring(0,index) + ".\n" + antwort.substring(index + 1,antwort.length()); schreib(satz); }
Siehe auch:
→ String, → substring()Interfaces sind nichts anderes als → abstrakte Klassen,
die ausschließlich abstrakte Methoden definieren dürfen.
Die Definition ist ähnlich der von Klassen, statt class wird das Schlüsselwort interface verwendet.
Der DrehHamster definiert die Methode drehen().
interface DrehHamster { public abstract void drehen(); }
Das Interface LaufHamster definiert die Methoden rueckeVor(int anzahlSchritte) und zufallsZahl(int maxZahl).
interface LaufHamster { public abstract void rueckeVor(int anzahlSchritte); public abstract int zufallsZahl(int maxZahl); }
Weiterhin existieren zwei → Klassen:
EhrlicherHamster und MogelHamster.
Mit dem Schlüsselwort implements können Interfaces anstelle der → extends-Anweisung
oder zusätzlich zu extends eingesetzt werden.
class EhrlicherHamster extends Hamster implements LaufHamster, DrehHamster { . . . }
Innerhalb der Klasse müssen die Methoden der Interfaces DrehHamster und LaufHamster mit Inhalt gefüllt (implementiert) werden.
In beiden Klassen kommt die → Polymorphie zum Einsatz:
Die Methoden rueckeVor(int anzahlSchritte) und drehen() sind für die beiden Klassen unterschiedlich implementiert.
class EhrlicherHamster extends Hamster implements LaufHamster, DrehHamster { // static -> in der ganzen Klasse gültig static int anzahlSchritte; // Konstruktor EhrlicherHamster (int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } // Methode des interfaces LaufHamster // der Hamster geht die durch Zufall ermittelte Anzahl von Schritten public void rueckeVor(int anzahlSchritte) { while (anzahlSchritte > 0) { this.vor(); anzahlSchritte --; } } // Methode des interfaces LaufHamster public int zufallsZahl(int maxZahl) { return (int)(Math.random()*maxZahl); } // Methode des interfaces DrehHamster public void drehen() { this.linksUm(); this.linksUm(); this.linksUm(); } }
class MogelHamster extends Hamster implements LaufHamster, DrehHamster { // static -> in der ganzen Klasse gültig static int anzahlSchritte; // Konstruktor MogelHamster (int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } // Methode des interfaces LaufHamster // der Hamster "mogelt": er geht unabhängig von der Zufallszahl // bis zum Ende des Territoriums public void rueckeVor(int anzahlSchritte) { int schritte = 0; while (schritte > Territorium.getAnzahlSpalten() - 1) { this.vor(); schritte ++; } } // Methode des interfaces LaufHamster public int zufallsZahl(int maxZahl) { return (int)(Math.random() * maxZahl); } // Methode des interfaces DrehHamster public void drehen() { this.linksUm(); } }
Im Hauptprogramm gehen die Hamster unterschiedliche Wege:
void main() { MogelHamster willi = new MogelHamster(Territorium.getAnzahlReihen() -1, 0, Hamster.OST, 0); EhrlicherHamster paul = new EhrlicherHamster(0, 0, Hamster.OST, 0); // paul und willi ermitteln eine Zufallszahl // willi "mogelt" und läuft bis zur nächsten Wand // paul geht die zufällige Anzahl Schritte willi.rueckeVor(willi.zufallsZahl(6)); paul.rueckeVor(paul.zufallsZahl(6)); // willi dreht sich nach links, paul nach rechts // beide laufen zur gegenüberliegenden Wand willi.drehen(); while (willi.vornFrei()) willi.vor(); paul.drehen(); while (paul.vornFrei()) paul.vor(); }
Siehe auch:
→ Abstrakte Klasse, → Polymorphie, → Dynamisches BindenDie bisher verwendeten → Klassen wurden immer außerhalb des eigentlichen Programms
erstellt und gespeichert.
Daneben gibt es die Möglichkeit, Klassen zur besseren Strukturierung innerhalb einer
bestehenden Klasse zu definieren.
// Klasse Zufall muss als static deklariert werden static class Zufall { static int zufallsZahl(int maxZahl) { return (int)(Math.random() * maxZahl + 1); } } void main() { Hamster willi = new Hamster(0, 0, Hamster.OST, 0); // Zugriff auf die innere Klasse Zufall int anzahlSchritte = Zufall.zufallsZahl(6); int schrittZaehler = 0; while (schrittZaehler < anzahlSchritte) { if (willi.vornFrei()) willi.vor(); schrittZaehler = schrittZaehler + 1; } }
Auch → Hamsterklassen können als innere Klassen eingebunden werden.
Im Beispiel werden die Klassen Laufhamster und Sammelhamster als innere Klassen definiert.
class LaufHamster extends Hamster { LaufHamster(int reihe, int spalte, int blickrichtung, int koerner) { this.init(reihe, spalte, blickrichtung, koerner); } void bisZurWand() { while(this.vornFrei()) this.vor(); } } class SammelHamster extends Hamster { SammelHamster(int reihe, int spalte, int blickrichtung, int koerner) { this.init(reihe, spalte, blickrichtung, koerner); } void rechtsUm() { this.linksUm(); this.linksUm(); this.linksUm(); } boolean linksFrei() { linksUm(); boolean ist_frei = vornFrei(); rechtsUm(); return ist_frei; } void laufeUndSammle() { int reihe = 0; while (reihe < Territorium.getAnzahlReihen()) { reihe = reihe + 1; while (this.vornFrei()) { if(this.kornDa()) this.nimm(); this.vor(); } if(reihe < Territorium.getAnzahlReihen()) { if(this.getSpalte() > 0) { this.rechtsUm(); this.vor(); this.rechtsUm(); } else { this.linksUm(); this.vor(); this.linksUm(); } } } } } void main() { LaufHamster willi = new LaufHamster(0, 0, Hamster.OST, 0); willi.bisZurWand(); SammelHamster paul = new SammelHamster(0, 0, Hamster.OST, 0); paul.laufeUndSammle(); }
Der Hamster muss oft eine Aufgabe vom Typ solange eine Bedingung erfüllt ist, führe einen Befehl aus, erledigen.
Dies kann mit einer Iteration mit Hilfe von → while oder → for gelöst werden.
Das Problem lässt sich auch mit einer → Rekursion lösen.
Der Hamster soll solange die Körner einer Reihe sammeln, bis er die gegenüberliegende Wand erreicht hat.
Die Aufgabe kann mit einer Iteration oder Rekursion gelöst werden.
void main() { // iterative Lösung mit while while (vornFrei()) { if (kornDa()) nimm(); vor(); } // rekursive Lösung reiheAbgrasen(); } void reiheAbgrasen() { if (vornFrei()) { if (kornDa()) { nimm(); vor(); reiheAbgrasen(); } } }
Um diese Funktion benutzen zu können, muss in der Datei hamsterproperties im Java-Hamster-Verzeichnis eine Änderung vorgenommen werden: Der Wert für security muss auf false gesetzt werde.
security=false
import java.io.File; import java.text.SimpleDateFormat; class VerzeichnisLesen { String verzeichnisInhalt(String verzeichnisDurchsuchen) { // uebergebenens String-Objekt verzeichnisDurchsuchen in File-Objekt umwandeln File verzeichnis = new File(verzeichnisDurchsuchen); // Ein File-Array anlegen, den Inhalt des Verzeichnisses auslesen File[] dateien = verzeichnis.listFiles(); String dateienZeigen = ""; // mit for each das Array dateien durchlaufen for(File zaehler : dateien) { if (zaehler.isDirectory()) { dateienZeigen = dateienZeigen + "Ordner: " + zaehler.getName() + "\n"; } else { /* Objekt SimpleDateFormat anlegen, Datum und Uhrzeit mit SimpleDateFormat feststellen Umlaute nach Unicode umwandeln \u00C4 -> Ä \u00F6 -> ö \u00DFe -> ß */ SimpleDateFormat datumDatei = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); dateienZeigen = dateienZeigen + "Datei: " + zaehler.getName() + " Letzte \u00C4nderung: " + datumDatei.format(zaehler.lastModified()) + " Gr\u00F6\u00DFe in KB: " + zaehler.length()/1024 + " KB\n"; } } return dateienZeigen; } }
void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // neues Objekt VerzeichnisLesen erzeugen VerzeichnisLesen lesen = new VerzeichnisLesen(); // Ordner Programme als String übergeben String dateien = lesen.verzeichnisInhalt("Programme"); paul.schreib(dateien); }
Um diese Funktion benutzen zu können, muss in der Datei hamsterproperties im Java-Hamster-Verzeichnis eine Änderung vorgenommen werden: Der Wert für security muss auf false gesetzt werde.
security=false
Im Verzeichnis Programme befindet sich eine Datei namen.txt mit dem Inhalt:
Paul Gerda Karin Willi
import java.io.PrintWriter; import java.io.File; import java.io.FileWriter; import java.io.FileReader; import java.io.BufferedReader; import java.io.IOException; // oder alle Einbinden -> import java.io.*; import java.util.ArrayList; import java.util.Collections; void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); ArrayList<String> namen = new ArrayList<String>(); try { // FileReader-Objekt erzeugen FileReader dateiName = new FileReader("Programme/namen.txt"); // BufferedReader-Objekt erzeugen BufferedReader zeile = new BufferedReader(dateiName); // erste Zeile aus Datei lesen String eingabe = zeile.readLine(); namen.add(eingabe); // solange lesen bis die gelesene Zeile leer ist while (eingabe != null) { eingabe = zeile.readLine(); if (eingabe != null) namen.add(eingabe); } } catch (IOException fehlerMeldung) { // eventuelle Fehlermeldung wird in die Datei syserr.txt geschrieben fehlerMeldung.printStackTrace(); } // Liste aufsteigend sortieren Collections.sort(namen); String alleNamen = new ArrayList<String>(namen).toString(); paul.schreib("Liste aufsteigend sortieren: " + alleNamen); }
Um diese Funktion benutzen zu können, muss in der Datei hamsterproperties im Java-Hamster-Verzeichnis eine Änderung vorgenommen werden: Der Wert für security muss auf false gesetzt werde.
security=false
Mit Hilfe der → Java-Klassenbibliothek kann der Hamster auch Daten in eine Datei speichern.
import java.io.PrintWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; // oder alle Einbinden -> import java.io.*; class DateiSchreiben { void dateiSchreiben(String nameDatei, String inhalt) { try { // String-Objekt in File-Objekt umwandeln File datei = new File(nameDatei); // PrintWriter-Objekt erzeugen PrintWriter dateiName; // dem Printwriter wird das Objekt FileWriter mit dem Dateinamen übergeben dateiName = new PrintWriter(new FileWriter(datei)); // der Inhalt wird in die Datei geschrieben dateiName.println(inhalt); // die Datei wird geschlossen dateiName.close(); } catch (IOException fehlerMeldung) { // eventuelle Fehlermeldung wird in die Datei syserr.txt geschrieben fehlerMeldung.printStackTrace(); } } }
void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 10); // neues Objekt DateiSchreiben erzeugen DateiSchreiben schreiben = new DateiSchreiben(); // eingegebenen Text in den String inhalt schreiben String inhalt = paul.liesZeichenkette("Text:"); /* Aufruf der Methode dateiSchreiben der Klasse DateiSchreiben als Parameter wird der Dateiname und der Text uebergeben die Datei wird in das Verzeichnis des Hamstersimulators geschrieben */ schreiben.dateiSchreiben("text.txt", inhalt); }
import java.io.PrintWriter; import java.io.File; import java.io.FileWriter; import java.io.FileReader; import java.io.BufferedReader; import java.io.IOException; // oder alle Einbinden -> import java.io.*; import java.text.SimpleDateFormat; class DateiLesenSchreiben { String verzeichnisLesen(String verzeichnisDurchsuchen) { // String-Objekt in File-Objekt umwandeln File verzeichnis = new File(verzeichnisDurchsuchen); // Ein File-Array anlegen, den Inhalt des Verzeichnisses mit dem Filter TextDateiFilter auslesen File[] dateien = verzeichnis.listFiles(new TextDateiFilter()); String dateienZeigen = "Dateiname Aenderungsdatum\n_____________________________________\n "; // mit for each das Array dateien durchlaufen for(File zaehler : dateien) { if (zaehler.isDirectory()) { dateienZeigen = dateienZeigen +"Ordner: " + zaehler.getName() + "\n"; } else { // Objekt SimpleDateFormat anlegen, Datum und Uhrzeit mit SimpleDateFormat feststellen SimpleDateFormat datumDatei = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); dateienZeigen = dateienZeigen + zaehler.getName() + "\t" + datumDatei.format(zaehler.lastModified()) + "\n"; } } return dateienZeigen; } String dateiLesen(String dateiOeffnen) { String dateiInhalt = ""; try { // String-Objekt in File-Objekt umwandeln File datei = new File(dateiOeffnen); // FileReader-Objekt erzeugen FileReader dateiName = new FileReader(datei); // BufferedReader-Objekt erzeugen BufferedReader zeile = new BufferedReader(dateiName); // Zeile aus Datei lesen String befehl = zeile.readLine(); // solange lesen bis die gelesene Zeile leer ist while (befehl != null) { dateiInhalt = dateiInhalt + befehl + "\n"; befehl = zeile.readLine(); } String[] splitted = dateiInhalt.split(" "); } catch (IOException fehlerMeldung) { // eventuelle Fehlermeldung wird in die Datei syserr.txt geschrieben fehlerMeldung.printStackTrace(); } return dateiInhalt; } void dateiSchreiben(String dateiSchreiben, String inhalt) { try { // String-Objekt in File-Objekt umwandeln File datei = new File(dateiSchreiben); // PrintWriter-Objekt erzeugen PrintWriter dateiName; // dem Printwriter wird das Objekt FileWriter mit dem Dateinamen übergeben dateiName = new PrintWriter(new FileWriter(datei)); // der Inhalt wird zeilenweise in die Datei geschrieben dateiName.println(inhalt); // die Datei wird geschlossen dateiName.close(); } catch (IOException fehlerMeldung) { // eventuelle Fehlermeldung wird in die Datei syserr.txt geschrieben fehlerMeldung.printStackTrace(); } } }
import java.io.*; class TextDateiFilter implements FileFilter { private final String[] erlaubteErweiterungen = new String[] {"txt"}; public boolean accept(File datei) { // mit for each Dateien auf die Erweiterung txt durchsuchen for (String erweiterung : erlaubteErweiterungen) { // Umwandlung in Kleinbuchstaben -> Großschreibung ignorieren if (datei.getName().toLowerCase().endsWith(erweiterung)) { return true; } } return false; } }
/* zugehörige Klassen: TextDateiFilter -> setzt .txt als Filter DateiLesenSchreiben -> zeigt ein Verzeichnis mit .txt-Dateien an, schreibt eine txt-Datei */ void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); String verzeichnisName; String auswahl = ""; DateiLesenSchreiben lesen = new DateiLesenSchreiben(); while (!auswahl.equals("e")) { auswahl = paul.liesZeichenkette("Was soll ich tun?\nv = Verzeichnis nach *.txt durchsuchen\n n = Textdatei anlegen\n e = Programm beenden"); if (auswahl.equals("v")) { verzeichnisName = paul.liesZeichenkette("Welches Verzeichnis durchsuchen?"); String dateien = lesen.verzeichnisLesen(verzeichnisName); paul.schreib(dateien); String dateiFrage = paul.liesZeichenkette("Welche Datei \u00F6ffnen?\nDie Endung txt wird automatisch angeh\u00E4ngt!"); dateiFrage = verzeichnisName +"/" + dateiFrage + ".txt"; String inhaltAnzeigen = lesen.dateiLesen(dateiFrage); paul.schreib(inhaltAnzeigen); } if (auswahl.equals("n")) { verzeichnisName = paul.liesZeichenkette("In welchem Verzeichnis soll\ndie Datei gespeichert werden?"); String inhalt = paul.liesZeichenkette("Text: (Zeilenumbruch mit \\n"); String dateiNamefestlegen = paul.liesZeichenkette("Dateiname?\nDie Endung txt wird automatisch angeh\u00E4ngt!"); dateiNamefestlegen = verzeichnisName + "/" +dateiNamefestlegen + ".txt"; lesen.dateiSchreiben(dateiNamefestlegen, inhalt); } } }
Der Java-Hamster kann auch die sogenannte Java-Klassenbibliothek nutzen.
Für die Nutzung von Swing-Elementen musst du in der Datei hamster.properties den Parameter runlocally auf true setzen!
Grundlage:
→ Swing-Bibliothek , → innere Klasse,
→ ASCII-Tabelle .
Der KeyListener kann die Eingaben der Tastatur auf einem vorhandenen → JLabel oder einer → JTextArea abfragen.
// Pakete importieren import java.awt.event.KeyListener; import java.awt.event.KeyEvent; class TastaturAbfragen implements KeyListener { // Hier muss ein Hamster (paul) definiert werden Hamster paul; TastaturAbfragen(Hamster neuerHamster) { paul = neuerHamster; } public void keyPressed(KeyEvent gedrueckteTaste) { char tasteBuchstabe = gedrueckteTaste.getKeyChar(); int taste = gedrueckteTaste.getKeyCode(); // Taste r oder Cursor nach rechts -> rechts if (taste == 39 || taste == 82) { paul.linksUm(); paul.linksUm(); paul.linksUm(); } // Taste l oder Cursor nach links -> links if (taste == 37 || taste == 76) paul.linksUm(); // Taste v oder Cursor nach oben -> vor if (taste == 38 || taste == 86) { if (paul.vornFrei()) { paul.vor(); } } // Taste n oder Cursor nach unten -> nimm if (taste == 40 || taste == 78) { if (paul.kornDa()) { paul.nimm(); } } } // überschriebene Methoden des KeyListener public void keyReleased(KeyEvent gedrueckteTaste) {} public void keyTyped(KeyEvent gedrueckteTaste) {} }
Die Hamster sind in vielen Dingen gleich:
Jeder neu erzeugt Hamster ist dennoch ein Individuum:
Alle Hamster gehören einer sogenannten Klasse an.
Eine Klasse ist eine Vorlage, die zur Erzeugung vieler Objekte (in diesem Fall Hamster) mit gleichen Eigenschaften und Verhaltensweisen dient.
Wie bei einem Abreißklotz kann immer wieder ein neuer Hamster "abgerissen" werden.
Die neu erzeugten Hamster werden auch Objekte oder Instanzen der Klasse Hamster genannt.
Hamster paul = new Hamster();... und mit den Eigenschaften Reihe, Spalte, Blickrichtung, Anzahl der Körner im Maul wird → initialisiert:
paul.init(0, 0, Hamster.OST, 0); paul.vor(); paul.rechtsUm(); void rechtsUm() { this.linksUm(); this.linksUm(); this.linksUm(); }
Beachte bei der Definition von Klassen die → Konventionen zur Bezeichnung!
Siehe auch:
→ erweiterte Hamsterklassen, → this, → super, → Methode → Methoden überladenGrundlagen:
→ Java-Swing
→ ActionListener
Mit JFrame wird ein Rahmen erzeugt in dem verschiedene grafische Elemente wie → Buttons,
→ Comboboxen oder → Textfelder platziert werden können.
Die Struktur ist immer gleich:
// Layout des Frames import java.awt.FlowLayout; import javax.swing.JFrame; import javax.swing.JButton; // → Ereignisse auf die das Programm reagieren soll import java.awt.event.ActionEvent; import java.awt.event.ActionListener;
JButton vorButton; JButton linksUmButton;
// neues Frame-Objekt erzeugen JFrame fenster = new JFrame("Hamster-Steuerung"); /* Verhalten des Fensters beim Klicken auf X festlegen JFrame.EXIT_ON_ CLOSE -> Programm wird beendet JFrame.DO_NOTHING_ON_CLOSE -> nichts tun JFrame.DISPOSE_ON_CLOSE -> nur das aktuelle Fenster wird geschlossen */ fenster.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); fenster.setLayout(new FlowLayout());
vorButton = new JButton("vor"); linksUmButton = new JButton("links");
fenster.add(vorButton); fenster.add(linksUmButton);
// dem ActionListener muss der Name des Hamsters übergeben werden vorButton.addActionListener(new MausklickAbfragen(paul)); linksUmButton.addActionListener(new MausklickAbfragen(paul));
// Frame platzieren -> 100 Pixel von links/200 Pixel von oben fenster.setLocation(100, 200); /* Fenstergroöße automatisch anpassen Alternative: fenster.setSize(Breite, Hoehe); */ fenster.pack(); // Fenster sichtbar machen fenster.setVisible(true);
Grundlagen:
→ import, → Swing-Bibliothek,
→ ActionListener
Du musst in der Datei hamster.properties den Parameter runlocally auf true setzen!
Ein JButton ist ein Button, der nach einem Mausklick ein Ereignis auslösen kann.
// Pakete importieren import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; // globale Variablen JButton linksUmButton; JButton vorButton; class MausklickAbfragen implements ActionListener { Hamster paul; MausklickAbfragen(Hamster neuerHamster) { paul = neuerHamster; } public void actionPerformed(ActionEvent mausKlick) { // getSource() -> Quelle ermitteln // Button vorButton abfragen if (mausKlick.getSource() == vorButton) { if (paul.vornFrei()) paul.vor(); } // Button linksUmButton abfragen if (mausKlick.getSource() == linksUmButton) { paul.linksUm(); } } } void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // neues Frame-Objekt erzeugen JFrame fenster = new JFrame("Hamster-Steuerung"); /* Verhalten des Fensters beim Klicken auf X festlegen JFrame.EXIT_ON_ CLOSE -> Programm wird beendet JFrame.DO_NOTHING_ON_CLOSE -> nichts tun JFrame.DISPOSE_ON_CLOSE -> nur das aktuelle Fenster wird geschlossen */ fenster.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // setLayout(new FlowLayout() -> alle Komponenten nebeneinander anordnen fenster.setLayout(new FlowLayout()); // JButton erzeugen vorButton = new JButton("vor"); linksUmButton = new JButton("linksUm"); /* ActionListener hinzufügen der Name des Hamster muss übergeben werden */ linksUmButton.addActionListener(new MausklickAbfragen(paul)); vorButton.addActionListener(new MausklickAbfragen(paul)); // Buttons anzeigen fenster.add(vorButton); fenster.add(linksUmButton); // Frame platzieren -> 100 Pixel von links/200 Pixel von oben fenster.setLocation(100, 200); /* Fenstergröße automatisch anpassen Alternative: fenster.setSize(Breite, Hoehe); */ fenster.pack(); // Fenster sichtbar machen fenster.setVisible(true); }
// Pakete importieren import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.Color; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JFrame; import javax.swing.ImageIcon; import javax.swing.Icon; import javax.swing.border.*; import java.awt.Dimension; // globale Variablen JButton vorButton; JButton linksUmButton; JButton rechtsUmButton; JButton kornNehmenButton; JButton kornGebenButton; JButton zurWandButton; JButton beendeProgrammButton; JLabel aktionBeschreibung; class MausBewegungAbfragen implements MouseListener { Hamster paul; MausBewegungAbfragen(Hamster neuerHamster) { paul = neuerHamster; } /* alle Methoden von MouseListener müssen überschrieben werden: mousePressed, mouseClicked, mouseExited, mouseReleased, mouseEntered */ public void mousePressed(MouseEvent mausAktion){} public void mouseClicked(MouseEvent mausAktion) { // Button vorButton abfragen if (mausAktion.getSource() == vorButton) { paul.vor(); } // Button linksUmButton abfragen if (mausAktion.getSource() == linksUmButton) { paul.linksUm(); } // Button rechtsUmButton abfragen if (mausAktion.getSource() == rechtsUmButton) { paul.linksUm(); paul.linksUm(); paul.linksUm(); } // Button kornNehmenButton abfragen if (mausAktion.getSource() == kornNehmenButton) { while(paul.kornDa()) paul.nimm(); } // Button kornGebenButton abfragen if (mausAktion.getSource() == kornGebenButton) { while(!paul.maulLeer()) paul.gib(); } // Button beendeProgrammButton abfragen if (mausAktion.getSource() == beendeProgrammButton) { System.exit(0); } } public void mouseExited(MouseEvent mausAktion) { aktionBeschreibung.setText(""); } public void mouseReleased(MouseEvent mausAktion){} // Text beim Überfahren des Buttons anzeigen public void mouseEntered(MouseEvent mausIn) { if (mausIn.getSource() == vorButton) { aktionBeschreibung.setText("vor"); } if (mausIn.getSource() == linksUmButton) { aktionBeschreibung.setText("nach links drehen"); } if (mausIn.getSource() == rechtsUmButton) { aktionBeschreibung.setText("nach rechts drehen"); } if (mausIn.getSource() == kornNehmenButton) { aktionBeschreibung.setText("alle Körer nehmen"); } if (mausIn.getSource() == kornGebenButton) { aktionBeschreibung.setText("alle Körner abgeben"); } if (mausIn.getSource() == beendeProgrammButton) { aktionBeschreibung.setText("Programm beenden"); } } } void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // neues Frame-Objekt erzeugen JFrame fenster = new JFrame("Hamster-Steuerung"); /* Verhalten des Fensters beim Klicken auf X festlegen JFrame.EXIT_ON_ CLOSE -> Programm wird beendet JFrame.DO_NOTHING_ON_CLOSE -> nichts tun JFrame.DISPOSE_ON_CLOSE -> nur das aktuelle Fenster wird geschlossen */ fenster.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); fenster.setLayout(new FlowLayout()); // JButtons erzeugen // vor Icon vor = new ImageIcon("Programme/start.gif"); vorButton = new JButton("", vor); vorButton.setToolTipText("vor"); // links Icon links = new ImageIcon("Programme/links.gif"); linksUmButton = new JButton("", links); // rechts Icon rechts = new ImageIcon("Programme/rechts.gif"); rechtsUmButton = new JButton("", rechts);; // Korn nehmen Icon kornNehmen = new ImageIcon("Programme/korn_nehmen.png"); kornNehmenButton = new JButton("", kornNehmen); // Korn geben Icon kornGeben = new ImageIcon("Programme/korn_geben.png"); kornGebenButton = new JButton("", kornGeben); // Programm beenden Icon stop = new ImageIcon("Programme/stop.gif"); beendeProgrammButton = new JButton("", stop); // Text zeigen, wenn der Mauszeiger sich über dem Button befindet aktionBeschreibung = new JLabel(""); aktionBeschreibung.setPreferredSize(new Dimension(175, 40)); aktionBeschreibung.setBackground(Color.yellow); aktionBeschreibung.setOpaque(true); aktionBeschreibung.setBorder(new BevelBorder(BevelBorder.LOWERED)); aktionBeschreibung.setHorizontalAlignment(JLabel.CENTER); // Buttons und Label anzeigen fenster.add(vorButton); fenster.add(linksUmButton); fenster.add(rechtsUmButton); fenster.add(kornNehmenButton); fenster.add(kornGebenButton); fenster.add(beendeProgrammButton); fenster.add(aktionBeschreibung); // für jedes Element MouseListener hinzufügen vorButton.addMouseListener(new MausBewegungAbfragen(paul)); linksUmButton.addMouseListener(new MausBewegungAbfragen(paul)); rechtsUmButton.addMouseListener(new MausBewegungAbfragen(paul)); kornNehmenButton.addMouseListener(new MausBewegungAbfragen(paul)); kornGebenButton.addMouseListener(new MausBewegungAbfragen(paul)); beendeProgrammButton.addMouseListener(new MausBewegungAbfragen(paul)); // Frame platzieren -> 100 Pixel von links/200 Pixel von oben fenster.setLocation(100, 200); /* Fenstergroesse automatisch anpassen Alternative: fenster.setSize(Breite, Hoehe); */ fenster.pack(); // Fenster sichtbar machen fenster.setVisible(true); }
Grundlagen:
→ import, → Swing-Bibliothek,
→ ActionListener
Eine JCombobox bietet ein Auswahlmenü an. Ein Mausklick auf eines der Felder löst ein Ereignis aus.
// Pakete importieren import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.Color; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JComboBox; // globale Variablen JComboBox hamsterBefehle; JButton beendeProgrammButton; class MausklickAbfragen implements ActionListener { Hamster paul; MausklickAbfragen(Hamster neuerHamster) { paul = neuerHamster; } public void actionPerformed(ActionEvent mausKlick) { // getSource() -> Quelle ermitteln // Button beendeProgrammButton abfragen if (beendeProgrammButton == mausKlick.getSource()) { System.exit(0); } // JCombobox abfragen -> Zählung beginnt mit 0 if ( mausKlick.getSource() == hamsterBefehle) { int index = hamsterBefehle.getSelectedIndex(); if (index == 0) { if (paul.vornFrei()) paul.vor(); } if (index == 1) { paul.linksUm(); } if (index == 2) { paul.linksUm(); paul.linksUm(); paul.linksUm(); } if (index == 3) { while (paul.vornFrei()) paul.vor(); } } } } void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // neues Frame-Objekt erzeugen JFrame fenster = new JFrame("Hamster-Steuerung"); /* Verhalten des Fensters beim Klicken auf X festlegen JFrame.EXIT_ON_ CLOSE -> Programm wird beendet JFrame.DO_NOTHING_ON_CLOSE -> nichts tun JFrame.DISPOSE_ON_CLOSE -> nur das aktuelle Fenster wird geschlossen */ fenster.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // setLayout(new FlowLayout() -> alle Komponenten nebeneinander anordnen fenster.setLayout(new FlowLayout()); // → String-Array Hamster-Befehle String[] Befehle = {"vor", "links", "rechts", "zur Wand" }; // neues Objekt von JComboBox erzeugen hamsterBefehle = new JComboBox(); // mit → for each JComboBox "bauen" for (String eintrag : Befehle) { hamsterBefehle.addItem(eintrag); } // neues Objekt von JButton erzeugen beendeProgrammButton = new JButton("Programm beenden"); beendeProgrammButton.setBackground(Color.red); // Elemente hinzufügen fenster.add(beendeProgrammButton); fenster.add(hamsterBefehle); // ActionListener hinzufügen beendeProgrammButton.addActionListener(new MausklickAbfragen(paul)); hamsterBefehle.addActionListener(new MausklickAbfragen(paul)); // Frame platzieren -> 100 Pixel von links/200 Pixel von oben fenster.setLocation(100, 100); fenster.setSize(300, 250); /* Fenstergröße automatisch anpassen Alternative: fenster.setSize(Breite, Hoehe); */ fenster.pack(); // Fenster sichtbar machen fenster.setVisible(true); }
Grundlagen:
→ import, → Swing-Bibliothek,
→ ActionListener
Mit JLabel wird ein Hinweisfeld erzeugt.
// Pakete importieren import java.awt.FlowLayout; import java.awt.Color; import javax.swing.JLabel; import javax.swing.JFrame; // globale Variablen JLabel textHamster; void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // neues Frame-Objekt erzeugen JFrame fenster = new JFrame("Beispiel JLabel"); /* Verhalten des Fensters beim Klicken auf X festlegen JFrame.EXIT_ON_ CLOSE -> Programm wird beendet JFrame.DO_NOTHING_ON_CLOSE -> nichts tun JFrame.DISPOSE_ON_CLOSE -> nur das aktuelle Fenster wird geschlossen */ fenster.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); fenster.setLayout(new FlowLayout()); // JLabel definieren textHamster = new JLabel("Java-Hamster"); textHamster.setBackground(Color.yellow); textHamster.setOpaque(true); // Label anzeigen fenster.add(textHamster); // Frame platzieren -> 100 Pixel von links/200 Pixel von oben fenster.setLocation(100, 200); fenster.setSize(200, 80); // Fenster sichtbar machen fenster.setVisible(true); }
Grundlagen:
→ import, → Swing-Bibliothek,
→ JTextArea, → contains
import javax.swing.JFrame; import javax.swing.JTextArea; import javax.swing.JScrollPane; // globale Variable JTextArea tasteGedrueckt; JScrollPane bildLauf; void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); String textEingabe = ""; JFrame fenster = new JFrame("Beispiel Scrollbalken"); tasteGedrueckt = new JTextArea(8, 20); fenster.add(tasteGedrueckt); // der JTextArea tasteGedrueckt einen Scrollbalken hinzufügen JScrollPane bildLauf = new JScrollPane (tasteGedrueckt); fenster.add(bildLauf); // Fensterposition fenster.setLocation(100, 200); // Fenstergröße festlegen fenster.setSize(250, 250); fenster.pack(); fenster.setVisible(true); // while läuft solange bis ende == true boolean ende = false; while (!ende) { textEingabe = textEingabe + paul.liesZeichenkette(" x = Ende") + "\n"; tasteGedrueckt.setText(textEingabe); if (textEingabe.contains("x")) ende = true; } System.exit(0); }
Grundlagen:
→ import, → Swing-Bibliothek,
→ contains,
→ System.exit(0), → ActionListener
Eine JTextArea ist ein mehrzeiliges Textfeld.
Im Beispiel werden mit Hilfe von → liesZeichenkette dem Textfeld solange Wörter oder Sätze hinzugefügt, bis "x" eingegeben wird.
import javax.swing.JFrame; import javax.swing.JTextArea; // globale Variable JTextArea tasteGedrueckt; Hamster paul = new Hamster(0, 0, Hamster.OST, 0); void main() { String textEingabe = ""; JFrame fenster = new JFrame("Beispiel TextArea"); tasteGedrueckt = new JTextArea(15, 20); fenster.add(tasteGedrueckt); // Fensterposition fenster.setLocation(100, 200); // Fenstergröße festlegen fenster.setSize(250, 250); fenster.pack(); fenster.setVisible(true); boolean ende = false; while (!ende) { textEingabe = textEingabe + paul.liesZeichenkette(" x = Ende") + "\n"; tasteGedrueckt.setText(textEingabe); if (textEingabe.contains("x")) ende = true; } System.exit(0); }
Grundlagen:
→ import, → Swing-Bibliothek,
→ ActionListener
Ein JTtextField fügt ein Eingabefeld für eine einzelne Textzeile hinzu..
import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JTextField; import javax.swing.JFrame; // globale Variable JTextField schritte; class SchritteGehen implements ActionListener { Hamster paul; SchritteGehen(Hamster neuerHamster) { paul = neuerHamster; } public void actionPerformed(ActionEvent mausKlick) { /* getSource() -> Quelle ermitteln TextField schritte abfragen ausführen mit return */ if (mausKlick.getSource() == schritte) { String anzahlSchritte = schritte.getText(); int schritte = Integer.parseInt(anzahlSchritte); while (schritte > 0) { paul.vor(); schritte --; } } } } void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // neues Objekt JFrame erzeugen JFrame fenster = new JFrame("Hamster-Schritte"); /* Verhalten des Fensters beim Klicken auf X festlegen JFrame.EXIT_ON_ CLOSE -> Programm wird beendet JFrame.DO_NOTHING_ON_CLOSE -> nichts tun JFrame.DISPOSE_ON_CLOSE -> nur das aktuelle Fenster wird geschlossen */ fenster.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // setLayout(new FlowLayout() -> alle Komponenten nebeneinander anordnen fenster.setLayout(new FlowLayout()); // neues Objekt von JTextField erzeugen schritte = new JTextField(10); fenster.add(schritte); // ActionListener hinzufügen schritte.addActionListener(new SchritteGehen(paul)); // Frame platzieren -> 100 Pixel von links/200 Pixel von oben fenster.setLocation(100, 200); /* Fenstergröße automatisch anpassen Alternative: fenster.setSize(Breite, Hoehe); */ fenster.pack(); // Fenster sichtbar machen fenster.setVisible(true); }
Siehe auch:
→ JTextArea
Im Beipielprogramm soll der Hamster durch Drücken eines → Buttons
die Befehle vor() und linksUm() ausführen.
Das Programm muss wissen, auf welchem Element (Button) ein Ereignis ausgelöst werden soll und wie die "Reaktion" dann aussehen soll.
Es werden drei Möglichkeiten dargestellt:
→ getActionCommand()
→ getSource()
→ MouseListener
setActionCommand() legt ein Kommando fest, auf das der ActionListener "hört".
import java.awt.event.ActionEvent; import java.awt.event.ActionListener;
vorButton.setActionCommand("vor"); linksUmButton.setActionCommand("links"); vorButton.addActionListener(new MausklickAbfragen(paul)); linksUmButton.addActionListener(new MausklickAbfragen(paul));
class MausklickAbfragen implements ActionListener { Hamster paul; MausklickAbfragen(Hamster neuerHamster) { paul = neuerHamster; } public void actionPerformed(ActionEvent mausKlick) { if (mausKlick.getActionCommand().equals("vor")) { if (paul.vornFrei()) paul.vor(); } if (mausKlick.getActionCommand().equals("links")) { paul.linksUm(); } } }
import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; // globale Variablen JButton vorButton; JButton linksUmButton; class MausklickAbfragen implements ActionListener { Hamster paul; MausklickAbfragen(Hamster neuerHamster) { paul = neuerHamster; } public void actionPerformed(ActionEvent mausKlick) { // Abfrage ActionCommand if (mausKlick.getActionCommand().equals("vor")) { if(paul.vornFrei()) paul.vor(); } if (mausKlick.getActionCommand().equals("links")) paul.linksUm(); } } void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // neues Frame-Objekt erzeugen JFrame fenster = new JFrame("Hamster-Steuerung"); /* Verhalten des Fensters beim Klicken auf X festlegen JFrame.EXIT_ON_ CLOSE -> Programm wird beendet JFrame.DO_NOTHING_ON_CLOSE -> nichts tun JFrame.DISPOSE_ON_CLOSE -> nur das aktuelle Fenster wird geschlossen */ fenster.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); fenster.setLayout(new FlowLayout()); // JButtons erzeugen vorButton = new JButton("vor"); linksUmButton = new JButton("links"); // Buttons anzeigen fenster.add(vorButton); fenster.add(linksUmButton); /* ActionsCommand hinzufügen sie werden im ActionsListenr abgefragt */ vorButton.setActionCommand("vor"); linksUmButton.setActionCommand("links"); // ActionListener hinzufügen linksUmButton.addActionListener(new MausklickAbfragen(paul)); vorButton.addActionListener(new MausklickAbfragen(paul)); // Frame platzieren -> 100 Pixel von links/200 Pixel von oben fenster.setLocation(100, 200); /* Fenstergröße automatisch anpassen Alternative: fenster.setSize(Breite, Hoehe); */ fenster.pack(); // Fenster sichtbar machen fenster.setVisible(true); }
getSource() ermittelt den Namen des gedrückten Buttons und führt die entsprechende Aktion aus.
import java.awt.event.ActionEvent; import java.awt.event.ActionListener;
// ActionListener hinzufügen linksUmButton.addActionListener(new MausklickAbfragen(paul)); vorButton.addActionListener(new MausklickAbfragen(paul));
class MausklickAbfragen implements ActionListener { Hamster paul; MausklickAbfragen(Hamster neuerHamster) { paul = neuerHamster; } public void actionPerformed(ActionEvent mausKlick) { // getSource() -> Quelle ermitteln // Button linksUmButton abfragen if (mausKlick.getSource() == linksUmButton) { paul.linksUm(); } // Button vorButton abfragen if (mausKlick.getSource() == vorButton) { if (paul.vornFrei()) paul.vor(); } } }
import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; // globale Variablen JButton linksUmButton; JButton vorButton; class MausklickAbfragen implements ActionListener { Hamster paul; MausklickAbfragen(Hamster neuerHamster) { paul = neuerHamster; } public void actionPerformed(ActionEvent mausKlick) { // getSource() -> Quelle ermitteln // Button linksUmButton abfragen if (mausKlick.getSource() == linksUmButton) { paul.linksUm(); } // Button vorButton abfragen if (mausKlick.getSource() == vorButton) { if (paul.vornFrei()) paul.vor(); } } } void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // neues Frame-Objekt erzeugen JFrame fenster = new JFrame("Hamster-Steuerung"); /* Verhalten des Fensters beim Klicken auf X festlegen JFrame.EXIT_ON_ CLOSE -> Programm wird beendet JFrame.DO_NOTHING_ON_CLOSE -> nichts tun JFrame.DISPOSE_ON_CLOSE -> nur das aktuelle Fenster wird geschlossen */ fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // setLayout(new FlowLayout() -> alle Komponenten nebeneinander anordnen fenster.setLayout(new FlowLayout()); // JButtons erzeugen vorButton = new JButton("vor"); linksUmButton = new JButton("linksUm"); // ActionListener hinzufügen linksUmButton.addActionListener(new MausklickAbfragen(paul)); vorButton.addActionListener(new MausklickAbfragen(paul)); // Buttons anzeigen fenster.add(vorButton); fenster.add(linksUmButton); // Frame platzieren -> 100 Pixel von links/200 Pixel von oben fenster.setLocation(100, 200); /* Fenstergröße automatisch anpassen Alternative: fenster.setSize(Breite, Hoehe); */ fenster.pack(); // Fenster sichtbar machen fenster.setVisible(true); }
Der MouseListener kann auf alle Mausereignisse reagieren:
Alle Methoden von MouseListener müssen überschrieben werden, auch dann wenn sie nicht verwendet werden!
import java.awt.event.MouseEvent; import java.awt.event.MouseListener;
vorButton.addMouseListener(new MausBewegungAbfragen(paul)); linksUmButton.addMouseListener(new MausBewegungAbfragen(paul));
class MausBewegungAbfragen implements MouseListener { Hamster paul; MausBewegungAbfragen(Hamster neuerHamster) { paul = neuerHamster; } public void mouseClicked(MouseEvent mausAktion) { if (mausAktion.getSource() == vorButton) { if (paul.vornFrei()) paul.vor(); } if (mausAktion.getSource() == linksUmButton) { paul.linksUm(); } } // nicht verwendete Methoden überchreiben public void mouseEntered(MouseEvent mausAktion){} public void mouseExited(MouseEvent mausAktion){} public void mousePressed(MouseEvent mausAktion){} public void mouseReleased(MouseEvent mausAktion){} }
import java.awt.FlowLayout; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.JButton; import javax.swing.JFrame; // globale Variablen JButton vorButton; JButton linksUmButton; class MausBewegungAbfragen implements MouseListener { Hamster paul; MausBewegungAbfragen(Hamster neuerHamster) { paul = neuerHamster; } /* alle Methoden von MouseListener müssen ueberschrieben werden: mousePressed, mouseClicked, mouseExited, mouseReleased, mouseEntered */ public void mousePressed(MouseEvent mausAktion){} public void mouseExited(MouseEvent mausAktion){} public void mouseReleased(MouseEvent mausAktion){} public void mouseEntered(MouseEvent mausIn) {} public void mouseClicked(MouseEvent mausAktion) { // mit getSource() Button vorButton abfragen if (mausAktion.getSource() == vorButton) { if (paul.vornFrei()) paul.vor(); } // mit getSource() Button linksUmButton abfragen if (mausAktion.getSource() == linksUmButton) { paul.linksUm(); } } } void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // neues Frame-Objekt erzeugen JFrame fenster = new JFrame("Hamster-Steuerung"); /* Verhalten des Fensters beim Klicken auf X festlegen JFrame.EXIT_ON_ CLOSE -> Programm wird beendet JFrame.DO_NOTHING_ON_CLOSE -> nichts tun JFrame.DISPOSE_ON_CLOSE -> nur das aktuelle Fenster wird geschlossen */ fenster.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); fenster.setLayout(new FlowLayout()); // JButtons erzeugen vorButton = new JButton("vor"); linksUmButton = new JButton("linksUm"); // Buttons anzeigen fenster.add(vorButton); fenster.add(linksUmButton); // MouseListener hinzufügen vorButton.addMouseListener(new MausBewegungAbfragen(paul)); linksUmButton.addMouseListener(new MausBewegungAbfragen(paul)); // Frame platzieren -> 100 Pixel von links/200 Pixel von oben fenster.setLocation(100, 200); /* Fenstergröße automatisch anpassen Alternative: fenster.setSize(Breite, Hoehe); */ fenster.pack(); // Fenster sichtbar machen fenster.setVisible(true); }
Grundlagen:
→ import, → Swing-Bibliothek,
→ contains,
→ System.exit(0)
setText() schreibt Text in ein JTextField/in eine JTextArea schreiben, getTtext() kann den Text wieder auslesen.
import javax.swing.JFrame; import javax.swing.JTextArea; // globale Variable JTextArea mitteilungsFenster; void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); String textEingabe = ""; JFrame fenster = new JFrame("Beispiel TextArea"); mitteilungsFenster = new JTextArea(15, 20); fenster.add(mitteilungsFenster); // Fensterposition fenster.setLocation(100, 200); // Fenstergröße festlegen fenster.setSize(250, 250); fenster.pack(); fenster.setVisible(true); boolean ende = false; while (!ende) { textEingabe = textEingabe + paul.liesZeichenkette(" x = Ende") + "\n"; // mit setText() Text in mitteilungsFenster schreiben mitteilungsFenster.setText(textEingabe); if (textEingabe.contains("x")) ende = true; } // mit getText() Text aus mitteilungsFenster lesen String text = mitteilungsFenster.getText(); // Leerstellen und x abschneiden text = text.trim(); paul.schreib(text.substring(0, text.length() - 1)); System.exit(0); }
Grundlagen:
→ Swing-Bibliothek, → KeyListener
getKeyCode ermittelt den numerischen Tastencode, getKeyChar bestimmt die gedrückte Taste.
Das Beispiel zeigt alle alphanumerischen Tasten und verschiedene Sondertasten in einem → Textfeld an.
import java.awt.event.KeyListener; import java.awt.event.KeyEvent; import javax.swing.JTextField; import javax.swing.JFrame; // globale Variable JTextField tasteGedrueckt; class TastaturAbfragen implements KeyListener { String infoTaste = ""; public void keyPressed(KeyEvent gedrueckteTaste) { // "normale" Buchstaben abfragen int taste = gedrueckteTaste.getKeyCode(); // Umlaute abfragen char tasteBuchstabe = gedrueckteTaste.getKeyChar(); // Keycode 0 -> Umlaute if (taste == 0) infoTaste = "Taste " + tasteBuchstabe + "\n" ; else if (taste == 8) infoTaste = "Taste: " + taste + " -> backspace\n"; else if (taste == 9) infoTaste = "Taste: " + taste + " -> Tabulator\n"; else if (taste == 10) infoTaste = "Taste: " + taste + " -> return\n"; else if (taste == 17) infoTaste = "Taste: " + taste + " -> strg\n"; else if (taste == 27) infoTaste = "Taste: " + taste + " -> ESC\n"; else if (taste == 32) infoTaste = "Taste: " + taste + " -> Leertaste\n"; else if (taste == 34) infoTaste = "Taste: " + taste + " -> Bild unten\n"; else if (taste == 35) infoTaste = "Taste: " + taste + " -> Ende\n"; else if (taste == 36) infoTaste = "Taste: " + taste + " -> Pos 1\n"; else if (taste == 10) infoTaste = "Taste: " + taste + " -> return\n"; else if (taste == 37) infoTaste = "Taste: " + taste + " -> Cursor links\n"; else if (taste == 38) infoTaste = "Taste: " + taste + " -> Cursor oben\n"; else if (taste == 39) infoTaste = "Taste: " + taste + " -> Cursor rechts\n"; else if (taste == 40) infoTaste = "Taste: " + taste + " -> Cursor unten\n"; else if (taste == 127) infoTaste = "Taste: " + taste + " -> Entf\n"; else if (taste == 96 || taste == 155) infoTaste = "Taste: " + taste + " -> Einfg\n"; else infoTaste = "Taste: " + taste + " -> " + "\n" ; tasteGedrueckt.setText(infoTaste); tasteGedrueckt.requestFocus(); } // überschriebene Methoden des KeyListener public void keyReleased(KeyEvent gedrueckteTaste) {} public void keyTyped(KeyEvent gedrueckteTaste) {} } void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // KeyListener hinzufügen tasteGedrueckt = new JTextField(20); JFrame fenster = new JFrame("Taste anzeigen"); fenster.add(tasteGedrueckt); // Fensterposition fenster.setLocation(100, 200); // Fenstergröße festlegen fenster.setSize(250, 250); fenster.pack(); fenster.setVisible(true); tasteGedrueckt.addKeyListener(new TastaturAbfragen()); }
Siehe auch:
→ KeyListenerDie get-/set-Methode dient dazu, Variablen vom Typ → int, → String oder ein Hamster-→ Subobjekt außerhalb einer Klasse zu speichern (set) oder den gespeicherten Wert zu holen (get).
Grundlage:
→ Subobjekt.
Der faule Hamster willi schickt seine Knechte paul und james los. Sie sollen die Körner in den beiden Ecken des Territoriums einsammeln und anschließend mitteilen, wie viele Körner sie insgesamt gesammelt haben.
class FaulerHamster extends Hamster { // Subobjekt definieren Hamster knecht; int anzahlKoerner; // Konstruktor FaulerHamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } // der übergebene Hamster wird zum Knecht void setKnecht(Hamster neuerKnecht) { this.knecht = neuerKnecht; } // Wert für anzahlKoerner speichern void setGefresseneKoerner(int anzahlKoerner) { this.anzahlKoerner = anzahlKoerner; } // aktuellen Wert für anzahlKoerner holen int getGefresseneKoerner() { return anzahlKoerner; } void rechtsUm() { this.knecht.linksUm(); this.knecht.linksUm(); this.knecht.linksUm(); } void gibAlle() { while(!this.knecht.maulLeer()) { this.knecht.gib(); } } void kehrt() { this.knecht.linksUm(); this.knecht.linksUm(); } int nimmAlle() { int gesammelteKoerner = 0; while(this.knecht.kornDa()) { this.knecht.nimm(); gesammelteKoerner = gesammelteKoerner + 1; } return gesammelteKoerner; } void laufeBisZurWand() { while(this.knecht.vornFrei()) this.knecht.vor(); } } void main() { FaulerHamster willi = new FaulerHamster(0, 0, Hamster.OST, 0); Hamster james = new Hamster(0, 0, Hamster.OST, 0); // willi lässt James Körner einsammeln willi.setKnecht(james); willi.laufeBisZurWand(); int gefresseneKoerner = willi.nimmAlle(); // Anzahl der Körner setzen willi.setGefresseneKoerner(gefresseneKoerner); willi.kehrt(); willi.laufeBisZurWand(); willi.gibAlle(); Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // willi lässt paul Körner einsammeln willi.setKnecht(paul); willi.rechtsUm(); willi.laufeBisZurWand(); gefresseneKoerner = willi.nimmAlle(); willi.kehrt(); willi.laufeBisZurWand(); willi.gibAlle(); // willi.getGefresseneKoerner() + gefresseneKoerner -> berechnet die Gesamtanzahl der gefressenen Körner willi.schreib("Insgesamt " + (willi.getGefresseneKoerner() + gefresseneKoerner) + " K\u00F6rner gefressen!"); }
Grundlagen:
→ import, → JButton,
→ ActionListener.
Der erste Hamster gibt die zufällige Anzahl der Schritte vor. Alle anderen Hamster laufen zur gleichen Spalte.
// Pakete importieren import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import java.util.Random; // globale Variablen int anzahlHamster = 4; int anzahlSchritte; int zaehlerHamster; JButton schritteGehenButton; // Array initialisieren Hamster[] rennHamster = new Hamster[anzahlHamster]; // aktuellen Wert für zaehlerHamster holen int getZaehler() { return zaehlerHamster; } // zaehlerHamster um 1 erhöhen void setZaehler(int zaehlerHamster) { if (zaehlerHamster < rennHamster.length) { zaehlerHamster ++; this.zaehlerHamster = zaehlerHamster; } if (zaehlerHamster == rennHamster.length) System.exit(0); } // gespeicherten Wert für anzahlSchritte abrufen int getAnzahlSchritte() { return anzahlSchritte; } // Wert für anzahlSchritte speichern void setAnzahlSchritte(int anzahlSchritte) { this.anzahlSchritte = anzahlSchritte; } // Zufallszahl im Bereich 1-6 bestimmen class Zufall { int zufallsZahl(int minZahl, int maxZahl) { Random zufall = new Random(); return zufall.nextInt(maxZahl + 1) + minZahl; } } class MausklickAbfragen implements ActionListener { public void actionPerformed(ActionEvent mausKlick) { // Button schritteGehenButton abfragen if (schritteGehenButton == mausKlick.getSource()) { // gespeicherten Wert für zaehlerHamster holen zaehlerHamster = getZaehler(); // gespeicherten Wert für anzahlSchritte holen anzahlSchritte = getAnzahlSchritte(); int schrittZaehler = 0; while (schrittZaehler < anzahlSchritte) { if (rennHamster[zaehlerHamster].vornFrei()) rennHamster[zaehlerHamster].vor(); schrittZaehler = schrittZaehler + 1; } // nächster Hamster -> zaehlerHamster um 1 erhöhen setZaehler(zaehlerHamster); } } } void main() { for (int zaehler = 0; zaehler < anzahlHamster; zaehler ++) { rennHamster[zaehler] = new Hamster(zaehler, 0, Hamster.OST, 0); } // neues Objekt der Klasse Zufall erzeugen Zufall zahl = new Zufall(); // Aufruf der Funktion zufallsZahl der Klasse Zufall int anzahlSchritte = zahl.zufallsZahl(1, 6); // Wert für anzahlSchritte speichern setAnzahlSchritte(anzahlSchritte); // neues Objekt JFrame erzeugen JFrame fenster = new JFrame("Hamster-Rennen"); /* Verhalten des Fensters beim Klicken auf X festlegen JFrame.EXIT_ON_ CLOSE -> Programm wird beendet JFrame.DO_NOTHING_ON_CLOSE -> nichts tun JFrame.DISPOSE_ON_CLOSE -> nur das aktuelle Fenster wird geschlossen */ fenster.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); fenster.setLayout(new FlowLayout()); schritteGehenButton = new JButton("N\u00E4chster Hamster"); fenster.add(schritteGehenButton); schritteGehenButton.addActionListener(new MausklickAbfragen()); fenster.setLocation(100, 200); fenster.pack(); fenster.setVisible(true); }
Neben den → Hamster-Klassen gibt es noch ein allgemeineres Klassenkonzept.
Der Quellcode wird in einer eigenen Datei untergebracht.
Diese Klassen werden Top-Level-Klassen genannt.
class Zufall { int zufallsZahl(int maxZahl) { return (int)(Math.random() * maxZahl); } }
Die Klasse Zufall ermittelt eine Zufallszahl.
Sie unterscheidet sich von einer normalen Hamsterklasse:
Nachdem ein → Objekt der Klasse erzeugt wurde, kann sie im Hauptprogramm verwendet werden:
void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // neues Objekt der Klasse Zufall erzeugen Zufall wuerfeln = new Zufall(); int gewuerfelteZahl = wuerfeln.zufallsZahl(7); paul.schreib(String.valueOf(gewuerfelteZahl)); }
class Zufall { int zufallsZahl(int maxZahl) { return (int)(Math.random() * maxZahl); } }
class ZahlFormat { String zahlFormat(String zahlString) { int zaehlerStelle = 1; String formatierteZahl = ""; String ausgabeZahl = ""; // nur Zahlen mit mehr als 3 Stellen berücksichtigen if (zahlString.length() > 3) { // Zahl in Dezimalschreibweise formatieren for (int zaehler = zahlString.length(); zaehler > 0;zaehler --) { formatierteZahl = formatierteZahl + zahlString.substring(zaehler - 1, zaehler); zaehlerStelle ++; // nach 3 Stellen ein Punkt if (zaehlerStelle>3) { zaehlerStelle = 1; formatierteZahl = formatierteZahl + "."; } } } // Zahl hat maximal 3 Stellen else ausgabeZahl = zahlString; // letztes Zeichen ist ein Punkt if (formatierteZahl.endsWith(".")) { formatierteZahl = formatierteZahl.substring(0, formatierteZahl.length()-1); } // Zahl von hinten nach vorne lesen for (int zaehler = formatierteZahl.length(); zaehler > 0; zaehler --) { ausgabeZahl = ausgabeZahl + formatierteZahl.substring(zaehler - 1, zaehler); } return ausgabeZahl; } }
void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // maximale Zufallszahl bestimmen int maxZahl = 100000; // neues Objekt der Klasse Zufall erzeugen Zufall zahl = new Zufall(); // neues Objekt der Klasse ZahlFormat erzeugen ZahlFormat zahlString = new ZahlFormat(); // Funktion zufallsZahl der Klasse Zufall aufrufen int zahlErmitteln = zahl.zufallsZahl(maxZahl); // Funktion zahlFormat der Klasse ZahlFormat aufrufen String ausgabeZahl = zahlString.zahlFormat(String.valueOf(zahlErmitteln)); paul.schreib(ausgabeZahl); }
class Position { int reihe; int spalte; Position(int rWert, int sWert) { reihe = rWert; spalte = sWert; } int getSpalte() { return this.spalte; } int getReihe() { return this.reihe; } }
Die Klasse Position unterscheidet sich von einer normalen Hamsterklasse:
Die Klasse Position wird im Hauptprogramm verwendet:
void main() { // neue Objekte der Klasse Position erzeugen Position pos1 = new Position(0, 0); Position pos2 = new Position(1, 1); // paul und willi auf die entsprechenden Position setzen (pos1 -> paul, pos2 -> willi) Hamster paul = new Hamster(pos1.getReihe(), pos1.getSpalte(), Hamster.OST, 0); Hamster willi = new Hamster(pos2.getReihe(), pos2.getSpalte(), Hamster.OST, 0); paul.vor(); willi.vor(); }
Die Klassen und das Programm müssen im gleichen Ordner abgespeichert werden!
Siehe auch:
→ innere Klasse// das ist ein Kommentar für eine Zeile /* das ist ein Kommentar für mehrere Zeilen */
Kompilieren ist der Vorgang, in dem ein Programm in Maschinencode (die Sprache, die der Prozessor versteht) übersetzt wird.
Im Editor findest du den Menüpunkt kompilieren Ist dein Programm fehlerlos geschrieben, siehst du ein Fenster mit der Meldung Kompilierung erfolgreich. Ansonsten musst du auf → Fehlersuche gehen.
Innerhalb einer → Klasse kann ein besonderes Attribut erzeugt werden, das einen konstanten Wert erhält.
static final int MAXZAHL = 6;
Es ist üblich Konstante in Großbuchstaben zu notieren.
Der Versuch den Wert einer Konstanten zu verändern führt zu einer Fehlermeldung.
MAXZAHL = 7;
cannot assign a value to final variable MAXZAHL
Wenn du eine eigene → Hamster-Klasse definiert hast, musst du den neuen Hamster in deinem Programm → "initialisieren".
AllesKoennerHamster willi = new AllesKoennerHamster(); willi.init (0, 0, Hamster.OST, 0);
Diesen Schritt kannst du vereinfachen:
Lege in der Klasse AllesKoennerHamster einen gleichnamigen Hamster an, dem du die Werte für die Position (Reihe/Spalte), die Blickrichtung und die Anzahl der Körner mitgibst.
Im nächsten Schritt wird dieser Hamster mit → this initialisiert und gilt damit für beliebige Hamster der Klasse AllesKoennerHamster.
class AllesKoennerHamster extends Hamster { AllesKoennerHamster(int reihe, int spalte, int blickrichtung, int koerner) { this.init(reihe, spalte, blickrichtung, koerner); } }Das Hauptprogramm
Hier musst du nur noch den neuen Hamster erzeugen, die Initialisierung fällt weg.
void main() { AllesKoennerHamster willi = new AllesKoennerHamster(0,0,Hamster.OST,0); }
Konstruktoren können nicht vererbt werden. Deshalb solltest du in der neuen Klasse ebenfalls einen Konstruktor definieren und ausdrücklich in einer abgeleiteten Klasse mit super den Konstruktor der Oberklasse aufrufen.
class AllesKoennerHamster extends Hamster { AllesKoennerHamster(int reihe, int spalte, int blickrichtung, int koerner) { this.init(reihe, spalte, blickrichtung, koerner); } }
class StaffelHamster extends AllesKoennerHamster { StaffelHamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } }
Im Hauptprogramm wird der Hamster mit Hilfe des Konstruktors definiert:
void main() { StaffelHamster willi = new StaffelHamster(3, 0, Hamster.OST, 0); }
Für → Subobjekte gilt dies ebenso:
class StaffelHamster extends AllesKoennerHamster { StaffelHamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } StaffelHamster laeufer; // Der "Kindhamster" wird auf die gleiche Position wie der "Elternhamster" gesetzt this.laeufer = new StaffelHamster(this.getReihe(), this.getSpalte(), Hamster.OST, 0); }
Siehe auch:
→ super, → extendsUnter Java-ProgrammiererInnen haben sich Konventionen für die Namen von → Prozeduren, → Methoden, → Funktionen → Variablen, → Interfaces und → Klassen eingebürgert.
void stufeHoch() int anzahlKoerner()
int anzahlSchritte = 0; boolean rechtsFrei = true; String antwortSatz = "";
class StufeHochHamster class LaufeUndSammelHamster
Die Bezeichner sollten möglichst aussagekräftig sein und nur aus Buchstaben bestehen.
Umlaute (ä, ö, ü und ß) und Leerzeichen sind nicht erlaubt!
length() ermittelt die Länge einer Zeichenkette.
void main() { String text = "Java-Hamster"; int anzahlZeichen = text.length(); schreib(" " + anzahlZeichen); // oder statt der Verkettung Ausgabe mit → String.valueOf() schreib(String.valueOf(anzahlZeichen)); }
length ermittelt wie viele Elemente ein → Array enthält.
void main() { String [] buchstaben = {"A","B","C","D"}; int anzahlElemente = buchstaben.length; schreib(" " + anzahlElemente); // oder statt der Verkettung Ausgabe mit → String.valueOf() schreib(String.valueOf(anzahlElemente)); }
Dem Hamster kann mit liesZahl() der Wert einer Variable vom Typ → int mitgeteilt werden.
void main() { int schritte = liesZahl("Wie viele Schritte?"); }
Siehe auch:
→ liesZeichenkette()Dem Hamster kann mit liesZeichenkette() der Wert einer Variable vom Typ → String mitgeteilt werden.
void main() { String antwort = liesZeichenkette("Einen Schritt vorgehen (j/n)?"); if (antwort.equals("j")) vor(); } }Siehe auch: → liesZahl()
Ähnlich wie die → Vergleichsoperatoren stellen die logischen Operatoren die Abhängigkeit zweier Bedingungen fest.
Operator | Symbol | Beschreibung |
---|---|---|
und | && | liefert wahr, wenn beide Bedingungen erfüllt sind |
oder | || AltGr + < |
liefert wahr, wenn eine der beiden Bedingungen erfüllt ist |
Der Hamster stellt fest, ob vorne frei ist und ob auf der aktuellen Position ein Korn liegt:
while (vornFrei() && kornDa()) vor();
Wenn nicht vorne frei ist oder auf der aktuellen Position ein Korn liegt, geht der Hamster einen Schritt vor.
void main() { if (!vornFrei() || kornDa()) { linksUm(); linksUm(); } else { vor(); } }
Der Hamster kann auch mathematische Funktionen der Java-Biliothek Math verwenden:
Beachte die anglo-amerikanische Schreibweise: "." statt "."!
double zahl = 2.678; schreib(" " + Math.ceil(zahl));Als Ergebnis wird 3 ermittelt.
double zahl = 2.678; schreib(" " + Math.floor(zahl));Als Ergebnis wird 2 ausgegeben.
int zahl1 = 2; int zahl2 = 5; schreib(" " + Math.max(zahl1, zahl2));
int zahl1 = 2; int zahl2 = 5; schreib(" " + Math.min(zahl1, zahl2));
double zahl = 2.2345; schreib(" " + Math.round(zahl));
int basis = 5; int exponent = 4; int ergebnis = (int) Math.pow(basis, exponent);
double ergebnis = Math.sqrt(15);
Das Überladen von Methoden bedeutet, dass eine Klasse mehrere Methoden gleichen Namens besitzt.
Sie unterscheiden sich in der Anzahl oder dem Typ des Parameters(→ int
oder → boolean).
Im Beispiel werden die Methoden vor() und linksUm() überladen. Es existieren sowohl die hamstereigene Methoden vor() und linksUm() als auch die neuen Methoden
vor(int anzahlSchritte) und linksUm(int anzahlDrehungen)
Handelt es sich um eine Methode der Klasse Hamster (in diesem Fall vor() und linksUm()) muss das Schlüsselwort → public vorangestellt werden!
public void vor(int anzahlSchritte) { while (this.vornFrei() && anzahlSchritte > 0) { this.vor(); anzahlSchritte = anzahlSchritte - 1; } } public void linksUm(int anzahlDrehungen) { while (anzahlDrehungen > 0) { this.linksUm(); anzahlDrehungen = anzahlDrehungen - 1; } }
void main() { AllesKoennerHamster willi = new AllesKoennerHamster(0, 1, Hamster.OST, 0); willi.vor(5); willi.linksUm(2); willi.vor(5); }
Grundlage:
→ Klasse Hamster.
Der Befehl:
Hamster paul = new Hamster();
erzeugt einen neuen Hamster mit dem Namen paul. Die Anweisung darf an beliebiger Stelle im Programm stehen.
Anschließend muss der Hamster "initialisiert" werden:
paul.init(0, 0, Hamster.OST, 0);
Der Standard-Hamster ist immer in blau dargestellt. Wenn du weitere Hamster erzeugst, erhalten diese zur Unterscheidung andere Farben:
Der neu erzeugte Hamster bekommt noch seinen Standort, die Blickrichtung und die Anzahl der Körner, die er im Maul hat, mit auf den Weg:
Als Blickrichtung kannst du NORD, SUED, OST und WEST festlegen.
void main() { Hamster paul = new Hamster(); paul.init(0, 0, Hamster.OST, 0); Hamster karin = new Hamster(); karin.init(0, 4, Hamster.WEST, 0); Hamster gerda = new Hamster(); gerda.init(3, 0, Hamster.OST, 0); Hamster gerd = new Hamster(); gerd.init(3, 4, Hamster.WEST, 0); }
Jedem Befehl muss der Name des → Objektes (des Hamsters) vorangestellt werden:
void main() { Hamster paul = new Hamster(); paul.init(0, 0, Hamster.OST, 0); Hamster karin = new Hamster(); karin.init(0, 4, Hamster.WEST, 0); while (paul.vornFrei()) paul.vor(); while (karin.vornFrei()) karin.vor(); }
Du musst → objektorientierte Programme schreiben!
Siehe auch:
→ Objekteimperatives Programm | objektorientiertes Programm |
---|
Wähle mit dem Icon neu als Typ des Programms Klasse aus.
Ersetze die Bezeichnung MeinHamster durch AllesKoennerHamster.
In den → Prozeduren und → int-Funktionen
muss das Schlüsselwort → this verwendet werden.
void rechtsUm() { this.linksUm(); this.linksUm(); this.linksUm(); }
int bisZurMauer() { int anzahl = 0; while (this.vornFrei()) { this.vor(); anzahl = anzahl + 1; } return anzahl; }
void schritteVor(int anzahlSchritte) { int schrittZaehler = 0; while (schrittZaehler < anzahlSchritte) { if (this.vornFrei()) this.vor(); schrittZaehler = schrittZaehler + 1; } }
Für den Datentyp Hamster und alle von ihm abgeleiteten Klassen existiert die Zuweisung null.
Es drückt aus, dass einem bestimmten Hamster-Namen aktuell kein Hamster zugeordnet wird.
void main() { // dem Hamster-Namen paul wird kein Hamster zugeordnet Hamster paul = null; Hamster willi = new Hamster(); willi.init(0, 0, Hamster.OST, 2); // paul übernimmt den aktuellen Status von willi paul = new Hamster(); paul.init(willi.getReihe(), willi.getSpalte(), willi.getBlickrichtung(), willi.getAnzahlKoerner()); // willi "stirbt" willi = null; paul.vor(); willi.vor(); }
Für den Compiler ist das Programm in Ordnung. Die Ausführung zeigt aber einen Laufzeitfehler ...
... weil die Anweisung
willi.vor();
nicht mehr ausgeführt werden kann, da willi nicht mehr existiert.
Java ist eine sogenannte "objektorientierte Sprache". Sie definiert Klassen, in der zu einer Problemstellung verschiedene Teillösungen zusammengefasst werden können.
Der Zugriff auf die Klasse erfolgt mit dem Schlüsselwort new.
class Zufall { int zufallsZahl(int maxZahl) { return (int)(Math.random() * maxZahl); } }
void main() { AllesKoennerHamster paul = new AllesKoennerHamster(0, 0, Hamster.OST, 0); Zufall wuerfeln = new Zufall; // Methode zufallsZahl aufrufen int gewuerfelteZahl = wuerfeln.zufallsZahl(7); paul.schreib(String.valueOf(gewuerfelteZahl)); }
// ArrayRueckwaertsLesen kehrt die Reihenfolge eines Array (buchstaben) um class ArrayRueckwaertsLesen { String StringAusgabe(String buchstaben[]) { String buchstabenString = ""; for (int zaehler = buchstaben.length - 1; zaehler >= 0; zaehler --) { buchstabenString = buchstabenString + buchstaben[zaehler]; } return buchstabenString; } }
void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // Array erstellen String[] buchstaben = {"F","E","D","C","B","A"}; // neues Objekt ArrayRueckwaertsLesen erzeugen ArrayRueckwaertsLesen lesen = new ArrayRueckwaertsLesen(); // Reihenfolge der Buchstaben umkehren String buchstabenString = lesen.StringAusgabe(buchstaben); paul.schreib(buchstabenString); }
Bisher waren die Hamster eher passiv:
Sie werden im Programm erzeugt und warten darauf, dass ihnen Befehle erteilt werden. Das Programm gibt den Hamstern vor ...
Im folgenden Programm wird eine → Hamsterklasse LaufeUndSammle definiert, deren Aufgabe
es ist, bis zur nächsten Wand zu laufen und dabei alle Körner einzusammeln.
Die im Hauptprogramm erzeugten Hamster paul und willi sind "passiv", sie starten nicht von alleine und arbeiten ihre Befehle nacheinander ab.
class LaufeUndSammleHamster extends Hamster { LaufeUndSammleHamster(int reihe, int spalte, int blickrichtung, int koerner) { this.init(reihe, spalte, blickrichtung, koerner); } void laufeUndSammle() { while (this.vornFrei()) { while (this.kornDa()) this.nimm(); this.vor(); } } }
void main() { LaufeUndSammleHamster willi = new LaufeUndSammleHamster(0, 0, Hamster.OST, 0); LaufeUndSammleHamster paul = new LaufeUndSammleHamster(1, 0, Hamster.OST, 0); willi.laufeUndSammle(); paul.laufeUndSammle(); }
Damit die Hamster ein Eigenleben führen können, müssen bestimmte Voraussetzungen geschaffen werden:
class SammelHamster extends Hamster { SammelHamster(int reihe, int spalte, int blickrichtung, int koerner) { this.init(reihe, spalte, blickrichtung, koerner); } // Body public void run() { while (this.vornFrei()) { while (this.kornDa()) this.nimm(); this.vor(); } } }
SammelHamster(int reihe, int spalte, int blickrichtung, int koerner) { this.init(reihe, spalte, blickrichtung, koerner); }
SammelHamster paul = new SammelHamster(0, 0, Hamster.OST, 0); // paul wird aktiviert paul.start();Innerhalb der Methode start() wird für Hamster paul dessen Methode run() aufgerufen. Ein neuer Prozess wird erzeugt und gestartet, der die Methode run() ausführt. Die Methode start() wird parallel dazu weiter geführt.
class SammelHamster extends Hamster { SammelHamster(int reihe, int spalte, int blickrichtung, int koerner) { this.init(reihe, spalte, blickrichtung, koerner); } public void run() { while (this.vornFrei()) { while (this.kornDa()) this.nimm(); this.vor(); } } } void main() { SammelHamster paul = new SammelHamster(0, 0, Hamster.OST, 0); paul.start(); SammelHamster willi = new SammelHamster(1, 0, Hamster.OST, 0); willi.start(); }
Die selbstständigen Hamster werden nie wirklich parallel laufen. Vielmehr entscheidet der Java-Scheduler, in welcher Reihenfolge die Prozesse ablaufen und damit auch darüber, in welcher Reihenfolge die Hamster laufen.
Bisher wurden für Objektevariablen eines Klassendatentyps X Objekte von der Klasse X zugeordnet.
AllesKoennerHamster paul = new AllesKoennerHamster(0, 0, Hamster.OST, 0)
AllesKoennerHamster ist in diesem Fall die Objektvariable, paul das konkret zugeordnete Objekt des Klassendatentyps AllesKoennerHamster.
Objektvariable vom Typ X heißen polymorph, wenn ihnen auch andere Objekte als die der Klasse X zugeordnet werden können.
Das gilt aber nur für direkte oder indirekte Unterklassen.
Die Klasse Kindhamster1 ist ein Unterklasse der Klasse Hamster, die Klasse EnkelHamster1 eine Unterklasse von Kindhamster1.
Der Enkelhamster1 ist ein indirekter "Abkömmling" der Klasse Hamster.
Kindhamster2 ist eine Unterklasse der Klasse Hamster, aber kein "Abkömmling" der Klasse Kindhamster1.
Das Bild verdeutlicht diesen Stammbaum.
Die Klasse Kindhamster1 kennt die Methode kehrt().
class KindHamster1 extends Hamster { KindHamster1(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } void kehrt() { this.linksUm(); this.linksUm(); } }Die Klasse Kindhamster2 kennt die Methode sammle().
class KindHamster2 extends Hamster { KindHamster2(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } void sammle() { while(this.kornDa()) { this.nimm(); } } }Die Klasse EnkelHamster1 kennt die Methode rechtsUm().
class EnkelHamster1 extends KindHamster1 { EnkelHamster1(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } void rechtsUm() { this.kehrt(); this.linksUm(); } }
void main() { // Hamster ist die Oberklasse Hamster paul = new KindHamster1(0, 0, Hamster.OST, 0); // KindHamster1 ist der Abkoemmling der Oberklasse Hamster Hamster willi = new KindHamster2(1, 0, Hamster.OST, 0); // EnkelHamster1 ist der Abkoemmling der Klassen KindHamster1 und Hamster Hamster karin = new EnkelHamster1(1, 0, Hamster.OST, 0); // Fehler: incompatible types // Hamster ist keine Unterklasse der Klasse Kindhamster KindHamster1 karl = new Hamster(1, 0, Hamster.OST, 0); // Fehler: incompatible types // KindHamster1 ist keine Unterklasse der Klasse Kindhamster2 KindHamster1 gisela = new KindHamster2(1, 0, Hamster.OST, 0); }
Die Gesamtheit aller → Attribute und → Methoden einer Klasse (einschließlich aller geerbten), auf die auch von außerhalb der Klassendefinition zugegriffen werden kann, wird als das Protokoll der Klasse X bezeichnet.
Für Objektvariable bedeutet das:
Falls obj eine Objektvariable vom Typ X ist, der ein Objekt der Klasse Y zugeordnet wird (Y ist eine Unterklasse von X), dann kann mittels der Punkt-Schreibweise nur auf diejenigen Komponenten der Klasse Y zugegriffen werden, die auch im Protokoll der Klasse X sind.
Das Protokoll der Klasse Y ist eingeschränkt auf das Protokoll der Klasse X.
class DrehHamster extends Hamster { DrehHamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } void rechtsUm() { this.linksUm(); this.linksUm(); this.linksUm(); } }
void main() { DrehHamster paul = new DrehHamster(0, 0, Hamster.WEST, 0); paul.vor(); paul.rechtsUm(); // polymorphes Objekt: // willi vom Typ Hamster wird als Objekt der Klasse Drehhamster zugeordnet Hamster willi = new DrehHamster(0, 1. Hamster.WEST, 0); willi.vor(); // Fehler: rechtsUm() gehört nicht zum Protokoll der Klasse Hamster willi.rechtsUm(); }
Die Klasse DrehHamster wird von der Klasse Hamster abgeleitet. Das Protokoll der Klasse DrehHamster besteht aus allen Attributen und Methoden der Klassen DrehHamster und Hamster.
paul ist eine Objektvariable der Klasse DrehHamster und ihm wird ein Objekt der Klasse DrehHamster zugeordnet.
Die Aufrufe der Methoden vor() und rechtsUm() sind korrekt, da die Methode vor() zum Protokoll der Klasse Hamster gehört und die Methode rechtsUm() sich im Protokoll der Klasse DrehHamster befindet.
willi ist eine Objektvariable der Klasse Hamster und die Methode rechtsUm() gehört nicht zum Protokoll der Klasse Hamster.
Der Aufruf von vor() ist hingegen korrekt, weil die Methode vor() zum Protokoll der Klasse Hamster gehört.
Siehe auch:
→ Dynamisches Binden
Es kommt oft vor, dass in einem Programm eine Abfolge von Befehlen mehrfach ausgeführt wird.
Diese Abfolge von Anweisungen können dann in einer Prozedur ausgelagert werden.
Eine Prozedur wird mit void NameDerProzedur() eingeleitet.
Beachte die → Konventionen für die Bezeichner von Prozeduren.
Der Hamster soll jeweils bis zum Ende laufen, nach rechts drehen und zum Schluss zum Ausgangspunkt zurückkehren..
void main() { while (vornFrei()) vor(); // wird durch rechtsUm() ersetzt linksUm(); linksUm(); linksUm(); while (vornFrei()) vor(); // wird durch rechtsUm() ersetzt linksUm(); linksUm(); linksUm(); while (vornFrei()) vor(); // wird durch rechtsUm() ersetzt linksUm(); linksUm(); linksUm(); while (vornFrei()) vor(); }
Die farbig markierten Anweisungen werden mehrfach ausgeführt und können jeweils durch eine Prozedur ersetzt werden.
void rechtsUm() { linksUm(); linksUm(); linksUm(); }
void main() { while (vornFrei()) vor(); rechtsUm(); while (vornFrei()) vor(); rechtsUm(); while (vornFrei()) vor(); rechtsUm(); while (vornFrei()) vor(); } void rechtsUm() { linksUm(); linksUm(); linksUm(); }
Die Prozeduren dürfen am Anfang oder am Ende des Programms stehen. Sonderzeichen (ä, ü, ö,ß und Zahlen als erstes Zeichen sind nicht gestattet.
In den runden Klammern des Prozedurnamens kann eine oder mehrere → Variable(n) übergeben werden.
void main() { int anzahlSchritte = 4;
Die Zahl der Schritte wird auf 4 festgelegt.
schritteVor(anzahlSchritte); }
Die → Prozedur schritteVor wird aufgerufen und die Variable anzahlSchritte wird mit dem Wert 4 übergeben.
Die Prozedur schritteVor sorgt mit einer → while-Schleife
und der "Hilfsvariable" schrittZaehler dafür, dass der Hamster 4 Schritte vorwärts geht.
void schritteVor(int anzahlSchritte) { int schrittZaehler = 0; while (schrittZaehler < anzahlSchritte) { if (vornFrei()) vor(); schrittZaehler = schrittZaehler + 1; } }
Im Hauptprogramm kann die Prozedur jetzt aufgerufen werden:
void main() { anzahlSchritte = anzahlSchritte + 1; schritteVor(anzahlSchritte); }Hamster als Variable in einer → Prozedur übergeben
Beim Aufruf einer → Prozedur kann auch der Name eines Hamster übergeben werden:
void main() { Hamster paul = new Hamster(); Hamster karin = new Hamster(); paul.init(4, 0, Hamster.OST, 0); karin.init(6, 0, Hamster.OST, 0); int anzahlSchritte = paul.liesZahl("Wieviele Schritte sollen die Hamster gehen?"); // der Name des Hamster wird als Parameter übergeben schritteVor(anzahlSchritte, paul); schritteVor(anzahlSchritte, karin); } // die Methode schritteVor kann für beliebige Hamster aufgerufen werden void schritteVor(int anzahlSchritte, Hamster hamster) { while (anzahlSchritte > 0) { if (hamster.vornFrei()) hamster.vor(); anzahlSchritte = anzahlSchritte - 1; } }
Siehe auch:
→ Array übergebenGrundlagen:
→ Java-Klassenbibliothek, → import
Die Klasse Random aus der Java-Klassenbibliothek erzeugt Zufallszahlen der Typen → int und
→ double
Zunächst musst du ein neues Objekt der Klasse Random erzeugen:
Random zufall = new Random();
import java.util.Random; void main() { AllesKoennerHamster paul = new AllesKoennerHamster(Hamster.getStandardHamster()); // neuen Zufallsgenerator erzeugen Random zufall = new Random(); // Zufallszahl als double zwischen 0 und 1 erzeugen double zufallsZahlDouble = zufall.nextDouble(); paul.schreib(String.valueOf(zufallsZahlDouble)); // Zufallszahl aus dem // Wertebereich: -2.147.483.648 bis 2.147.483.647 erzeugen int zufallsZahlInt = zufall.nextInt(); paul.schreib(String.valueOf(zufallsZahlInt)); // Zufallszahl aus einem Bereich // hier: 0 bis 10 int zufallsZahlIntBereich = zufall.nextInt(10); paul.schreib(String.valueOf("Zufallszahl zwischen 0 und 10:\n" + zufallsZahlIntBereich)); }
Siehe auch:
→ Math.random()Siehe auch:
→ int-Variable, → MathRekursion ist eine Methode eine → Prozedursolange in sich selbst aufzurufen, bis eine Abbruchbedingung erreicht ist.
void main() { zurMauer(); } void zurMauer() { if (vornFrei()) { vor(); zurMauer(); } }
main | zurMauer (1) | zurMauer (2) | zurMauer (3) |
---|---|---|---|
zurMauer(); |
--> vornFrei() --> true vor() zurMauer(); |
|
|
Der rekursive Aufruf läßt sich durch die Iteration mit → while ersetzen
void main() { while (vornFrei()) { vor(); } }
Siehe auch:
→ Iterationreplace() ersetzt ein einzelnes Zeichen in einem → String.
Im Beispiel wird die anglo-amerikanische Punktschreibweise einer Kommazahl durch einen Komma ersetzt. Außerdem wird die Zahl auf zwei
Nachkommstellen gekürzt (allerdings ohne zu runden!).
void main() { int maxZahl = 6; double zufallsZahl = 0; // Kommazahl per Zufall bestimmen zufallsZahl = (Math.random() * maxZahl + 1); // Double in String umwandeln String stringDouble = Double.toString(zahl); // . durch , ersetzen String neueZahl = stringDouble.replace(".",","); schreib(neueZahl); // auf 2 Nachkommastellen kürzen int index = neueZahl.indexOf(","); neueZahl = neueZahl.substring(0,index) + "," + neueZahl.substring(index + 1,index + 3); schreib(neueZahl); }
Siehe auch:
→ indexOf(), → replaceAll()replaceAll() ist in der Lage, mehrere Zeichen oder Strings in einem Durchlauf zu ersetzen.
Die zu ersetzenden Zeichen müssen in [ ] eingeschlossen werden.
void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); String text = "Drei Chinesen mit dem Kontrabass"; // ersetzt alle Vorkommen von aeiou im String text text = text.replaceAll("[aeiou]","i"); paul.schreib(text); }
void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); String zahlenMitBuchstaben = "1ab2cde3f45AB67CD89EF"; // ersetzt alle Buchstaben String nurZahlen = zahlenMitBuchstaben.replaceAll("[a-zA-Z]", ""); paul.schreib("Zahlen: " + nurZahlen); // ersetzt alle Zahlen String nurBuchstaben = zahlenMitBuchstaben.replaceAll("[0-9]", ""); paul.schreib("Buchstaben: " + nurBuchstaben); }
void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); /* Sonderzeichen eretzen Sonderzeichen müssen mit \\ maskiert werden im Beispiel werden die Zeichen [ ] { } ersetzt */ String stringMitSonderzeichen = "[abc{def}g]"; String stringOhneSonderzeichen = stringMitSonderzeichen.replaceAll("[\\[\\]\\{\\}]",""); paul.schreib(stringMitSonderzeichen + "\n" + stringOhneSonderzeichen); }
return gibt den Wert einer → int-, → boolean- , → String- und → Hamster- Funktion zurück.
boolean linksFrei() { linksUm(); if (vornFrei()) { linksUm(); linksUm(); linksUm(); return true; } else { linksUm(); linksUm(); linksUm(); return false; } }
int schritteBisZurMauer() { int anzahl = 0; while (vornFrei()) { vor(); anzahl = anzahl + 1; } return anzahl; }
void main() { String satz = liesZeichenkette("Gib einen Text ein:"); String neuerSatz = rueckwaertsText(satz); schreib(neuerSatz); // oder kürzer: schreib(rueckwaertsText(satz)); } String rueckwaertsText(String text) { int zaehler = 0; String satz = ""; for (zaehler = text.length(); zaehler > 0; zaehler --) { satz = satz + text.substring(zaehler - 1, zaehler); } return satz; }
Der Hamster kann mit schreib() eine Mitteilung machen:
void main() { String satz = "Java Hamstern ist nicht schwer!"; schreib(satz); }
Siehe auch:
→ Variablentyp umwandeln → liesZahl() → liesZeichenkette() → Variablen verketten → StringDer Hamster kann sein Arbeitsfeld "wahrnehmen". Er kann Hindernisse erkennen und beurteilen, ob auf seiner Position ein Korn liegt.
Siehe auch:
→ VerneinungMit SimpleDateFormat kann ein Datum, das mit der Klasse → Calendar ermittelt wurde, formatiert werden.
import java.text.SimpleDateFormat; import java.util.Calendar; class DatumSimpleDateFormat { String datumErmitteln() { // neues Objekt der Klasse Calendar erzeugen Calendar kalender = Calendar.getInstance(); /* SimpleDateFormat zur Formatierung von Datum und Zeit verwenden dd -> Tag MM -> Monat yyyy -> Jahreszahl 4-stellig HH -> Stunden mm -> Minuten ss -> Sekunden */ SimpleDateFormat datumFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); return datumFormat.format(kalender.getTime()); } }
void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); DatumSimpleDateFormat datumLesen = new DatumSimpleDateFormat(); String datum = datumLesen.datumErmitteln(); paul.schreib(datum); }
Ein → Array kann mit Hilfe des Sortieralgorithmus Bubblesort aufsteigend sortiert werden.
// Array mit Zahlen, die sortiert werden sollen int[] zahlen = {3, 5, 2, 7, 9, 10}; // Zwischenspeicher: die zu tauschende Zahl wird gesichert int tausch = 0; // Die Liste wird von Element 0 bis zum Ende abgefragt for (int anzahlElemente = 0; anzahlElemente < zahlen.length; anzahlElemente++) { // Durchlauf der Liste fuer das jeweilige Elemente for (zaehler = 0; zaehler < zahlen.length - 1; zaehler++ ) { /* ist das aktuelle Element größer als das darauf Folgende? wenn ja: das aktuelle Element wird in der Variablen tausch gesichert anschließend wird das aktuelle Element zahlen[zaehler] mit dem darauf folgenden Element zahlen[zaehler + 1] getauscht zahlen[zaehler] = zahlen[zaehler + 1]; in der Variablen zahlen[zaehler + 1] steht noch der bisherige Wert deshalb wird die gesicherte Variable tausch zahlen[zaehler] zugewiesen */ if (zahlen[zaehler] >= zahlen[zaehler + 1]) { tausch = zahlen[zaehler]; zahlen[zaehler] = zahlen[zaehler + 1]; zahlen[zaehler + 1] = tausch; } } }
Siehe auch:
→ Sortieren von Arrays mit java.util.ArraysDie Java-Klasse java.util.Arrays stellt zwei Methoden zur Verfügung:
import java.util.ArrayList; import java.util.Random; import java.util.Collections; void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); ArrayList<Integer> zahlen = new ArrayList<Integer>(); Random zufall = new Random(); int maxZahl = 20; // Liste mit Zufallszahlen füllen for (int zaehler = 0; zaehler <= maxZahl; zaehler ++) { zahlen.add(zufall.nextInt(maxZahl)); } String alleZahlen = new ArrayList<Integer>(zahlen).toString(); paul.schreib("Noch nicht sortierte Liste: " + alleZahlen); // Liste aufsteigend sortieren Collections.sort(zahlen); alleZahlen = new ArrayList<Integer>(zahlen).toString(); paul.schreib("Liste aufsteigend sortieren: " + alleZahlen); // Liste absteigend sortieren Collections.reverse(zahlen); alleZahlen = new ArrayList<Integer>(zahlen).toString(); paul.schreib("Liste absteigend sortieren: " + alleZahlen); }
Die Java-Klasse java.util.Arrays stellt zwei Methoden zur Verfügung:
import java.util.Arrays; void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); int[] zahlen = new int[]{ 4, 6, 2, 7, 5, 8, 9, 3, 1 }; String[] namen = new String[] {"Karin", "Gerda", "Karl", "Willi", "Paul"}; paul.schreib("Noch nicht sortierte Zahlen: " + Arrays.toString(zahlen)); // Array zahlen wird sortiert Arrays.sort(zahlen); // Array zahlen in String umwandeln paul.schreib("Sortierte Zahlen:" + Arrays.toString(zahlen)); paul.schreib("Noch nicht sortierte Namen: " + Arrays.toString(namen)); // Array namen wird sortiert Arrays.sort(namen); // Array namen in String umwandeln paul.schreib("Sortierte Namen:" + Arrays.toString(namen)); }
Siehe auch:
→ ArrayList sortierenMit dem Menüpunkt Speichern mit Territorium kann das Arbeitsfeld mit dem Programm verknüpft werden.
Neben den → Attributen einer Klasse in Form von Variablen vom Typ boolean oder int, lassen sich auch Attribute vom Typ Hamster oder vom Typ einer → erweiterten Hamsterklasse definieren.
Zwei Hamster laufen aufeinander zu und "erzeugen" Nachwuchs, wenn sie sich treffen.
class KindHamster extends Hamster { // Subobjekt nachwuchs definieren KindHamster nachwuchs; // Konstruktor KindHamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe,spalte, blickrichtung, koerner); } void lauf() { // auf einer Kachel befinden sich zwei Hamster if (Territorium.getAnzahlHamster(this.getReihe(), this.getSpalte()) > 1) { /* es werden zwei nachwuchs-Hamster erzeugt sie werden in der darunterliegenden Zeile platziert */ this.nachwuchs = new KindHamster(this.getReihe() + 1, this.getSpalte() - 1, 0, 0); this.nachwuchs = new KindHamster(this.getReihe() + 1, this.getSpalte() + 1, 0, 0); } this.vor(); } }
void main() { KindHamster paul = new KindHamster(3, 0, Hamster.OST, 0); KindHamster karin = new KindHamster(3, Territorium.getAnzahlSpalten() - 1, Hamster.WEST,0); while (Hamster.getAnzahlHamster() < 5) { paul.lauf(); karin.lauf(); } }
Mit substring() läßt sich aus einem → String ein Teil auslesen.
substring() erwartetet zwei Argumente, die durch Kommata getrennt werden:
void main() { String satz = "Programmieren mit dem Java-Hamster"; String teilString = satz.substring(22,26); schreib(teilString); }
Auch → Strings können mit Hilfe einer Funktion
manipuliert werden. Der veränderte String wird mit
→ return an das Hauptprogramm zurück gegeben.
Das Programm fügt hinter jedem Buchstaben ein Leerzeichen ein und gibt den Text aus:
void main() { String satz = "DreiChinesenmitdemKontrabass"; // Aufruf der Prozedur leerstellenEinfuegen() schreib(leerstellenEinfuegen(satz)); } String leerstellenEinfuegen(String satz) { int zaehler = 0; String stringLeerstellen = ""; for (zaehler = 0; zaehler != satz.length(); zaehler ++) { stringLeerstellen = stringLeerstellen + " " + satz.substring(zaehler,zaehler+1); } return stringLeerstellen; }
Siehe auch:
→ return, → int-Funktion, → boolean-FunktionString.compareTo() stellt fest, ob zwei → Strings identisch sind.
void main() { String passwort = liesZeichenkette("Bitte Passwort eingeben: "); String passwortWiederholen = liesZeichenkette("Bitte Passwort erneut eingeben: "); int vergleich = passwort.compareTo(passwortWiederholen); if (vergleich != 0) { schreib("Die Passwörter stimmen nicht überein!"); } else schreib("Die Passwörter stimmen überein!"); }
Siehe auch:
→ equals(), → contains(),Mit super wird der → Konstruktor der übergeordneten Klasse aufgreufen.
class AllesKoennerHamster extends Hamster { // Konstruktor AllesKoennerHamster(int reihe, int spalte, int blickrichtung, int koerner) { this.init(reihe, spalte, blickrichtung, koerner); } void rechtsUm() { this.kehrUm(); this.linksUm(); } void kehrUm() { this.linksUm(); this.linksUm(); } }
class RechtsUmHamster extends AllesKoennerHamster { /* Konstruktor -> Aufruf von super erforderlich -> ansonsten Fehlermeldung des Compilers bei this.init cannot find symbol constructor AllesKoennerHamster */ RechtsUmHamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } }
Mit → this wird sowohl auf eine lokale Methode/ein lokales Attribut als auch auf ein vererbtes Attribut zugegriffen.
Mit super kann -muss aber nicht- deutlich gemacht werden, dass auf ein vererbtes Attribut zugegriffen wird.
class StufeHochHamster extends Hamster { int zaehleStufe= 0 ; /* -> super: linksUm() und vor() sind geerbte Methoden der "übergeordneten" Klasse Hamster -> this: rechtsUm() - Methode innerhalb der Klasse stufeHochHamster zaehleStufe - Attribut innerhalb der Klasse stufeHochHamster */ void erklimmeStufe() { super.linksUm(); super.vor(); // super ist hier nicht erlaubt: // rechtsUm() ist eine Methode der Klasse StufeHochHamster this.rechtsUm(); super.vor(); // super ist hier nicht erlaubt: // zaehleStufe ist ein Attribut der Klasse StufeHochHamster this.zaehleStufe = this.zaehleStufe + 1; } void rechtsUm() { this.linksUm(); this.linksUm(); this.linksUm(); } } void main() { StufeHochHamster karin = new StufeHochHamster(); karin.init(5,0, Hamster.OST, 0); karin.erklimmeStufe(); }
Siehe auch:
→ this, → erweiterte Hamsterklasse
Die switch...case Abfrage kann sehr komfortabel mehrere Bedingungen abfragen.
Die Variable, die ausgewertet wird muss vom Type → int sein.
Wird keine passende Sprungmarke gefunden, wird die Anweisung hinter default ausgeführt.
break; sorgt dafür, dass die jeweils folgenden case-Anweisungen nicht abgefragt werden.
Die Anzahl der Körner, die auf der Position des Hamsters liegen, bestimmen die Richtung.
switch (anzahlKorn) { case (1): { while (vornFrei()) vor(); break; } case (2): { linksUm(); while (vornFrei()) vor(); break; } case (3): { linksUm(); linksUm(); while (vornFrei()) vor(); break; } default: { vor(); } }
Siehe auch:
→ if ... elseSystem.exit(0) erzwingt ein sofortiges Programmende.
Territorium.getAnzahlSpalten() stellt die Anzahl der Spalten in einem beliebigen Territorium fest, Territorium.getAnzahlReihen() zählt die Reihen eines beliebigen Territoriums.
void main() { AllesKoennerHamster paul = new AllesKoennerHamster(0, 0, Hamster.OST, 0); AllesKoennerHamster karin = new AllesKoennerHamster(Territorium.getAnzahlSpalten() - 1, 0, Hamster.OST, 0); AllesKoennerHamster willi = new AllesKoennerHamster(0,Territorium.getAnzahlReihen() - 1,Hamster.WEST, 0); AllesKoennerHamster heidi = ↵ new AllesKoennerHamster(Territorium.getAnzahlSpalten() - 1, Territorium.getAnzahlReihen() - 1, Hamster.WEST, 0); }
Die Funktion Territorium.getAnzahlKoerner(reihe, spalte) stellt die Anzahl der Körner fest,
die sich auf einer Position befinden.
Die Zählung für reihe und spalte beginnt mit 0!
In der 1. Reihe und der 3. Spalte befinden sich Körner.
Das Programm stellt ihre Anzahl fest.
void main() { int reihe = 0; int spalte = 2; int koerner = Territorium.getAnzahlKoerner(reihe, spalte); schreib(String.valueOf(koerner)); // oder: schreib(Integer.toString(koerner); }
Das Schlüsselwort this findet bei der Definition von → Methoden
bei einer → erweiteren Hamsterklasse Verwendung.
Wenn eine Methode definiert wird, ist ja noch nicht bekannt, für welchen namentlich benannten Hamster die Methode aufgerufen wird.
class SammelHamster extends Hamster { void sammle() { while (this.kornDa()) { this.nimm(); this.gesammelteKoerner = this.gesammelteKoerner + 1; } } void rechtsUm() { this.linksUm(); this.linksUm(); this.linksUm(); } } void main() { Hamster paul = new SammelHamster(); paul.init(0, 0, Hamster.OST, 0); paul.sammle(); paul.rechtsUm(); }
In der Methode main wird ein neuer Sammelhamster namens paul → initialisiert.
Wird jetzt die Methode sammle() aufgerufen wird der Platzhalter this durch den Hamsternamen paul ersetzt.
Eine String-Variable kann in Kleinbuchstaben- bzw. in Großbuchstaben umgewandelt werden:
void main() { String text = "Java Hamster"; // in Großbuchstaben umwandeln text = text.toUpperCase(); // in Kleinbuchstaben umwandeln text = text.toLowerCase(); }
Typecast ist die Umwandlung eines Datentyps in einen anderen.
So können Variable vom Typ → int nach → double
umgewandelt ("gecastet") werden.
Der umgekehrte Weg funktioniert ebenfalls, allerdings fallen dann eventuelle vorhandene Nachkommastellen weg.
Manchmal ist dieser Effekt aber auch wie bei der Bestimmung einer
→ Zufallszahl, gewünscht.
void main() { double zahl = 1.12; zahl = (int) zahl; zahl = (double) zahl; }
Das → Protokoll einer Klasse ist auf die Methoden der eigenen
Klasse und die der übergeordneten Klasse beschränkt.
Mit einer Typumwandlung kann diese aufgehoben werden.
class StufeHochHamster extends Hamster { StufeHochHamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } int zaehleStufe = 0; void erklimmeStufe() { while(!this.vornFrei()) { this.linksUm(); this.vor(); this.rechtsUm(); this.vor(); this.zaehleStufe = this.zaehleStufe + 1; } } void rechtsUm() { this.linksUm(); this.linksUm(); this.linksUm(); } } class AllesKoennerHamster extends Hamster { AllesKoennerHamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } void schritteVor(int anzahlSchritte) { while (anzahlSchritte > 0) { if (this.vornFrei()) this.vor(); anzahlSchritte = anzahlSchritte -1; } } }
Der StufehochHamster kennt die → Methoden
erklimmeStufe() und rechtsUm();,
der AllesKoennerHamster kennt schritteVor()
void main() { Hamster willi = new StufeHochHamster(1, 0, Hamster.OST, 0); Hamster paul = new AllesKoennerHamster(0, 0, Hamster.OST, 0); // Hamster paul wird für diese Zeile zum AllesKoennerHamster // schritteVor() gehört zum Protokoll der Klasse AllesKoennerHamster ((AllesKoennerHamster)paul).schritteVor(3); // Hamster willi wird für diese Zeile zum StufeHochHamster // erklimmeStufe() gehört zum Protokoll der Klasse StufeHochHamster ((StufeHochHamster)willi).erklimmeStufe(); // Fehler: rechtsUm() gehört nicht zum Protokoll der Klasse Hamster //paul.rechtsUm(); }
Wenn du in Java Umlaute darstellen willst, musst du den Umlaut als Unicode darstellen:
Sonderzeichen | Unicode |
---|---|
Ä | \u00C4 |
Ö | \u00F6 |
Ü | \u00DC |
ä | \u00E4 |
ö | \u00F6 |
ü | \u00FC |
ß | \u00DF |
Variablen sind eine Art Box, in der immer nur ein Gegenstand (eine Zahl/eine Zeichenkette) Platz findet.
Wird ein neuer Gegenstand (eine Zahl/eine Zeichenkette) hineingelegt, so wird der alte entfernt.
Der Java-Hamster kennt verschiedene Datentypen:
→ Ganzzahlen (int), → boolean-Variable (boolean),
→ double und → Zeichenketten (String).
Wenn du einer Variable einem Wert zugordnet hast, kannst du ihren Namen im Programm verwenden.
Beachte bei der Definition von Variablen die → Konventionen zur Bezeichnung!
Eine Integer-Variable ist eine Ganzzahl zwischen -2.147.483.648 und 2.147.483.647
int zahl;
int anzahlSchritte = 1 // heraufzählen anzahlSchritte = anzahlSchritte + 1 ; // herunterzählen anzahlSchritte = anzahlSchritte - 1 ;oder kürzer:
anzahlSchritte ++; anzahlSchritte --;
int anzahlSchritte = 1; int anzahlKorn = 2; anzahlSchritte = anzahlSchritte + 1 ; if (anzahlSchritte == anzahlKorn) { linksUm(); }
Siehe auch:
→ Konventionen für Bezeichner von Prozeduren, Methoden, Funktionen, Variablen, Klassen und InterfacesMit char kann ausschließlich ein einzelnes Zeichen definiert werden. Im Unterschied zur → String-Definition muss das Zeichen als ASCII-Wert angegeben oder in Hochkommata gesetzt werden
ASCII-Tabelle
void main() { // der Buchstabe A in der Schreibweise mit Hochkommata char zeichenHochkommata = 'A'; // der Buchstabe A in der Schreibweise als Dezimalwert char zeichenDezimal = 65; }
Siehe auch:
→ getKeyCode/getKeyChar
Funktionen vom Typ int "berechnen" eine Integer-Variable. Typischerweise wird diese Variable
herauf- oder heruntergezählt. Der Wert dieser Variable wird mit
→ return zurückgegeben.
Der Hamster soll feststellen, wieviele Schritte bis zu einer Mauer zu gehen sind.
Er soll dann die gleiche Anzahl von Schritten zurückgehen.
int schritteBisZurMauer() { int anzahl = 0;
Die Variable anzahl muss einen Startwert erhalten:
while (vornFrei()) { vor(); anzahl = anzahl + 1; }
Nach jedem Schritt wird die Variable anzahl um 1 heraufgesetzt.
Du kannst auch die Kurzform ...
anzahl ++;
... verwenden
return anzahl; }
Der Wert der Variable anzahl wird an das Hauptprogramm zurückgegeben.
int anzahlSchritte = schritteBisZurMauer();
Der Variablen anzahlSchritte wird der Rückgabewert der Funktion schritteBisZurMauer übergeben.
Auch die Anzahl der Körner kann mit einer int-Funktion festgestellt werden:
void main() { int anzahlKoerner = koernerAufnehmen(); } int koernerAufnehmen() { int anzahl = 0; while (kornDa()) { nimm(); anzahl = anzahl + 1; } return anzahl; }
int-Funktionen stehen immer außerhalb von void main()!
Eine Variable vom Typ boolean kennt zwei Werte: wahr (true) oder falsch (false). Alle → Sensoren sind Variablen vom Typ boolean. Du verwendest immer die Kurzform:
if (vornFrei() vor();
Eigentlich heißt es:
if (vornFrei() == true) vor(); if (vornFrei() == false) linksUm();
Hat das Ergebnis z. B. einer → if ... else -Abfrage nur zwei mögliche Werte, kann die Boolean-Variable als Kriterium für die Verzweigung genutzt werden.
void main() { boolean gefunden = false; int position; String satz = "Die Variable boolean kann zwei Werte haben: true oder false."; // Ist das Wort Variable im String satz enthalten? position = satz.indexOf("Variable"); // Das Wort "Variable" ist vorhanden! if (position > 0) { gefunden = true; } if (gefunden) schreib("Das Wort wurde gefunden!"); else schreib("Das Wort wurde nicht gefunden!"); }
Beachte bei der Definition von Variablen die → Konventionen zur Bezeichnung!
Eine boolean-Funktion dient dazu, abzufragen, ob eine Bedingung wahr (true) oder falsch (false) ist.
Der gespeicherte Wert wird mit return an das Hauptprogramm oder die → Prozedur zurückgegeben.
if (linksFrei())
linksFrei() ist der Aufruf einer Boolean-Funktion
boolean linksFrei() { linksUm(); if (vornFrei()) { linksUm(); linksUm(); linksUm(); return true; }
Der Hamster dreht sich nach links und stellt fest, dass der Weg nach vorne frei ist.
Er gibt den Wert true zurück
else { linksUm(); linksUm(); linksUm(); return false; } }
Der Weg nach links ist durch eine Mauer versperrt.
Er gibt den Wert false zurück
Es geht auch noch kürzer:
boolean linksFrei() { linksUm(); boolean ist_frei = vornFrei();
Der Zustand vornFrei (wahr oder falsch) wird in der Variablen ist_frei gespeichert.
linksUm(); linksUm(); linksUm(); return ist_frei; }
linksFrei wird als true oder false zurückgegeben.
Variable vom Typ double sind Kommazahlen.
double zahl1 = 3.347; double zahl2 = 45.65;
Du musst das anglo-amerikanische Format verwenden: "." statt ","
Zeichenketten sind Folgen von Zeichen, die in Anführungszeichen eingeschlossen werden
String antwort = "Ich drehe mich nach links";
Du darfst im Namen der Variablen keine Umlaute und Sonderzeichen verwenden!
String antwort = "Der Hamster sagt: \"Ich drehe mich nach links\""
String antwort = "Der Hamster sagt:\n \"Ich drehe mich nach links\""
void main() { Hamster paul = new Hamster(); paul.init(5, 0, Hamster.OST, 0); int anzahlDrehung = 4; String antwort = "Ich drehe mich " + anzahlDrehung + " Mal nach links"; paul.schreib(antwort); }Auch Strings können verkettet werden:
void main() { String antwort1 = "Ich drehe mich "; String antwort2 = "nach links"; schreib(antwort1 + antwort2); }
void main() { int anzahlSchritte = 5; schreib(String.valueOf(anzahlSchritte)); }
void main() { String ausgabe = ""; int maxZahl = 9; for (int zaehler = 0; zaehler < 5; zaehler ++) { int zufallsZahl = (int) (Math.random() * maxZahl); ausgabe = ausgabe + String.valueOf(zufallsZahl); } schreib(ausgabe); }
Siehe auch:
→ substring(), → indexOf(),Variable vom Typ → String oder → int können in den jeweils anderen Typ umgewandelt werden.
int zahl = 10; String ergebnis = String.valueOf(zahl); // oder: ergebnis = integer.toString(zahl);
double zahl = 0.11; String stringDouble = Double.toString(zahl);
String stringZahl = "12"; int intZahl = Integer.parseInt(stringZahl);
Siehe auch:
→ double, → int, → StringVerbundanweisungen sind eine Abfolge von Befehlen, die beim Zutreffen einer Bedingung "abgearbeitet" werden. Der Anweisungsblock wird in geschweifte Klammern gefasst.
while (vornFrei()) { vor(); if (kornDa()) nimm(); }
oder:
if (maulLeer()) { vor(); nimm(); linksUm(); }
Für Variable vom Typ → int:
Operator | Benutzung | Beschreibung |
---|---|---|
< | a < b | liefert wahr, wenn a kleiner als b ist |
> | a > b | liefert wahr, wenn a größer als b ist |
<= | a <= b | liefert wahr, wenn a kleiner oder gleich b ist |
>= | a >= b | liefert wahr, wenn a größer oder gleich b ist |
== | a == b | liefert wahr, wenn a gleich b ist |
!= | a != b | liefert wahr, wenn a ungleich b ist |
Für Variable vom Typ → boolean kann abgefragt werden, ob die Variable den Wert true oder false hat:
void main() { boolean gefunden = false; if (kornDa()) gefunden = true; else gefunden = false; if (gefunden == true) vor(); if (gefunden == false) linksUm(); }
oder kürzer:
void main() { boolean gefunden = false; if (kornDa()) gefunden = true; else gefunden = false; if (gefunden) vor(); if (!gefunden) linksUm(); }
Für Variable vom Typ → String kann mit → equals()abgefragt werden, ob der String einen bestimmten Wert hat:
void main() { String antwort = liesZeichenkette("Nach links drehen (j/n)?"); if (antwort.equals("j")) linksUm(); }
Die → Sensoren liefern als Rückgabewert eine → boolean Variable, die den Wert true oder false hat.
Der Vorgabewert ist true:
while (vornFrei()) ...
heißt immer, dass in Blickrichtung keine Mauer steht.
Du kannst auch mit einer Verneinung abfragen, ob vorne nicht frei ist:
while (vornFrei() == false) ....
oder kürzer:
while (!vornFrei()) ...
Schwieriger wird es, wenn du feststellen willst, ob der Hamster Körner im Maul hat.
Der Hamster kennt nur den Sensor maulLeer(). Du musst also das Gegenteil -ist nicht maulLeer()- abfragen:
while (maulLeer() == false) ....
oder kürzer:
while (!maulLeer()) ...
Als Schleife → Iteration versteht man eine oder mehrere Anweisung(en), die solange wiederholt wird (werden),
bis eine bestimmte Bedingung erfüllt ist.
Als Bedingungen können verwendet werden:
while (vornFrei()) vor();Der Hamster geht solange vorwärts, bis er auf ein Hindernis trifft.
while (kornDa()) nimm();Der Hamster frisst solange Körner, bis auf seiner Position keins mehr liegt.
boolean gefunden = false; // Die Schleife läuft solange bis gefunden den Wert true hatwhile (gefunden) { if (kornDa()) gefunden = true; }
int anzahlSchritte = schritteBisZurMauer(); while (anzahlSchritte > 0) { vor(); anzahlSchritte = anzahlSchritte - 1; }
Siehe auch:
→ do ... while, → Logische Operatoren
Math.random erzeugt Zufallszahlen vom Typ → double zwischen 0.0 (einsschießlich) und
1.0 (ausschließlich).
Wenn du eine Obergrenze für die Zahl festlegen willst, musst du die ermittelte Zahl mit der maximal erlaubten Zahl multiplizieren
und anschließend mit einer → Typumwandlung in eine Variable vom Typ
→ int umwandeln.
Da die Zahl immer nach unten abgerundet wird, kannst du die Zahl 0 ausschließen, indem du die maximale Zahl immer um eins erhöst.
Das kannst du entweder erledigen, indem du die maximale Zahl direkt beim Aufruf der Funktion herauf setzt oder innerhalb der Funktion 1 addierst.
void main() { int maxZahl = 6; // maxZahl 6: 0 ausschließen -> Erhöhung um 1 int anzahlSchritte = (int) (Math.random() * maxZahl + 1); while (anzahlSchritte > 0) { vor(); anzahlSchritte = anzahlSchritte - 1; } }Beispiel mit einer → int-Funktion:
Es sollen die Zahlen zwischen 1 und 6 gewürfelt werden:
int zufallsZahl(maxZahl) { // maxZahl 6: 0 ausschließen -> Erhöhung um 1 int zahl = (int) (Math.random() * maxZahl + 1); return zahl; } void main() { int maxZahl = 6; int anzahlSchritte = zufallsZahl(maxZahl); while (anzahlSchritte > 0) { vor(); anzahlSchritte = anzahlSchritte - 1; } }
oder kürzer mit Übergabe der höchsten Zahl:
int zufallsZahl(int maxZahl) { // maxZahl 6: 0 ausschließen -> Erhöhung um 1 return (int) (Math.random() * maxZahl + 1); } void main() { int maxZahl = 6; int anzahlSchritte = zufallsZahl(maxZahl); while (anzahlSchritte > 0) { vor(); anzahlSchritte = anzahlSchritte - 1; } }
class Zufall { int zufallsZahl(int maxZahl) { return (int)(Math.random() * maxZahl); } }
void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // neues Objekt der Klasse Zufall erzeugen Zufall wuerfeln = new Zufall(); int gewuerfelteZahl = wuerfeln.zufallsZahl(7); paul.schreib(String.valueOf(gewuerfelteZahl)); }
import java.util.Random; class Zufall { int zufallsZahl(int maxZahl) { Random zufall = new Random(); return zufall.nextInt(maxZahl + 1); } }
void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // neues Objekt der Klasse Zufall erzeugen Zufall zahl = new Zufall(); // Aufruf der Funktion zufallsZahl paul.schreib(String.valueOf(zahl.zufallsZahl(6))); }
int zufallsZahl(int minZahl, int maxZahl) { return (int) (Math.random() * (maxZahl - minZahl + 1) + minZahl); } void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // Aufruf der Funktion zufallsZahl mit den Parametern minZahl, maxZahl paul.schreib(String.valueOf(zufallsZahl(2, 6))); }
import java.util.Random; class Zufall { int zufallsZahl(int minZahl, int maxZahl) { Random zufall = new Random(); return zufall.nextInt(maxZahl + 1) + minZahl; } }
void main() { Hamster paul = new Hamster(0, 0, Hamster.OST, 0); // neues Objekt der Klasse Zufall erzeugen Zufall zahl = new Zufall(); // Aufruf der Funktion zufallsZahl mit den Parametern minZahl, maxZahl paul.schreib(String.valueOf(zahl.zufallsZahl(2, 6))); }
Siehe auch:
→ Math-Bibliothek, → Typecast, → RandomDie → Methoden, → Attribute und
→ Konstruktoren einer Klasse werden unter dem Begriff Klassenelemente zusammengefasst.
Mit den Zugriffsrechten kann festgelegt werden, wer auf Klassen oder die Klassenrumpf definierten → Attribute,
→ Konstanten und → Methoden einer Klasse zugreifen darf.
Die Zugriffsrechte stellen eine Rangfolge von weniger zu mehr dar:
private → <ohne> → protected → public
public class DrehHamster extends Hamster { DrehHamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } void rechtsUm() { this.linksUm(); this.linksUm(); this.linksUm(); } }Die Klasse muss unter dem Namen DrehHamster abgespeichert werden
public class DrehHamster extends Hamster { public final static int MAX_RECHTSDREHUNGEN = 10; private int anzahlRechtsDrehungen; DrehHamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } public void rechtsUm() { if (this.rechtsDrehungenMoeglich()) { this.linksUm(); this.linksUm(); this.linksUm(); this.anzahlRechtsDrehungen ++; } } public boolean rechtsDrehungenMoeglich() { return this.anzahlRechtsDrehungen <= DrehHamster.MAX_RECHTSDREHUNGEN; } } void main() { DrehHamster paul = new DrehHamster(0, 0, Hamster.OST, 0); while(paul.rechtsDrehungenMoeglich()) { paul.rechtsUm(); } paul.anzahlRechtsDrehungen = 0; }Der Versuch, die anzahlRechtsDrehungen für paul auf 0 zu setzen scheitert, weil das Attribut in der Klasse DrehHamster als private deklariert ist.
public class DrehHamster extends Hamster { DrehHamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } public void umdrehen() { this.kehrt(); } private void kehrt() { this.linksUm(); this.linksUm(); } } public class Dreh2Hamster extends drehHamster { Dreh2Hamster(int reihe, int spalte, int blickrichtung, int koerner) { super(reihe, spalte, blickrichtung, koerner); } private void kehrt() { this.linksUm(); this.linksUm(); this.linksUm(); this.linksUm(); this.linksUm(); this.linksUm(); } } void main() { DrehHamster paul = new DrehHamster(0, 3, Hamster.OST, 0); Dreh2Hamster willi = new Dreh2Hamster(2, 3, Hamster.OST, 0); paul.umdrehen(); willi.umdrehen(); }Die Klasse Dreh2Hamster überschreibt zwar die Methode kehrt() der Klasse DrehHamster, sie wird aber nicht → dynamisch gebunden, weil sie als private definiert ist.