Stichwörter:
Abstrakte Klassen

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.

Beispiel: Definition einer abstrakten Klasse:
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();
    }
}
Das Programm:

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:

→ Interfaces
Arbeitsfeld erstellen

Arrays - Datenfelder

Mit 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.

Dem Array werden bei der Initialisierung bereits Werte zugewiesen:
int[] zahlen = {3, 5, 2, 7, 9, 10};
Dem Array werden zur Laufzeit Werte zugewiesen:
// 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
→ String-Array
→ char-Array
→ Hamster-Array
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];
Beispiel:
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);
}
String-Array
Beispiel:
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);
}

Beispiele für Arrays, die zur Laufzeit mit Werten gefüllt werden:
Array mit Zufallszahlen:
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);
}
Beispiel char-Array
char-Array
Das Beispiel füllt ein char-Array mit den 26 Großbuchstaben:
Beispiel char-Array
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 → ArrayList
Hamster-Array

Auch die Hamster selbst können in einem Array abgelegt werden.

Beispiel: in jeder Zeile wird auf der ersten Spalte ein Hamster erzeugt:
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.


Array an Prozedur übergeben

Ein Array kann auch an eine → Prozedur übergeben werden:

Beispiel:
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);
}
Array an Methode übergeben

Ein Array kann auch an eine → Methode innerhalb einer → Klasse übergeben werden:

Beispiel:
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:

→ ArrayList
ArrayList<>().toString()

Grundlagen:
→ Java-Klassen, → import, → ArrayList

ArrayList<>().toString() wandelt eine → ArrayList in einen → String um.

Beispiel:
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);
}

Arrays.toString()

Grundlagen:
→ Java-Klassen, → import → Array

Arrays.toString() wandelt ein → Array in eine String um.

Beispiel:
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));  
}

ArrayList

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.

Beispiel:

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

Der Typ der Liste muss definiert werden:
Einige Methoden werden hier beschrieben:

ASCII-Tabelle
ASCII-Tabelle Die ASCII-Tabelle ordnet jedem Buchstaben eine Zahl zu.
Wenn du das Programm ausprobieren möchtest, musst du in der Datei hamsterproperties den Wert runlocally auf true setzen.

Das dazugehörige Hamsterprogramm:
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:


Attribut, Klasse

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.

Beispiel mit einem → Konstruktor :
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;
    }
}
Beispiel:

Die Hamster sollen die gemeinsam gemachten Schritte zählen und sie als Mitteilung ausgeben.

Die Klasse AllesKoennerHamster
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();  
}


break - Schleifen unterbrechen

→ 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);
}

calendar - Java-Klassenbibliothek
Grundlagen:
→ Java-Klassenbibliothek. → import
     Die Klasse Calendar ermittelt das aktuelle Datum und die aktuelle Zeit.
Beispiel class DatumAnzeigen
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;       
    }
}
Das Programm:
void main()
{
    Hamster paul = new Hamster(0, 0, Hamster.OST, 0);
    DatumAnzeigen datumLesen = new DatumAnzeigen();
    String datum = datumLesen.datumErmitteln();
    paul.schreib(datum);
}

charAt() - einzelnes Zeichen eines Strings

charAt() beschreibt das Zeichen eines Strings an einer bestimmten Position

Beispiel:
void main() 
{
    String satz = "Java-Hamster";
    for (int zaehler = 0; zaehler < satz.length(); zaehler ++)
    {
        schreib(" " + satz.charAt(zaehler));
    }
}


CLASSPATH - Zielordner für eigene Pakete festlegen

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

String.contains() - Inhalt eines Strings prüfen

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()
continue - aktuellen Schleifendurchlauf beenden

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()
Debugger

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.





DecimalFormat - Dezimalzahlen formatieren
Grundlagen:
→ Java-Klassenbibliothek. → import
Das Programm formatiert Dezimalzahlen mit Komma und Dezimalpunkten.

