Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
schule:klassen:2017:10b:kap10 [2018/06/13 10:58]
martin [Die Klasse SternNeu]
schule:klassen:2017:10b:kap10 [2018/06/13 11:00] (aktuell)
martin [Bessere Implementierung durch Nutzung von Vererbung]
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)