Eigenes Programm: Little Crab1
Transcription
Eigenes Programm: Little Crab1
Eigenes Programm: Little Crab1, Seite 1 von 5 3. Das erste „eigene“ Programm mit Greenfoot: Litte Crab 3.1. Quelltext bearbeiten Nachdem Sie etwas Erfahrungen in der Bedienung von Greenfoot gewonnen haben, geht es jetzt ans erste eigene kleine Programm. Hier zeigt sich ein Vorteil von Java (und anderen objektorientierten Sprachen): Sie müssen nicht von vorne anfangen, Sie können einfach fertige und vorgefertigte Klassen benutzen. - Java-Programme bestehen ja einfach aus einem Satz von Klassen. In Greenfoot werden Klassen für ein Spiel (zusammen mit Bildern und der Dokumentation) in einem Szenario zusammengefasst. Öffnen Sie das Szenario little-crab. Platzieren Sie eine Krabbe in die Welt. - Falls das nicht funktioniert, müssen Sie zuerst kompilieren (unten rechts auf Compile klicken). Starten Sie das Programm ( ). Was passiert? Es ist nichts kaputt, wenn nichts passiert ;-) Bis jetzt hat niemand definiert, was eine Krabbe tun soll, wenn Act oder Run gestartet wird. Das werden wir jetzt tun, und zwar für alle Krabben: Dazu erweitern wir die Klasse Crab, also den Bauplan für alle Krabben: Doppelklicken Sie im Klassendiagramm (rechts) auf die Klasse Crab. Der Quelltext-Editor von Greenfoot öffnet sich und zeigt den Quelltext der Klasse Crab. Wenn Ihr Bildschirm deutlich anders aussieht, haben Sie die Dokumentation geöffnet. - Dann steht bei Ihnen oben rechts statt Source Code das Wort Documentation. Klicken Sie in diesem Fall auf den kleinen Pfeil neben Documentation und wählen Sie dann Source Code. Uns interessiert im Moment die Methode act(). Alles, was in der act()-Methode eingeschlossen ist, wird ausgeführt, wenn Sie auf klicken (und zwar bei allen Objekten, in denen eine act()Methode definiert ist). Eigenes Programm: Little Crab1, Seite 2 von 5 Fügen Sie in die act()-Methode folgenden Code (statt des Kommentars) ein: move(); So sollte es dann aussehen: public void act() { move(); } Zur Erklärung: Wir haben jetzt innerhalb der Methode act() einen Methodenaufruf geschrieben: Wenn act() aufgerufen wird, startet act() wiederum die Methode move(). Irgendwo anders wird definiert, was diese Methode machen soll. Bevor Sie jetzt eine Krabbe in die Welt setzen, um das Ergebnis auszuprobieren, müssen Sie erst kompilieren. - Tun Sie das und klicken Sie anschließend auf Act und dann auf Run. Die Krabbe müsste sich jetzt bewegen. - Und zwar bis zum Rand. Denn niemand hat bisher festgelegt, was die Krabbe tun soll, wenn Sie am Ende ihrer Welt angekommen ist. Bevor wir das versuchen, müssen wir eine andere Frage klären: Wie kommen wir darauf, welche Methoden es gibt? Irgendwo muss festgelegt sein, was die Krabbe bisher kann (also welche Methoden definiert sind). Ein Rechtsklick auf die Krabbe verrät es uns: 3.2 Vererbung Die Methode move() ist von der Klasse Animal „geerbt“ (inherited)! Als „Kind“ von Animal kann Crab nämlich über die Methoden von Animal verfügen. - Sie können das an einem neuen Crab-Objekt ausprobieren, indem Sie auf void move() klicken – wie in der Abbildung gezeigt. (Denken Sie daran, dass Sie vorher auf Pause klicken müssen, falls Ihr Programm läuft.) Vererbung ist ein Schlüsselkonzept objektorientierter Programmierung. Das Klassendiagramm (oben rechts) zeigt die Einordnung von Crab in die Klassenhierarchie: Die Krabben-Klasse ist also sozusagen ein Kind von Animal, Animal ist wiederum ein Kind von Actor. Kinder bezeichnet man in der Fachsprache als Subklassen (oder Unterklassen), Eltern als Superklassen (oder Oberklassen). Das Verhältnis wird durch folgende Formulierungen klar: Crab ist ein Animal. Animal ist ein Actor. Der Vorteil liegt auf der Hand: Methoden wie move() müssen nur einmal definiert werden. Suchen Sie den Code, der die Methode move() definiert. - Sie müssen ihn (noch) nicht verstehen!! Eigenes Programm: Little Crab1, Seite 3 von 5 3.3 Dokumentation In Greenfoot ist es relativ einfach zu erfahren, welche Methoden zur Verfügung stehen: ein Rechtsklick auf ein Objekt genügt. In anderen Entwicklungsumgebungen (also bei der professionellen Programmentwicklung) geht das nicht so einfach. Theoretisch könnte man den ganzen Quellcode durchforsten, aber bei komplexeren Projekten ist das nicht mehr sinnvoll. - Deshalb müssen die „Schnittstellen“ der einzelnen Klassen dokumentiert werden: mit Schnittstellen sind hier die Methoden gemeint, die von außen aufgerufen werden können. Auf Englisch heißen diese Schnittstellen API: Application Programming Interface. In Java sind das (wie gesagt) die Methoden, die eine Klasse (für ihre Objekte) zur Verfügung stellt. Der Zugriff auf die Dokumentation ist bei Greenfoot einfach: Doppelklicken Sie im Klassendiagramm auf die Klasse, deren Doku Sie sehen wollen. Im Editorfenster klicken Sie dann oben rechts auf den Pull-Down-Pfeil und anschließend auf Documentation (siehe Abbildung). Öffnen Sie die Dokumentation zur Klasse Animal. Welche Methoden gibt es? Dargestellt wird die „Syntax“ für einen Methodenaufruf. Beachten Sie folgendes Beispiel: void turn(int angle) Dreht 'angle' Grad nach rechts (im Uhrzeigersinn). In der linken Spalte steht der Rückgabetyp. - Es sei daran erinnert, dass void bedeutet, dass die Methode quasi ein Befehl ist (und die Methode nix zurückgibt). Alle anderen Rückgabetypen kennzeichnen die Methode als Frage. Der Methodenname ist fett gedruckt. Falls kein Parameter übergeben werden kann, bleibt die anschließende Klammer leer, sonst folgt in der Klammer der Datentyp und die Parameterbezeichnung. Im Beispiel muss der Methode turn() mitgeteilt werden, um wieviel Grad (angle = Winkel) die Krabbe drehen soll. Die Angabe muss als Ganzzahl (int) erfolgen. Ergänzen Sie den Quellcode der Klasse Crab mit einem Methodenaufruf von turn() innerhalb der act()-Methode. Der Code könnte z.B. so aussehen: public void act() { move(); turn(3); } Probieren Sie verschiedene Parameter-Werte der Methode turn() aus. Was passiert, wenn Sie eine „Kommazahl“ als Parameter übergeben. Studieren Sie bei der Gelegenheit eventuelle Fehlermeldungen. Eigenes Programm: Little Crab1, Seite 4 von 5 Das Ergebnis ist natürlich nicht wirklich befriedigend. - Eine Krabbe, die sich im Kreis dreht, ist noch nicht der Weisheit letzter Schluss. Der nächste Schritt sollte sein, dass die Krabbe (wieder) geradeaus geht und wendet, bevor sie an den Rand stößt. 3.4 Wenn... - Kontrollstrukturen (zum ersten...) Kontrollstrukturen steuern den Ablauf eines Programms. - Normalerweise werden die Anweisungen eines Programms in der Reihenfolge ausgeführt, wie sie hingeschrieben sind. Durch Kontrollstrukturen kann der Ablauf des Programms je nach „Datenstand“ (oder dem derzeitigen Zustand eines Objekts) unterschiedlich sein. Die einfachste Kontrollstruktur ist eine if-KonstrukKrabben: act1 tion: Wenn eine bestimmte Bedingung erfüllt wird, soll gehe geradeaus etwas bestimmtes gemacht werden. Zum Beispiel soll Weltende erreicht? die Krabbe im Prinzip geradeaus gehen. Wenn aber J eine Krabbe das Ende der Welt erreicht hat, soll sie drehe um 90 Grad sich um 90 Grad nach links drehen. Rechts sehen Sie eine Veranschaulichung in einem Struktogramm. N Als Code wäre folgende Lösung möglich: public void act() { move(); if(atWorldEdge()) { turn(90); } } Probieren Sie es aus! Denken Sie daran, dass Sie nach der Änderung des Codes neu kompilieren müssen. Das Verhalten ist etwas anders als erwartet. Lassen Sie sich deshalb die einzelnen „Schritte“ (mit Act) anzeigen. Die Syntax einer einfachen if-Konstruktion ist folgendermaßen: if(logischer Ausdruck) { anweisung; [anweisung;] [weitere anweisungen;] } Der logische Ausdruck in der runden Klammer wird ausgewertet. Ist er WAHR, werden die Anweisungen zwischen den anschließenden geschweiften Klammern ausgeführt. Ist der Ausdruck nicht WAHR, werden sie nicht ausgeführt. In unserem Beispiel ist der Ausdruck WAHR, wenn sich die Krabbe in der Nähe des Randes befindet. Um die Bedingung zu formulieren, werden häufig Vergleichsoperatoren verwendet: < == > ist kleiner ist gleich (Achtung!!) ist größer <= ist kleiner oder gleich klein != ist ungleich >= ist größer oder gleich groß Außerdem gibt es die Möglichkeit der „Verneinung“, die durch das Ausrufezeichen angegeben wird: if (!atWorldEdge()) // Wenn das Ende der Welt nicht in der Nähe ist... Eigenes Programm: Little Crab1, Seite 5 von 5 3.5 Methodenaufruf und Methodendeklaration Sie haben bereits mit Methoden gearbeitet. Jetzt wird es darum gehen, Methoden etwas genauer anzuschauen. Dabei werden wir eine eigene Methoden definieren und aufrufen. In der Methodendefinition (oder Methodendeklaration) wird festgelegt, was ein Objekt können soll. Der Methodenaufruf veranlasst, dass das Objekt das dann auch macht. Die act()-Methode der Klasse Crab sollte bis jetzt etwa folgenden Code enthalten (der Parameter von turn() wurde auf 17 geändert, um eine etwas unregelmäßigere „Wendung“ zu erreichen): public void act() { move(); if(atWorldEdge()) { turn(17); } } Der gezeigte Ausschnitt aus dem Code zeigt die Definition (oder Deklaration) der Methode act() a) Die erste Zeile zeigt die Signatur der Methode: Rückgabetyp (void), Methodenname (act), Klammern (für eine leere Parameter-Liste). b) Innerhalb der geschweiften Klammern folgt der Rumpf der Methode. Im Rumpf können einfache Anweisungen, Schleifen, bedingte Anweisungen oder Methodenaufrufe stehen. Hier wird festgelegt, was die Methode bewirken soll. Eine Methodendeklaration kann recht komplex werden. In ihr steht, was diese Methode mit „ihrem“ Objekt machen kann. Im Beispiel steht, was passieren soll, wenn man die act()-Methode eines Objektes aufruft. Das kann man mit einem Rechtsklick auf das Objekt und der anschließenden Auswahl der Methode act() für ein einzelnes Objekt machen. - Wenn man den ACT-Schalter der Greenfoot-Steuerung drückt, wird die act()-Methode von allen Akteuren eines Szenarios aufgerufen. Wenn man den RUN-Schalter drückt, wird die act()-Methode aller Akteure immer wieder (in einer Schleife) aufgerufen. Damit eine Methode ausgeführt wird, muss man immer die Methode aufrufen. Innerhalb der act()-Methode werden verschiedene Methoden aufgerufen: move() und (innerhalb der ifKonstruktion) die Methoden atWorldEdge() und turn(17). Als nächstes erweitern wir den Code so, dass ein Teil des Codes in eine eigene, selbst geschriebene Methodendefinition aus act() ausgelagert und in act() nur noch aufgerufen wird. Die neue Methode benennen wir auf Deutsch, damit man das Eigene schneller erkennt. Der ganze Code sieht dann so aus: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 import greenfoot.*; // (World, Actor, GreenfootImage und Greenfoot) public class Crab extends Animal { public void act() { move(); drehen(); } public void drehen() { if(atWorldEdge()) turn(17); } }