Beispiel: class ZahlFormat
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);
    }
}
Das Programm:
void main()
{
    Hamster paul = new Hamster(0, 0, Hamster.OST, 0);
    ZahlFormat zahl = new ZahlFormat();
    String zahlAnzeigen = zahl.zufallsZahl();
    paul.schreib(zahlAnzeigen);
}
Beispiel: class ZahlFormatInt
Das Programm formatiert Ganzzahlen mit Dezimalpunkten.
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);
    }
}

Das Programm:
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);
}

do ... while

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:

Beispiel:
do
{
   nimm();
}
while (kornDa());

Der Hamster nimmt solange Körner auf, bis auf seiner Position kein Korn mehr liegt.

do ... while ist eine sogenannte Fuß-gesteuerte Schleife. Die Anweisung werden mindestens einmal ausgeführt, auch dann, wenn die im Schleifenfuß genannte Bedingung falsch ist.
Liegt beim Programmstart auf der aktuellen Position kein Korn, wird das Programm mit einer → Fehlermeldung abgebrochen.

Siehe auch:

→ while

Dynamisches Binden von Methoden

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.

Beispiel:
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 Protokolls
Editor
Dateioperationen 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() - letztes Zeichen eines Strings feststellen

endsWith() stellt das letzte Zeichen eines → Strings fest

Beispiel:
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);
}

String.equals() - Strings vergleichen

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(),
trim() - Leerstellen entfernen

Die Methode trim() entfernt die Leerstellen am Anfang und am Endes eines → Strings.

Beispiel:
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");
}

Exceptions - Fehlerklassen

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

Die Klasse VorsichtigerHamster
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();
        }
    }
}
Das Hauptprogramm:
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:

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.

Beispiel

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(); 
    }
}

existierenderHamster - neuen Hamster mit den Attributen eines bestehenden Hamsters erzeugen

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();   
}

extends - erweiterte Hamsterklassen

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.

Beispiel:
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.

Beispiel:
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.
Farbe, Hamster

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);
}

Fehlermeldungen des Compilers

for

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, → continue
for each

Mit 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!

Beispiel:
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);
}

Territorium.getAnzahlHamster()

Mit Territorium.getAnzahlHamster wird die Anzahl der Hamster (einschließlich des Standardhamsters), die sich im Territorium befinden, ermittelt.

Beispiel:
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:
Die Klasse NachwuchsHamster
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();
        }
    }		   
}
Das Hauptprogramm:
void main() 
{
    NachwuchsHamster paul = new NachwuchsHamster();
    paul.laufe();
}

Territorium.mauerDa()

Territorium.mauerDa() stellt fest, ob sich an der angegebenen Position im Hamsterfeld eine Mauer befindet.
Es werden die Parameter reihe und spalte erwartet.

Beispiel:
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()

getAnzahlKoerner() stellt fest, wie viele Körner der Hamster im Maul hat.

Beispiel:
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!");
}

getBlickrichtung()
getReihe()
getSpalte()

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!

Beispiel getReihe() getSpalte():
void main()
{
  Hamster willi = new Hamster();
  willi.init(2, 3, Hamster.OST, 0);

  willi.schreib("Ich befinde mich " +
  willi.getReihe() + " Spalte" + willi.getReihe());
}
Beispiel getBlickrichtung():

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;
         }
      }
   }
}

Gültigkeitsbereich von Variablen und Objekten

→ Variable können lokal oder global definiert werden:

Siehe auch:

→ static
Funktionen
→ int-Funktion
→ boolean-Funktion
→ String-Funktion
→ Hamster-Funktion

getStandardHamster()

Mit getStandardHamster() kann dem blauen Standardhamster ein Name zugeordnet werden.

Beispiel:
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

Beispiel:
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());
}

Grundgerüst eines Hamsterprogramms
void main ()
{
    . . . 

}

Hamster-Befehle

Wenn du einen → neuen Hamster erzeugt hast, musst du dem Befehl den Namen des Hamster → voranstellen.


