Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
schule:klassen:2017:10b:kap10 [2018/06/13 11:00] – [Bessere Implementierung durch Nutzung von Vererbung] martinschule:klassen:2017:10b:kap10 [2021/12/29 11:40] (aktuell) – Externe Bearbeitung 127.0.0.1
Zeile 1: Zeile 1:
 +====== Kapitel 10: Vererbung ======
 +{{:schule:klassen:2017:10b:pasted:20180613-101206.png?300}}
 +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 ''Stern'', ''Auto'' und ''Motorrad'' für die bewegten Objekte zu erstellen sowie eine zusätzliche Klasse ''AnimationStarter'', in der 
 +  * 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, vernichtet werden.
 +
 +==== 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("/vererbung/star.png", x, y);
 +        sprite.strecken(0.2);
 +
 +    }
 +
 +    public void zeitschritt(){
 +
 +        vy += ay;
 +
 +        if(sprite != null) {
 +            sprite.verschieben(vx, vy);
 +        }
 +    }
 +
 +    public boolean istAußerhalbDesFensters(){
 +        return sprite.istAußerhalbDesFensters();
 +    }
 +
 +    public void vernichten(){
 +        sprite.vernichten();
 +    }
 +
 +}
 +</code>
 +
 +==== 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("/vererbung/car2.png", x, y);
 +        sprite.strecken(0.2);
 +
 +    }
 +
 +    public void zeitschritt(){
 +
 +        vy += ay;
 +
 +        if(sprite != null) {
 +            sprite.verschieben(vx, vy);
 +        }
 +    }
 +
 +    public boolean istAußerhalbDesFensters(){
 +        return sprite.istAußerhalbDesFensters();
 +    }
 +
 +
 +    public void vernichten(){
 +        sprite.vernichten();
 +    }
 +
 +}
 +</code>
 +
 +==== 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("/vererbung/motorbike.png", x, y);
 +        sprite.strecken(0.2);
 +
 +    }
 +
 +    public void zeitschritt(){
 +
 +        vy += ay;
 +
 +        if(sprite != null) {
 +            sprite.verschieben(vx, vy);
 +        }
 +    }
 +
 +    public boolean istAußerhalbDesFensters(){
 +        return sprite.istAußerhalbDesFensters();
 +    }
 +
 +    public void vernichten(){
 +        sprite.vernichten();
 +    }
 +
 +}
 +</code>
 +
 +==== Klasse AnimationStarter ====
 +<code java>
 +public class AnimationStarter implements TimerListener {
 +
 +    private ArrayList<Stern> sterne = new ArrayList<>();
 +    private ArrayList<Auto> autos = new ArrayList<>();
 +    private ArrayList<Motorrad> motorräder = new ArrayList<>();
 +
 +    int i = 0;
 +
 +    public static void main(String[] args) {
 +
 +        new AnimationStarter().start();
 +
 +    }
 +
 +    private void start() {
 +
 +        Fenster f = new Fenster(800, 750);
 +
 +        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(); i++){
 +            Auto a = autos.get(i);
 +            if(a.istAußerhalbDesFensters()){
 +                autos.remove(a);
 +                a.vernichten();
 +            }
 +            a.zeitschritt();
 +        }
 +
 +        for(int i = 0; i < sterne.size(); i++){
 +            Stern s = sterne.get(i);
 +            if(s.istAußerhalbDesFensters()){
 +                sterne.remove(s);
 +                s.vernichten();
 +            }
 +            s.zeitschritt();
 +        }
 +
 +        for(int i = 0; i < motorräder.size(); i++){
 +            Motorrad m = motorräder.get(i);
 +            if(m.istAußerhalbDesFensters()){
 +                motorräder.remove(m);
 +                m.vernichten();
 +            }
 +            m.zeitschritt();
 +        }
 +
 +    }
 +}
 +</code>
 +
 +==== Bewertung der Implementierung ====
 +Die Implementierung hat folgende Nachteile:
 +  * Große Teile des Codes in den Klassen ''Stern'', ''Auto'' und ''Motorrad'' sind identisch.
 +    * 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 ''AnimationStarter'' müssen für Autos, Sterne und Motorräder jeweils extra Listen geführt werden. Dies hat zur Folge, dass sich in der Methode ''timerSignalVerarbeiten'' große Teile des Codes wiederholen.
 +
 +===== Bessere Implementierung durch Nutzung von Vererbung =====
 +Die gemeinsamen Methoden und Attribute der Klassen ''Stern'', ''Auto'' und ''Motorrad'' packen wir in eine **Basisklasse** ''BewegteFigur''. Die Klassen ''Stern'', ''Auto'' und ''Motorrad'' leiten wir dann von ''BewegteFigur'' ab, d.h. sie **erben** alle Attribute und Methoden der Basisklasse.
 +<WRAP center round info 60%>
 +  * Dass eine Klasse von einer anderen Klasse ('**Basisklasse**') abgeleitet ist, wird durch das Schlüsselwort **extends** ausgedrückt.
 +  * Der Konstruktor der Basisklasse lässt sich aus dem Konstruktor der abgeleiteten Klasse mit den Schlüsselwort **super** aufrufen, siehe die nachfolgenden Quelltexte.
 +</WRAP>
 +
 +==== 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, x, y);
 +        sprite.strecken(0.2);
 +
 +    }
 +
 +    public void zeitschritt(){
 +
 +        vy += ay;
 +
 +        if(sprite != null) {
 +            sprite.verschieben(vx, vy);
 +        }
 +    }
 +
 +    public boolean istAußerhalbDesFensters(){
 +        return sprite.istAußerhalbDesFensters();
 +    }
 +
 +    public void vernichten(){
 +        sprite.vernichten();
 +    }
 +
 +}
 +</code>
 +
 +==== Die Klasse SternNeu ====
 +<code java>
 +public class SternNeu extends BewegteFigur {
 +
 +    public SternNeu(double x, double y){
 +        // Aufruf des Konstruktors der Basisklasse BewegteFigur:
 +        super("/vererbung/star.png", x, y,
 +                Math.random() * 6 - 3, Math.random() * (-15) - 5,
 +                0.3);
 +    }
 +
 +}
 +</code>
 +
 +==== Die Klasse AutoNeu ====
 +<code java>
 +public class AutoNeu extends BewegteFigur {
 +
 +    public AutoNeu(double x, double y){
 +        super("/vererbung/car2.png", x, y,
 +                Math.random() * 3  + 1, 0,0);
 +    }
 +
 +}
 +</code>
 +
 +==== Die Klasse MotorradNeu ====
 +<code java>
 +public class MotorradNeu extends BewegteFigur {
 +
 +    public MotorradNeu(double x, double y){
 +        super("/vererbung/motorbike.png", x, y,
 +                Math.random() * 6  + 2, 0,0);
 +    }
 +
 +}
 +</code>
 +
 +==== Die Klasse AnimationStarterNeu====
 +<code java>
 +public class AnimationStarterNeu implements TimerListener {
 +
 +    private ArrayList<BewegteFigur> figuren = new ArrayList<>();
 +
 +    int i = 0;
 +
 +    public static void main(String[] args) {
 +
 +        new AnimationStarterNeu().start();
 +
 +    }
 +
 +    private void start() {
 +
 +        Fenster f = new Fenster(800, 750);
 +
 +        Timer timer = new Timer(this, 20);
 +        timer.start();
 +
 +    }
 +
 +
 +    @Override
 +    public void timerSignalVerarbeiten() {
 +
 +        i++;
 +        if(i % 10 == 0){
 +            figuren.add(new SternNeu(300, 600));
 +            figuren.add(new AutoNeu(0, Math.random() * 600));
 +            figuren.add(new MotorradNeu(0, Math.random() * 600));
 +        }
 +
 +        for(int i = 0; i < figuren.size(); i++){
 +            BewegteFigur f = figuren.get(i);
 +            if(f.istAußerhalbDesFensters()){
 +                figuren.remove(f);
 +                f.vernichten();
 +            }
 +            f.zeitschritt();
 +        }
 +
 +    }
 +}
 +</code>
  
Drucken/exportieren
QR-Code
QR-Code schule:klassen:2017:10b:kap10 (erstellt für aktuelle Seite)