Unterklasse von World
BluePlay-Welt
Das Spielfeld funktioniert - aber es ist noch eine ganz gewöhnliche Klasse:
Es öffnet sich kein Spielfenster, und act wird nur ausgeführt, wenn man per
Rechtsklick auf das Objekt die Methode aufruft.
Beim Goldrausch-Projekt war das anders: Dort öffnete
show() ein Fenster mit Steuerleiste, und nach einem Klick auf
Start lief das Spiel von allein.
Der Grund: Beim Goldrausch-Projekt war die Klasse
Spielfeld eine Unterklasse der
BluePlay-Klasse World.
Unser Spielfeld hat bisher noch nichts mit World zu tun.
Wir müssen also erreichen, dass Spielfeld eine Unterklasse von
World wird,
oder umgekehrt ausgedrückt, dass World die
Oberklasse von Spielfeld wird.
World als Oberklasse
In Kotlin steht die Oberklasse mit einem Doppelpunkt hinter dem
Klassennamen.
Wenn der Konstruktor der Oberklasse Parameter erwartet, müssen diese in Klammern dahinter
angegeben werden.
Der Konstruktor der Klasse World erwartet drei Parameter: die Breite und die
Höhe des Spielfeldes in Zellen sowie die Größe einer Zelle in Pixeln.
class Spielfeld : World(600, 400, 1) {
...
}
Aufgabe 1
World zur Oberklasse deines Spielfelds und kompiliere.
Du bekommst eine Fehlermeldung, die die Methode act betrifft.
Lies sie genau: Was teilt dir der Compiler mit?
Überschreiben mit override
Die Fehlermeldung lautet:
'act' hides member of supertype 'World' and needs an 'override' modifier.
Die Klasse World besitzt nämlich selbst schon eine Methode mit
dem Namen act - und das Spielfeld hat sie geerbt.
Die eigene Methode act soll die geerbte Methode ersetzen.
Man sagt dazu auch: Sie überschreibt die geerbte Methode.
Kotlin verlangt dafür ausdrücklich das Schlüsselwort override:
override fun act() {
...
}
override schreibt,
und nicht overwrite:
override ist ein englisches Verb, das im Deutschen
außer Kraft setzen bedeutet.
Im Zusammenhang mit Vererbung übersetzt man es oft mit überschreiben.
Aufgabe 2
Ergänze das Schlüsselwort override
und kompiliere erneut.
Erzeuge ein Spielfeld-Objekt und rufe seine geerbte Methode
show() auf - du findest sie wie beim Goldrausch-Projekt
im Untermenü inherited from World.
Starte das Spiel mit dem Start-Knopf und beobachte das Terminal.
Erkläre, warum act jetzt von allein läuft, vorher aber nicht.
Geerbte Methoden nutzen
Als Unterklasse besitzt das Spielfeld nun alle Attribute und Methoden einer BluePlay-Welt. Im Klassendiagramm stellt man die Vererbung mit einem Pfeil dar, der ein dreieckiges Ende hat und von der Unterklasse zur Oberklasse zeigt.
Das folgende Klassendiagramm zeigt einen Ausschnitt der beiden
Klassen. Spielfeld erbt die oben eingetragenen Attribute und
Methoden von World. Das Attribut schritte kommt in
Spielfeld neu hinzu; die geerbte Methode act() wird
dort überschrieben.
Ausgabe auf dem Spielfeld
Die Ausgabe der Schritte im Terminal ist unpraktisch - schöner wäre sie
direkt auf dem Spielfeld.
Auch dafür besitzt das Spielfeld eine geerbte Methode:
showText(text, x, y) zeigt einen Text an der Position
(x, y) an.
Der naheliegende Versuch sieht so aus:
showText(schritte, 100, 50)
Das lässt sich allerdings nicht kompilieren:
argument type mismatch: actual type is 'Int', but 'String' was expected.
Aufgabe 3
Vorschläge zur Behebung
Hier sind vier Vorschläge, wie man das Problem lösen könnte:
// Vorschlag 1
showText("schritte", 100, 50)
// Vorschlag 2
showText("$schritte", 100, 50)
// Vorschlag 3
showText(schritte.toString(), 100, 50)
// Vorschlag 4
showText("Schritte: $schritte", 100, 50)
Aufgabe 4
act ein.
Falls du nicht mehr weißt, was es mit den Dollarzeichen der Vorschläge 2 und 4 auf sich hat, findest du Hilfe im Abschnitt Tipps zu Kotlin → Ausgabe.