Hamster-Methode überschreiben

Das Überschreiben von hamstereigenen Methoden erfordert zwei Besonderheiten:

Beispiel:
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();
}

Hamsterfeld

Die Position, die der Hamster einnimmt, wird durch zwei → Integer-Variablen beschrieben:

Die Zählung beginnt immer mit 0!


Hamsterfeld speichern

Hamster-Funktion

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;
}

Beispiel mit einer Klasse:
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 ... else

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
{
    . . .
    . . .
}
Beispiele:

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.

Beispiel:
if (linksFrei()) linksUm();
else if (rechtsFrei()) rechtsUm();  
linksFrei() und rechtsFrei() sind → boolean-Funktionen, die du erst definieren musst.

if-Abfragen können auch verschachtelt sein:

Beispiel:

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:

→ switch
import - eigene Pakete einsetzen

Grundlagen:
→ Zugriffsrechte

Alle → Methoden und → Funktionen, die außerhalb des Paketes verwendet werden sollen, müssen als public definiert werden.

Beispiel:
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.


import - Java-Klassen einbinden

Grundlage:
→ Java-Klassenbibliothek

Mit der import-Anweisung bindest du eine oder mehrere Java-Klassen ein.

Beispiel:
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()

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);
}
Aufgabe Quiz

Siehe auch:

→ String, → substring()
Interfaces

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.

im Beispiel werden zwei Interfaces definiert:

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 Binden
Innere Klasse

Die 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.

Beispiel Zufall:
// 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;
    } 
}
Beispiel Hamsterklasse:

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();
}

Iteration

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.

Beispiel:

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();
        }
    }
}

java.io.File - Verzeichnisse lesen
Grundlagen:
→ Java-Klassenbibliothek. → import, → SimpleDateFormat, → for each

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
Beispiel class VerzeichnisLesen:
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;
    }
}
Das Programm:
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);  
}

java.io.BufferedReader
Grundlage:
→ Java-Klassenbibliothek. → import, → try catch

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
Das Programm:
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);   
}

java.io.PrintWriter
java.io.File
java.io.FileWriter
Grundlage:
→ Java-Klassenbibliothek, → import, → try catch, → bufferedReader

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.

Die im Beispiel verwendeten Methoden;
Beispiel: class DateiSchreiben:
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();
        }       
    }
}
Das Programm:
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);
}
Grundlagen:
→ Java-Klassenbibliothek. → import, → SimpleDateFormat, → Umlaute
Beispiel class DateiLesenSchreiben:


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();
        } 
        
    }
}

class TextDateiFilter:
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;
    }
}
Das Programm:
/*
 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);
        }
    }
}

Java-Klassenbibliothek

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!


KeyListener

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) {}
}

class - eigene Hamsterklasse erstellen

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.

Beachte bei der Definition von Klassen die → Konventionen zur Bezeichnung!

Siehe auch:

→ erweiterte Hamsterklassen, → this, → super, → Methode → Methoden überladen
JFrame

Grundlagen:
→ 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:


JButton

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);
}

Beispiel JButton mit Icons


// 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);
}


JComboBox

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);
}

JLabel

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);
}

JScrollpane

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);
}

JTextArea

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);
}

JTextField

Grundlagen:
→ import, → Swing-Bibliothek, → ActionListener

Ein JTtextField fügt ein Eingabefeld für eine einzelne Textzeile hinzu..

Beispiel:

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
ActionListener

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()/getActionCommand()

setActionCommand() legt ein Kommando fest, auf das der ActionListener "hört".

Das vollständige Programm:
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()

getSource() ermittelt den Namen des gedrückten Buttons und führt die entsprechende Aktion aus.

Das vollständige Programm:
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);
}
MouseListener

Der MouseListener kann auf alle Mausereignisse reagieren:

Alle Methoden von MouseListener müssen überschrieben werden, auch dann wenn sie nicht verwendet werden!

Das vollständige Programm:
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);
}

setText() - Text JTextField/JTextArea hinzufügen
getText() - Text aus JTextField/JTextArea lesen

Grundlagen:
→ import, → Swing-Bibliothek, → contains, → System.exit(0)

setText() schreibt Text in ein JTextField/in eine JTextArea schreiben, getTtext() kann den Text wieder auslesen.

Beispiel:
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);
}

getKeyCode/getKeyChar

Grundlagen:
→ Swing-Bibliothek, → KeyListener

getKeyCode ermittelt den numerischen Tastencode, getKeyChar bestimmt die gedrückte Taste.

Beispiel:

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:

→ KeyListener

get-/set-Methode

Die 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).

Beispiel:

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!");
}
Beispiel

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);
}

class - Verallgemeinerung

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.

Beispiel: Zufallszahl ermitteln
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));
}
Beispiel: Zahl mit Dezimalpunkten formatieren
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);
}
Beispiel: Position eines Hamstes im Territorium festlegen
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
Kommentar
// das ist ein Kommentar für eine Zeile

/*
     das ist ein Kommentar für 
     mehrere Zeilen
*/

