g9:uebungen:vererbung:start
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
— | g9:uebungen:vererbung:start [2024/08/31 10:03] (aktuell) – angelegt - Externe Bearbeitung 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | ====== Vererbung ====== | ||
+ | ====== Beispiel 1: Advanced Robot ====== | ||
+ | <WRAP center round todo 80%> | ||
+ | Die Klasse Robot hat alle Methoden, die Du von Robot Karol her kennst. Erweitere sie um weitere Methoden: | ||
+ | * Die Methode '' | ||
+ | * Die Methode '' | ||
+ | * Die Methode '' | ||
+ | * Die Methode '' | ||
+ | * Die Methode '' | ||
+ | |||
+ | Lass Dir noch weitere Methoden einfallen und schreibe ein Hauptprogramm, | ||
+ | </ | ||
+ | |||
+ | |||
+ | < | ||
+ | |||
+ | <div class=" | ||
+ | |||
+ | <script type=" | ||
+ | AdvancedRobot tom = new AdvancedRobot(1, | ||
+ | tom.legeQuadrat(4); | ||
+ | tom.baueTreppe(3); | ||
+ | |||
+ | class AdvancedRobot extends Robot { | ||
+ | |||
+ | void umdrehen() { | ||
+ | linksDrehen(); | ||
+ | linksDrehen(); | ||
+ | } | ||
+ | |||
+ | void gehe(int schrittzahl) { | ||
+ | for (int i = 0; i < schrittzahl; | ||
+ | | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void legeBahn(int länge) { | ||
+ | for (int i = 0; i < länge; i++) { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void legeQuadrat(int seitenlänge) { | ||
+ | for (int s = 0; s < 4; s++) { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void baueTreppe(int höhe) { | ||
+ | for (int i = 0; i < höhe; i++) { | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | ====== Beispiel 2: Fliegende Rechtecke ====== | ||
+ | Starte das Programm und regle die Geschwindigkeit langsam hoch! | ||
+ | < | ||
+ | |||
+ | <div class=" | ||
+ | |||
+ | <script type=" | ||
+ | new World(800, 800); | ||
+ | while(true) { | ||
+ | new FlyingRectangle(); | ||
+ | } | ||
+ | |||
+ | class FlyingRectangle extends Rectangle { | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | super(360, 760 - 40, 80, 80); | ||
+ | setFillColor(Math.round(Math.random() *(256 *256 * 256 - 1)), Math.random()*0.8+0.2); | ||
+ | |||
+ | vx = Math.random() * 10 - 5; | ||
+ | vy = Math.random() * (-20) - 6; | ||
+ | |||
+ | } | ||
+ | |||
+ | | ||
+ | move(vx, vy); | ||
+ | vy = vy + 0.2; | ||
+ | if(getCenterY() > 900) { | ||
+ | | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | }</ | ||
+ | |||
+ | </ | ||
+ | |||
+ | </ | ||
+ | |||
+ | Damit die Seite nicht zu lange wird, findest Du die [[: | ||
+ | |||
+ | === UML-Diagramm zu " | ||
+ | {{ : | ||
+ | Auf dem nebenstehenden Diagramm habe ich die (sehr zahlreichen!) Attribute und Methoden der Klassen '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | ===== Aufgabe: Starfield ===== | ||
+ | {{ youtube> | ||
+ | Programmiere ein Sternenfeld, | ||
+ | * Jeder Stern ist ein Kreis. | ||
+ | * Jeder Stern besitzt eine Geschwindigkeit, | ||
+ | * Ist ein Stern außerhab des sichtbaren Bereichs (testbar mit der Methode '' | ||
+ | * Sterne werden größer, je länger sie schon fliegen. Dadurch entsteht der Effekt, dass sie " | ||
+ | < | ||
+ | | ||
+ | |||
+ | < | ||
+ | <div class=" | ||
+ | |||
+ | <script type=" | ||
+ | // Hier programmieren! | ||
+ | </ | ||
+ | |||
+ | <script type=" | ||
+ | ## Tipp 1: | ||
+ | Ein Stern ist ein Kreis. Die Klasse ``Stern`` sollte also Unterklasse der Klasse ``Kreis`` sein. Zudem hat jeder Stern - wie die fliegenden Rechtecke im Bild oben - eine Geschwindigkeit. | ||
+ | </ | ||
+ | |||
+ | |||
+ | <script type=" | ||
+ | ## Tipp 2: | ||
+ | Hier ein " | ||
+ | ``` | ||
+ | new World(800, 800); | ||
+ | new Star(400, 400); | ||
+ | |||
+ | |||
+ | class Star extends Circle { | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | super(x, y, 1); | ||
+ | } | ||
+ | |||
+ | | ||
+ | // Alle Anweisungen hier werden 30-mal pro Sekunde ausgeführt | ||
+ | } | ||
+ | |||
+ | } | ||
+ | ``` | ||
+ | </ | ||
+ | <script type=" | ||
+ | ## Tipp 3: | ||
+ | Die Geschwindigkeit der Sterne in x- und y-Richtung ist zufällig. Eine Zufallszahl zwischen bspw. 2 und 10 erzeugt man folgendermaßen: | ||
+ | ``` | ||
+ | vx = Math.random()*8 + 2; | ||
+ | vy = Math.random()*8 + 2; | ||
+ | ``` | ||
+ | # Erklärung: | ||
+ | ``Math.random()`` erzeugt bei jedem Aufruf eine " | ||
+ | </ | ||
+ | <script type=" | ||
+ | ## Tipp 4: | ||
+ | Die Methode ``act()`` ist sehr ähnlich zur gleicnamigen Methode im Beispiel " | ||
+ | </ | ||
+ | <script type=" | ||
+ | ## Tipp 5: | ||
+ | Die Formel zur zufälligen Bestimmung der Geschwindigkeit in Tipp 3 hat einen Nachteil: Die Geschwindigkeiten haben nicht nur verschiedene Richtungen (gut!) sondern auch sehr unterschiedliche Beträge (schlecht!), | ||
+ | ``` | ||
+ | double v = Math.random()*8 + 2; // Betrag der Geschwindigkeit zwischen 2 und 10 | ||
+ | double w = Math.random()*2*Math.PI; | ||
+ | vx = v * Math.cos(w); | ||
+ | vy = v * Math.sin(w); | ||
+ | ``` | ||
+ | |||
+ | </ | ||
+ | |||
+ | </ | ||
+ | |||
+ | </ | ||
+ | |||
+ | [[: | ||
+ | |||
+ | ====== Beispiel 3: Klasse " | ||
+ | Die Programmiersprache stellt bisher nur Objekte zum Zeichnen von Rechtecken, Kreisen, Polygonen und Sprites zur Verfügung. Ich zeige Dir, wie man durch Erweiterung der Klasse Polygon leicht weitere Objektklassen erstellen kann. Im Folgenden entwickeln wir eine Klasse " | ||
+ | |||
+ | ==== Skizze: ==== | ||
+ | {{ : | ||
+ | < | ||
+ | |||
+ | <div class=" | ||
+ | |||
+ | <script type=" | ||
+ | new Raute(400, 300, 50, 100); | ||
+ | new Raute(200, 200, 100, 80); | ||
+ | |||
+ | class Raute extends Polygon { | ||
+ | |||
+ | | ||
+ | double diagonaleX, double diagonaleY) { | ||
+ | | ||
+ | super(true); | ||
+ | |||
+ | addPoint(mitteX + diagonaleX/ | ||
+ | addPoint(mitteX, | ||
+ | addPoint(mitteX - diagonaleX/ | ||
+ | addPoint(mitteX, | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | </ | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ====== Beispiel 4: Klasse " | ||
+ | Die Programmiersprache stellt bisher nur Objekte zum Zeichnen von Rechtecken, Kreisen, Polygonen und Sprites zur Verfügung. Ich zeige Dir, wie man durch Erweiterung der Klasse Polygon leicht weitere Objektklassen erstellen kann. Im Folgenden entwickeln wir eine Klasse " | ||
+ | |||
+ | ==== Mathematische Grundlagen ==== | ||
+ | {{ : | ||
+ | |||
+ | Wir wollen einen Stern mit $n$ Außenzacken zeichnen. Dazu brauchen wir die Koordinaten $(mitte_{x}, | ||
+ | Im Beispiel oben hat der Stern 5 Außenzacken (d.h. $n = 5$). Denke Dir eine Halbgerade, die im Mittelpunkt des Sterns beginnt und nach rechts zeigt. Sie geht durch den ersten Außenzacken des Sterns. Drehen wir sie um den Mittelpunkt des Sterns nach links, so überstreicht sie nach $360°/10 = 36°$ den ersten Innenzacken, | ||
+ | Der i-te Zacken erscheint also beim Winkel $i*36°$. Zur Berechnung seiner Koordinaten sieh' Dir oben das rechtwinklige Dreieck mit der roten und grünen Kathete an. Um die Koordinaten des zweiten Zackens zu berechnen muss die grüne Kathete zur x-Koordinate des Mittelpunkts addiert werden, die rote Kathete zur y-Koordinate: | ||
+ | $$ x = mitte_{x} + cos(i*36°)*radius $$ | ||
+ | $$ y = mitte_{y} + sin(i*36°)*radius $$ | ||
+ | Im Fall einer Außenzacke (gerades i, also '' | ||
+ | | ||
+ | |||
+ | < | ||
+ | |||
+ | <div class=" | ||
+ | |||
+ | <script type=" | ||
+ | new Stern(400, 300, 50, 150, 5); | ||
+ | |||
+ | class Stern extends Polygon { | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | super(true); | ||
+ | | ||
+ | for(int i = 0; i < 2 * zackenZahl; i++) { | ||
+ | |||
+ | | ||
+ | if(i % 2 == 0) r = rAußen; | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | |||
+ | } | ||
+ | |||
+ | setFillColor(Color.yellow); | ||
+ | | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | }</ | ||
+ | |||
+ | </ | ||
+ | |||
+ | </ | ||
+ | |||
+ | === UML-Diagramm zu " | ||
+ | {{ : | ||
+ | Auf dem nebenstehenden Diagramm habe ich die (sehr zahlreichen!) Attribute und Methoden der Klassen '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | |||
+ | === Viele Sterne === | ||
+ | Jetzt wollen wir unsere neue Klasse natürlich " | ||
+ | < | ||
+ | |||
+ | <div class=" | ||
+ | |||
+ | <script type=" | ||
+ | for(int i = 0; i < 15; i++) { | ||
+ | |||
+ | | ||
+ | | ||
+ | Stern s = new Stern(x, y, 10 + i, 30 + 3 * i, 5); | ||
+ | | ||
+ | | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | <script type=" | ||
+ | class Stern extends Polygon { | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | super(true); | ||
+ | | ||
+ | for(int i = 0; i < 2 * zackenZahl; i++) { | ||
+ | |||
+ | | ||
+ | if(i % 2 == 0) r = rAußen; | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | |||
+ | } | ||
+ | |||
+ | setFillColor(Color.yellow); | ||
+ | | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | }</ | ||
+ | |||
+ | </ | ||
+ | |||
+ | </ | ||
+ | |||
+ | ===== Beispiel 5: Feuerwerk ===== | ||
+ | Das Beispiel " | ||
+ | |||
+ | |||
+ | ====== Beispiel 6: Kochkurve ====== | ||
+ | < | ||
+ | |||
+ | <div class=" | ||
+ | |||
+ | <script type=" | ||
+ | new World(1000, 1000); | ||
+ | Kochkurve k = new Kochkurve(7); | ||
+ | |||
+ | class Kochkurve extends Turtle { | ||
+ | |||
+ | | ||
+ | super(50, 700); | ||
+ | setBorderWidth(3); | ||
+ | int länge = 700; | ||
+ | turn(60); | ||
+ | zieheLinie(länge, | ||
+ | turn(-120); | ||
+ | zieheLinie(länge, | ||
+ | turn(-120); | ||
+ | zieheLinie(länge, | ||
+ | } | ||
+ | |||
+ | | ||
+ | if(tiefe == 0) { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | zieheLinie(länge / 3, tiefe - 1); | ||
+ | turn(60); | ||
+ | zieheLinie(länge / 3, tiefe - 1); | ||
+ | turn(-120); | ||
+ | zieheLinie(länge / 3, tiefe - 1); | ||
+ | turn(60); | ||
+ | zieheLinie(länge / 3, tiefe - 1); | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | </ | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | ====== Beispiel 7: Fraktaler Baum ====== | ||
+ | < | ||
+ | |||
+ | <div class=" | ||
+ | |||
+ | <script type=" | ||
+ | new FraktalerBaum(400, | ||
+ | |||
+ | class FraktalerBaum extends Turtle { | ||
+ | |||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | super(x, y); | ||
+ | this.faktor = faktor; | ||
+ | this.winkel = winkel; | ||
+ | setBorderWidth(2); | ||
+ | turn(90); | ||
+ | zeichneAst(tiefe, | ||
+ | } | ||
+ | |||
+ | void zeichneAst(int n, double länge) { | ||
+ | if(n == 0) return; | ||
+ | |||
+ | forward(länge); | ||
+ | turn(winkel); | ||
+ | zeichneAst(n - 1, länge * faktor); | ||
+ | turn(-2*winkel); | ||
+ | zeichneAst(n - 1, länge * faktor); | ||
+ | turn(winkel); | ||
+ | turn(180); | ||
+ | penUp(); | ||
+ | forward(länge); | ||
+ | turn(180); | ||
+ | penDown(); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | </ | ||
+ | |||
+ | </ |