# Abstrakte Klasse



## lucyyy (17. Jan 2021)

Guten Tag,

Folgende Aufgabe habe ich bekommen: 
Lösche in allen existierenden konkreten Testklassen (in den Subklassen, nicht in BasisSpielfeldTest) den Konstruktor. Warum funktioniert das? Schreibe die Antwort als Kommentar in die Testklasse. Du wirst jetzt wieder einen Fehler in den konkreten Subklassen erhalten. Wie kannst Du diesen Fehler sinnvoll beheben? Behebe den Fehler entsprechend. Lösche jetzt allen redundanten Code in den Subklassen. Sehe Dir das Ergebnis an. Was hältst Du davon?

Dabei wollte ich fragen, was denn generell redundanter Code von Subklassen von abstrakten Klassen ist?
Ich habe schon versucht die Methoden bei den Subklassen zu entfernen, allerdings können Diese dann nicht mehr die Methode ausführen und es entsteht ein Fehler.


----------



## httpdigest (17. Jan 2021)

lucyyy hat gesagt.:


> Dabei wollte ich fragen, was denn generell redundanter Code von Subklassen von abstrakten Klassen ist?


Also das Wort "redundant" heisst "überflüssig, unnötig, nicht länger benötigt".
Im Kontext von Subclassing könnte das bedeuten, dass in einer Subklasse dieselbe Methodendefinition wie in der Oberklasse existiert (selbe Signatur der Methode und selbe Implementierung). Diese Methode wäre dann in der Subklasse redundant, weil sie ja dasselbe macht wie die Oberklassenmethode, von der sie erbt.
Für konkretere Hilfestellung müsste man schon Code haben.


----------



## lucyyy (17. Jan 2021)

Ah okay.
Hier ist einmal der Code der Superklasse:

[CODE lang="java" title="Superklasse"]import static org.junit.Assert.*;
import org.junit.Test;

/**
 * Eine Testklasse fuer Spielfeld-Klassen.
 */
abstract class BasisSpielfeldTest {
    private Spielfeld _spielfeld;

    /**
     * Jede Testmethode arbeitet auf einem frisch erzeugten Test-Exemplar. Im
     * Konstruktor kann man also den erforderlichen Ausgangszustand fuer die
     * einzelnen Testmethoden herstellen, in diesem Fall ein neues Spielfeld.
     */
    public BasisSpielfeldTest() {
        erzeugeSpielfeld();
    }

    /**
      * Diese abstrakte Methode ist für die Spielfelderzeugung zustaendig.
      * Allerdings wird hier kein Spielfeld erzeugt!
      */
    public abstract void erzeugeSpielfeld();

    /**
     * Wenn alle Positionen besetzt sind, solle das Spielfeld voll sein. Vorher
     * sollte es immer eine freie Position geben.
     */
    @Test
    public void testBefuelleSpielfeldKomplett() {
        for (int zeile = 0; zeile < 3; ++zeile) {
            for (int spalte = 0; spalte < 3; ++spalte) {
                assertFalse(_spielfeld.istVoll());
                _spielfeld.besetzePosition(zeile, spalte, 1);
            }
        }
        assertTrue(_spielfeld.istVoll());
    }

    /**
     * Wenn alle Positionen besetzt sind, solle das Spielfeld voll sein. Vorher
     * sollte es immer eine freie Position geben. Dieser Test befuellt das Spielfeld
     * von hinten nach vorne.
     */
    @Test
    public void testBefuelleSpielfeldKomplettRueckwaerts() {
        for (int zeile = 2; zeile >= 0; --zeile) {
            for (int spalte = 2; spalte >= 0; --spalte) {
                assertFalse(_spielfeld.istVoll());
                _spielfeld.besetzePosition(zeile, spalte, 1);
            }
        }
        assertTrue(_spielfeld.istVoll());
    }

    /**
     * Wenn neun Mal dieselbe Position besetzt wird, sollte das Spielfeld nicht voll
     * sein.
     */
    @Test
    public void testBesetzeNeunMalDieselbePosition() {
        for (int i = 0; i < 9; ++i) {
            _spielfeld.besetzePosition(0, 0, 1);
        }
        assertFalse(_spielfeld.istVoll());
    }

    /**
     * Teste, ob alle Zellen des Spielfeldes mit allen moeglichen Belegungen (0, 1
     * und 2) belegt werden koennen.
     */
    @Test
    public void testeBelegbarkeitAllerZellen() {
        for (int zeile = 0; zeile < 3; ++zeile) {
            for (int spalte = 0; spalte < 3; ++spalte) {
                assertEquals(0, _spielfeld.gibBesitzer(zeile, spalte));

                _spielfeld.besetzePosition(zeile, spalte, 1);
                assertEquals(1, _spielfeld.gibBesitzer(zeile, spalte));

                _spielfeld.besetzePosition(zeile, spalte, 2);
                assertEquals(2, _spielfeld.gibBesitzer(zeile, spalte));

                _spielfeld.besetzePosition(zeile, spalte, 0);
                assertEquals(0, _spielfeld.gibBesitzer(zeile, spalte));
            }
        }
    }
}
[/CODE]

