Inhaltsverzeichnis

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 Stern, Auto und Motorrad für die bewegten Objekte zu erstellen sowie eine zusätzliche Klasse AnimationStarter, in der

Klasse Stern

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();
    }
 
}

Klasse Auto

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();
    }
 
}

Klasse Motorrad

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();
    }
 
}

Klasse AnimationStarter

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();
        }
 
    }
}

Bewertung der Implementierung

Die Implementierung hat folgende Nachteile:

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.

  • 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.

Die Klasse BewegteFigur

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();
    }
 
}

Die Klasse SternNeu

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);
    }
 
}

Die Klasse AutoNeu

public class AutoNeu extends BewegteFigur {
 
    public AutoNeu(double x, double y){
        super("/vererbung/car2.png", x, y,
                Math.random() * 3  + 1, 0,0);
    }
 
}

Die Klasse MotorradNeu

public class MotorradNeu extends BewegteFigur {
 
    public MotorradNeu(double x, double y){
        super("/vererbung/motorbike.png", x, y,
                Math.random() * 6  + 2, 0,0);
    }
 
}

Die Klasse AnimationStarterNeu

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();
        }
 
    }
}