kompilieren

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.




Konstante

Innerhalb einer → Klasse kann ein besonderes Attribut erzeugt werden, das einen konstanten Wert erhält.

Beispiel:
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


Konstruktor

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.

Beispiel:
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, → extends
Konventionen für Bezeichner (Namen) von Prozeduren, Methoden, Funktionen, Variablen, Klassen und Interfaces

Unter Java-ProgrammiererInnen haben sich Konventionen für die Namen von → Prozeduren, → Methoden, → Funktionen → Variablen, → Interfaces und → Klassen eingebürgert.

Die Bezeichner sollten möglichst aussagekräftig sein und nur aus Buchstaben bestehen.
Umlaute (ä, ö, ü und ß) und Leerzeichen sind nicht erlaubt!


length()

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

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));
}

lieszahl()

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()
liesZeichenkette()

Dem Hamster kann mit liesZeichenkette() der Wert einer Variable vom Typ → String mitgeteilt werden.


Die Antwort wird mit → equals() verglichen.
void main()
{
    String antwort = liesZeichenkette("Einen Schritt vorgehen (j/n)?");
    if (antwort.equals("j")) vor();
}
}
Siehe auch: → liesZahl()
Logische Operatoren

Ä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
Beispiel Logisches UND:

Der Hamster stellt fest, ob vorne frei ist und ob auf der aktuellen Position ein Korn liegt:

while (vornFrei() && kornDa()) vor();
Beispiel Logisches ODER:

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();
    }
}

Math-Bibliothek

Der Hamster kann auch mathematische Funktionen der Java-Biliothek Math verwenden:

Beachte die anglo-amerikanische Schreibweise: "." statt "."!


Methode überladen

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!

Änderungen in der Klasse AllesKoennerHamster:
   
    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;
        }
    }
Das Programm:
void main() 
{
    AllesKoennerHamster willi = new AllesKoennerHamster(0, 1, Hamster.OST, 0);
    willi.vor(5);
    willi.linksUm(2);
    willi.vor(5);
}

new/init - neuen Hamster erzeugen und initialisieren

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.

Das folgende Programm erzeugt vier Hamster:
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:

Beispiel:
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:

→ Objekte
neues Programm erstellen
imperatives Programm objektorientiertes Programm

neue Hamster-Klasse erzeugen

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.

Beispiele:
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;
     }
}

new
→ new: neues Hamsterobjekt

→ new: neues allgemeines Objekt erzeugen
null

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.

Beispiel:
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.


Objekte von allgemeinen Klassen erzeugen
Grundlage:
→ Verallgemeinerung von Klassen

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.

Beispiele:

Parallele Programmierung

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 ...

Beispiel:

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.

Passive Hamster
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();
}



Selbstständige Hamster

Damit die Hamster ein Eigenleben führen können, müssen bestimmte Voraussetzungen geschaffen werden: