Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende Überarbeitung | |||
schule:klassen:2017:10b:kap10 [2018/06/13 09:00] – [Bessere Implementierung durch Nutzung von Vererbung] martin | schule:klassen:2017:10b:kap10 [2021/12/29 10:40] (aktuell) – Externe Bearbeitung 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | ====== Kapitel 10: Vererbung ====== | ||
+ | {{: | ||
+ | In einem kleinen Demo-Programm bewegen sich Autos und Motorräder von links nach rechts über das Fenster. Zusätzlich fliegen Sterne in Parabelbahnen. | ||
+ | |||
+ | ===== a) Schlechte Implementierung ===== | ||
+ | Es bietet sich an, Klassen '' | ||
+ | * ständig neue bewegte Objekte instanziert werden, | ||
+ | * alle auf dem Bildschirm befindlichen Objekte ständig weiterbewegt werden und | ||
+ | * alle Objekte, die aus dem Bildschirm herausfliegen, | ||
+ | |||
+ | ==== Klasse Stern ==== | ||
+ | <code java> | ||
+ | public class Stern { | ||
+ | |||
+ | private Sprite sprite; | ||
+ | |||
+ | private double vx, vy, ay; | ||
+ | |||
+ | public Stern(double x, double y) { | ||
+ | this.vx = Math.random() * 6 - 3; | ||
+ | this.vy = Math.random() * (-15) - 5; | ||
+ | this.ay = 0.3; | ||
+ | |||
+ | sprite = new Sprite("/ | ||
+ | sprite.strecken(0.2); | ||
+ | |||
+ | } | ||
+ | |||
+ | public void zeitschritt(){ | ||
+ | |||
+ | vy += ay; | ||
+ | |||
+ | if(sprite != null) { | ||
+ | sprite.verschieben(vx, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public boolean istAußerhalbDesFensters(){ | ||
+ | return sprite.istAußerhalbDesFensters(); | ||
+ | } | ||
+ | |||
+ | public void vernichten(){ | ||
+ | sprite.vernichten(); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Klasse Auto ==== | ||
+ | <code java> | ||
+ | public class Auto { | ||
+ | |||
+ | private Sprite sprite; | ||
+ | |||
+ | private double vx, vy, ay; | ||
+ | |||
+ | public Auto(double x, double y) { | ||
+ | this.vx = Math.random() * 3 + 1; | ||
+ | this.vy = 0; | ||
+ | this.ay = 0; | ||
+ | |||
+ | sprite = new Sprite("/ | ||
+ | sprite.strecken(0.2); | ||
+ | |||
+ | } | ||
+ | |||
+ | public void zeitschritt(){ | ||
+ | |||
+ | vy += ay; | ||
+ | |||
+ | if(sprite != null) { | ||
+ | sprite.verschieben(vx, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public boolean istAußerhalbDesFensters(){ | ||
+ | return sprite.istAußerhalbDesFensters(); | ||
+ | } | ||
+ | |||
+ | |||
+ | public void vernichten(){ | ||
+ | sprite.vernichten(); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Klasse Motorrad ==== | ||
+ | <code java> | ||
+ | public class Motorrad { | ||
+ | |||
+ | private Sprite sprite; | ||
+ | |||
+ | private double vx, vy, ay; | ||
+ | |||
+ | public Motorrad(double x, double y) { | ||
+ | this.vx = Math.random() * 6 + 2; | ||
+ | this.vy = 0; | ||
+ | this.ay = 0; | ||
+ | |||
+ | sprite = new Sprite("/ | ||
+ | sprite.strecken(0.2); | ||
+ | |||
+ | } | ||
+ | |||
+ | public void zeitschritt(){ | ||
+ | |||
+ | vy += ay; | ||
+ | |||
+ | if(sprite != null) { | ||
+ | sprite.verschieben(vx, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public boolean istAußerhalbDesFensters(){ | ||
+ | return sprite.istAußerhalbDesFensters(); | ||
+ | } | ||
+ | |||
+ | public void vernichten(){ | ||
+ | sprite.vernichten(); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Klasse AnimationStarter ==== | ||
+ | <code java> | ||
+ | public class AnimationStarter implements TimerListener { | ||
+ | |||
+ | private ArrayList< | ||
+ | private ArrayList< | ||
+ | private ArrayList< | ||
+ | |||
+ | int i = 0; | ||
+ | |||
+ | public static void main(String[] args) { | ||
+ | |||
+ | new AnimationStarter().start(); | ||
+ | |||
+ | } | ||
+ | |||
+ | private void start() { | ||
+ | |||
+ | Fenster f = new Fenster(800, | ||
+ | |||
+ | Timer timer = new Timer(this, 20); | ||
+ | timer.start(); | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | @Override | ||
+ | public void timerSignalVerarbeiten() { | ||
+ | |||
+ | i++; | ||
+ | if(i % 10 == 0){ | ||
+ | sterne.add(new Stern(300, 600)); | ||
+ | autos.add(new Auto(0, Math.random() * 600)); | ||
+ | motorräder.add(new Motorrad(0, Math.random() * 600)); | ||
+ | } | ||
+ | |||
+ | for(int i = 0; i < autos.size(); | ||
+ | Auto a = autos.get(i); | ||
+ | if(a.istAußerhalbDesFensters()){ | ||
+ | autos.remove(a); | ||
+ | a.vernichten(); | ||
+ | } | ||
+ | a.zeitschritt(); | ||
+ | } | ||
+ | |||
+ | for(int i = 0; i < sterne.size(); | ||
+ | Stern s = sterne.get(i); | ||
+ | if(s.istAußerhalbDesFensters()){ | ||
+ | sterne.remove(s); | ||
+ | s.vernichten(); | ||
+ | } | ||
+ | s.zeitschritt(); | ||
+ | } | ||
+ | |||
+ | for(int i = 0; i < motorräder.size(); | ||
+ | Motorrad m = motorräder.get(i); | ||
+ | if(m.istAußerhalbDesFensters()){ | ||
+ | motorräder.remove(m); | ||
+ | m.vernichten(); | ||
+ | } | ||
+ | m.zeitschritt(); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Bewertung der Implementierung ==== | ||
+ | Die Implementierung hat folgende Nachteile: | ||
+ | * Große Teile des Codes in den Klassen '' | ||
+ | * Die Erstellung der Klassen ist recht zeitaufwändig | ||
+ | * Will man etwas in den betroffenen Codeblöcken ändern, so muss man die Änderungen in allen drei Klassen vornehmen | ||
+ | * In der Klasse '' | ||
+ | |||
+ | ===== Bessere Implementierung durch Nutzung von Vererbung ===== | ||
+ | Die gemeinsamen Methoden und Attribute der Klassen '' | ||
+ | <WRAP center round info 60%> | ||
+ | * Dass eine Klasse von einer anderen Klasse (' | ||
+ | * Der Konstruktor der Basisklasse lässt sich aus dem Konstruktor der abgeleiteten Klasse mit den Schlüsselwort **super** aufrufen, siehe die nachfolgenden Quelltexte. | ||
+ | </ | ||
+ | |||
+ | ==== Die Klasse BewegteFigur ==== | ||
+ | <code java> | ||
+ | public class BewegteFigur { | ||
+ | |||
+ | private Sprite sprite; | ||
+ | |||
+ | private double vx, vy, ay; | ||
+ | |||
+ | public BewegteFigur(String dateiname, double x, double y, double vx, double vy, double ay) { | ||
+ | this.vx = vx; | ||
+ | this.vy = vy; | ||
+ | this.ay = ay; | ||
+ | |||
+ | sprite = new Sprite(dateiname, | ||
+ | sprite.strecken(0.2); | ||
+ | |||
+ | } | ||
+ | |||
+ | public void zeitschritt(){ | ||
+ | |||
+ | vy += ay; | ||
+ | |||
+ | if(sprite != null) { | ||
+ | sprite.verschieben(vx, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public boolean istAußerhalbDesFensters(){ | ||
+ | return sprite.istAußerhalbDesFensters(); | ||
+ | } | ||
+ | |||
+ | public void vernichten(){ | ||
+ | sprite.vernichten(); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Die Klasse SternNeu ==== | ||
+ | <code java> | ||
+ | public class SternNeu extends BewegteFigur { | ||
+ | |||
+ | public SternNeu(double x, double y){ | ||
+ | // Aufruf des Konstruktors der Basisklasse BewegteFigur: | ||
+ | super("/ | ||
+ | Math.random() * 6 - 3, Math.random() * (-15) - 5, | ||
+ | 0.3); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Die Klasse AutoNeu ==== | ||
+ | <code java> | ||
+ | public class AutoNeu extends BewegteFigur { | ||
+ | |||
+ | public AutoNeu(double x, double y){ | ||
+ | super("/ | ||
+ | Math.random() * 3 + 1, 0,0); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Die Klasse MotorradNeu ==== | ||
+ | <code java> | ||
+ | public class MotorradNeu extends BewegteFigur { | ||
+ | |||
+ | public MotorradNeu(double x, double y){ | ||
+ | super("/ | ||
+ | Math.random() * 6 + 2, 0,0); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Die Klasse AnimationStarterNeu==== | ||
+ | <code java> | ||
+ | public class AnimationStarterNeu implements TimerListener { | ||
+ | |||
+ | private ArrayList< | ||
+ | |||
+ | int i = 0; | ||
+ | |||
+ | public static void main(String[] args) { | ||
+ | |||
+ | new AnimationStarterNeu().start(); | ||
+ | |||
+ | } | ||
+ | |||
+ | private void start() { | ||
+ | |||
+ | Fenster f = new Fenster(800, | ||
+ | |||
+ | Timer timer = new Timer(this, 20); | ||
+ | timer.start(); | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | @Override | ||
+ | public void timerSignalVerarbeiten() { | ||
+ | |||
+ | i++; | ||
+ | if(i % 10 == 0){ | ||
+ | figuren.add(new SternNeu(300, | ||
+ | figuren.add(new AutoNeu(0, Math.random() * 600)); | ||
+ | figuren.add(new MotorradNeu(0, | ||
+ | } | ||
+ | |||
+ | for(int i = 0; i < figuren.size(); | ||
+ | BewegteFigur f = figuren.get(i); | ||
+ | if(f.istAußerhalbDesFensters()){ | ||
+ | figuren.remove(f); | ||
+ | f.vernichten(); | ||
+ | } | ||
+ | f.zeitschritt(); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | } | ||
+ | </ | ||