Und hier einmal der Subklasse:

[CODE lang="java" title="Subklasse"]import static org.junit.Assert.*;
import org.junit.Test;

/**
 * Eine Testklasse fuer Spielfeld-Klassen.
 *
 */
public class SpielfeldStringTest extends BasisSpielfeldTest{
    private Spielfeld _spielfeld;

    /**
     * Hier wird ein Spielfeld erzeugt.
     */
    @Override
    public void erzeugeSpielfeld(){
        _spielfeld = new SpielfeldString();
    }

    /**
     * Wenn alle Positionen besetzt sind, solle das Spielfeld voll sein. Vorher
     * sollte es immer eine freie Position geben.
     */
    @Test
    public void testBefuelleSpielfeldKomplett() {
        for (int zeile = 0; zeile < 3; ++zeile) {
            for (int spalte = 0; spalte < 3; ++spalte) {
                assertFalse(_spielfeld.istVoll());
                _spielfeld.besetzePosition(zeile, spalte, 1);
            }
        }
        assertTrue(_spielfeld.istVoll());
    }

    /**
     * Wenn alle Positionen besetzt sind, solle das Spielfeld voll sein. Vorher
     * sollte es immer eine freie Position geben. Dieser Test befuellt das Spielfeld
     * von hinten nach vorne.
     */
    @Test
    public void testBefuelleSpielfeldKomplettRueckwaerts() {
        for (int zeile = 2; zeile >= 0; --zeile) {
            for (int spalte = 2; spalte >= 0; --spalte) {
                assertFalse(_spielfeld.istVoll());
                _spielfeld.besetzePosition(zeile, spalte, 1);
            }
        }
        assertTrue(_spielfeld.istVoll());
    }

    /**
     * Wenn neun Mal dieselbe Position besetzt wird, sollte das Spielfeld nicht voll
     * sein.
     */
    @Test
    public void testBesetzeNeunMalDieselbePosition() {
        for (int i = 0; i < 9; ++i) {
            _spielfeld.besetzePosition(0, 0, 1);
        }
        assertFalse(_spielfeld.istVoll());
    }

    /**
     * Teste, ob alle Zellen des Spielfeldes mit allen moeglichen Belegungen (0, 1
     * und 2) belegt werden koennen.
     */
    @Test
    public void testeBelegbarkeitAllerZellen() {
        for (int zeile = 0; zeile < 3; ++zeile) {
            for (int spalte = 0; spalte < 3; ++spalte) {
                assertEquals(0, _spielfeld.gibBesitzer(zeile, spalte));

                _spielfeld.besetzePosition(zeile, spalte, 1);
                assertEquals(1, _spielfeld.gibBesitzer(zeile, spalte));

                _spielfeld.besetzePosition(zeile, spalte, 2);
                assertEquals(2, _spielfeld.gibBesitzer(zeile, spalte));

                _spielfeld.besetzePosition(zeile, spalte, 0);
                assertEquals(0, _spielfeld.gibBesitzer(zeile, spalte));
            }
        }
    }
}
[/CODE]


----------



## httpdigest (17. Jan 2021)

Gut, womit mein Punkt in meinem ersten Post ja mal validiert wurde.


> dass in einer Subklasse dieselbe Methodendefinition wie in der Oberklasse existiert (selbe Signatur der Methode und selbe Implementierung).


Du merkst also hoffentlich schon, dass ALLE Methoden in der Subklasse eine EXAKTE Kopie der Methoden der Oberklasse sind?


----------



## lucyyy (17. Jan 2021)

httpdigest hat gesagt.:


> Gut, womit mein Punkt in meinem ersten Post ja mal validiert wurde.
> 
> Du merkst also hoffentlich schon, dass ALLE Methoden in der Subklasse eine EXAKTE Kopie der Methoden der Oberklasse sind?


Ja. Kann ich diese Methoden dann in der Subklasse komplett entfernen oder muss ich noch pro Methode eine Zeile stehen haben, wie zum Beipsiel this.befuelleSpielfeldKomplett();


----------



## lucyyy (18. Jan 2021)

Wenn ich die Methoden entferne, besteht die Klasse den Test nicht. 
Ich weiß aber auch nicht, wo dabei das Problem dann liegt.


----------

