Skript Spiel -Text Vererbung

Werbung
Kü /Info Oberstufe
OOP - Spieleprogrammierung
SJ 2015/2016
Was ist Vererbung und warum sollte man das verwenden?
 Video:
o http://perm.ly/oop-vererbung
o http://perm.ly/oop-vererbung-ii
Es ist sehr unbefriedigend, große Programmtextabschnitte durch Kopieren in andere Klassen
zu übertragen, ohne dass in weiten Teilen auch nur eine Zeile geändert wird (will man nachträglich z.B. dort etwas ändern, so muss man das an vielen Stellen tun und verliert schnell
den Überblick). Absolut naheliegend ist, diese Abschnitte in eine eigene „Datei“
auszugliedern, um dann jedes Mal darauf zuzugreifen (oder dafür eigene Prozeduren zu benennen). In der OO ist das geeignete Mittel dafür aber keine Datei, sondern eine neue Klasse.
Das ist aber nicht nur einfach eine andere Schreibweise, dahinter steckt viel mehr – es geht
um eine neue Art von Abstraktion.
Beispiel:
Die Spielerklassen bisher beschreiben konkrete Objekte. Nun wird aber von allen Spielerklassen eine übergeordnete Klasse Spieler geschaffen, die alle Attribute und Methoden enthält,
die die nun untergeordneten konkreten Spielerklassen gemeinsam hatten. Diese übergeordnete Klasse Spieler beschreibt selbst kein konkretes Objekt (was genau sollte den ein Spieler
auch sein ), sie ist wie eine Art „Sammeleimer“ für alle Attribute und Methoden, die die
Unterklassen gemeinsam brauchen.
Dadurch muss man die Attribute und Methoden nun nur noch einmal in der Oberklasse
schreiben und die Unterklassen können dann automatisch darauf zugreifen (mit einer Einschränkung: die Attribute und Methoden müssen public oder protected sein, sind sie auf private
gesetzt, so kann eine Unterklasse nicht darauf zugreifen). In den konkreten Spielerklassen
wie Kugel und Kachel selbst stehen nur noch die Attribute und Methoden, die nur die spezielle Klasse selbst benötigt.
Kü /Info Oberstufe
OOP - Spieleprogrammierung
SJ 2015/2016
abstract
Beschreibt die Oberklasse so wie hier selbst kein konkretes Objekt, sondern ist nur ein „abstrakter“ Sammel-Eimer, so wird die Oberklasse auch als abstract gekennzeichnet. Man verhindert dadurch, dass von ihr konkrete Objekte gebildet werden können. In unserem Fall ist
das auch sinnvoll, denn sie dient nur dem Sammeln von Attributen und Methoden, aber ein
allgemeines „Spieler-Objekt kann die Leinwand gar nicht verarbeiten, es darf also auch nicht
erzeugt werden.
Wichtig: eine Oberklasse, die als „abstract“ gekennzeichnet ist, muss mindestens eine abstrakte Methode haben – d.h. eine Methode, die nicht in dieser Klasse selbst implementiert
wird, dafür aber durch ihre Kennzeichnung als „abstract“ erzwingt, dass jede Unterklasse sie
implementier (siehe Kapitel Probleme…)t.
Bsp.: public abstract void test(); <-ohne geschweifte Klammer, nur die Signatur und dann
ein Semikolon
protected/public
Gegenüber der Methode getForm() der ursprünglichen Klassendefinition hat
sich außerdem die Angabe zur Sichtbarkeit geändert. Weshalb das notwendig ist, kann
man leicht feststellen, wenn man es bei private belässt: Bei dieser Definition kann die
Methode, die nun in einer anderen Klasse steht, nicht aufgerufen werden. protected
macht eine Methode innerhalb des gesamten Paketes sichtbar, nicht aber nach außen (dafür müsste es auf public gesetzt sein).
extends
Es ergibt sich das Problem, dass unser Projekt nun zwar eine neue Klasse hat, BlueJ und
JAVA aber nichts davon wissen, dass die Spielerklassen ihre Attribute und Methoden von
der Klasse Spieler erben sollen. Das müssen wir in den Klassentext einarbeiten. Der Kopf
wird ergänzt um extends Spieler .
Nun weiß JAVA beim Übersetzen, dass es dort nach den fehlenden Attributen und Methoden
nachsehen kann.
Probleme, die entstehen, wenn man mit einer Oberklasse Moebel arbeitet
Wenn wir die gemeinsamen Methoden in die neue Klasse Spieler ausgegliedert haben und die
verkürzte Methode getForm() in der konkreten Spielerklasse – z.B. Kugel– verblieben ist, dann
kennt die Klasse Spieler die Methode getForm() nicht. Es gibt aber Methoden in Spieler, die
darauf zugreifen! Das muss zu einem Fehler führen. Wir können das auf zwei Arten lösen:
1. Wir erstellen eine eigene Methode getForm() in Spieler, die nichts tut (z.B. leer). In diesem Fall wird die Methode von Spieler durch die erbende Klasse überschrieben.
2. Wir erstellen einen reinen Methodenkopf und fügen ihm das Wort abstract hinzu. In
diesem Fall wird unsere Klasse aber notwendig eine abstrakte Klasse, also eine Klasse, von der keine Objekte erzeugt werden können. Viele andere Beispiele für die unter 2. beschriebene Variante finden wir in den von uns verwendeten Grafikklassen,
z.B. Ellipse2D, von der selbst keine Objekte erzeugt werden, sondern nur von Ellipse2D.Double und Ellipse2D.Float
Kü /Info Oberstufe
OOP - Spieleprogrammierung
SJ 2015/2016
Merke: In einer Klasse, die als abstract definiert ist, können Methoden ebenfalls als
abstract definiert werden. In diesem Falle braucht man für die Methode keine konkrete Implementierung angeben, es reicht der Methodenkopf. Die konkrete Implementierung muss dann aber in allen Unterklassen erfolgen.
Beachte: die Methodensuche fängt immer in der Klasse des gerade betrachteten
Objektes an und arbeitet sich dann von Oberklasse zu Oberklasse nach oben hin vor,
bis sie eine Methode gefunden hat, die passt. Findet man auf dem Vererbungsweg
keine passende Methode (also sowohl in der Klasse, in der sie aufgerufen wurde, also auch in einer der Oberklassen), so gibt es eine Fehlermeldung.
Die verbleibende Klassendefinition von Kugel ist dann nur noch sehr kurz:
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
public class Kugel extends Spieler
public Kugel(){
this.farbe= "green";
this.radius=30.0;
this.entfernen=false;
this.xPosition = 150.0;
this.yPosition = 50.0;
this.orientierung=90;
this.istSichtbar = true;
}
public Shape getForm(){
Ellipse2D.Double kreis = new Ellipse2D.Double(xPosition,
yPosition, this.radius, this.radius);
return kreis;
}
}
Herunterladen