# Wofür abstract?



## Reggie() (11. Aug 2011)

ich habe bisher in keinem Tut gefunden, was genau der Vorteil/Nutzen von einer abstrakten Klasse sein soll. Wenn ich den Teil Vererbung richtig verstanden habe, erben sub-klassen von den super-klassen, egal ob abstrakt oder nicht.

Reggie


----------



## njans (11. Aug 2011)

Jap, aber bei Abstrakten Klassen wirst du "gezwungen" die vollständig abstrakten Methoden zu implementieren (wie bei einem Interface), bist aber gleichzeitig in der Lage Methoden vollständig zu erstellen, so dass die erbende Klasse diese direkt verwenden kann.


----------



## Niki (11. Aug 2011)

erben tun sie alle, jedoch kannst du von einer abstrakten klasse keine instanz erstellen sondern MUSST vorher ableiten und die abstrakten methoden überschreiben. einige patterns machen davon gebrauch z.b. Template method pattern - Wikipedia, the free encyclopedia


----------



## Gregorrr (11. Aug 2011)

Reggie() hat gesagt.:


> ich habe bisher in keinem Tut gefunden, was genau der Vorteil/Nutzen von einer abstrakten Klasse sein soll. Wenn ich den Teil Vererbung richtig verstanden habe, erben sub-klassen von den super-klassen, egal ob abstrakt oder nicht.
> 
> Reggie



Abstrakte Basisklassen erlauben es vordefinierten Code, also Methoden, zu definieren, die in allen Unterklassen vorhanden sind, wie bei der normaler Vererbung. Allerdings können abstrakte Klassen auch abstrakte Methoden definieren, die von den Unterklassen, unbedingt implementiert werden müssen, d.h. das ist für Klassenspezifischen Code. Abstrakte Basisklassen kann man deswegen nicht instantiieren, da eine Implementierung nicht vorhanden sein muss. Das ist also ein Zwischending, zwischen Code-Wiederverwendung wie bei normaler Vererbung und Definition eines Typs wie bei Interfaces, ohne konkrete Implementierung angeben zu müssen.


----------



## maki (11. Aug 2011)

Reggie() hat gesagt.:


> ich habe bisher in keinem Tut gefunden, was genau der Vorteil/Nutzen von einer abstrakten Klasse sein soll. Wenn ich den Teil Vererbung richtig verstanden habe, erben sub-klassen von den super-klassen, egal ob abstrakt oder nicht.


Ja, aber mit dem Schlüsselwort abstract ist eben klar dass diese Klasse nicht zum Instanziieren gedacht war


----------



## muemmel_0811 (11. Aug 2011)

ich auch noch 

Stell Dir vor, Du hast folgende Klasse:

```
public abstract class Tier {
// irgendwas, was Tiere gemeinsam haben
}

public class Hund extends Tier {
}
```
Und warum ist die Klasse Tier nun abstract? Ganz einfach: stell Dir einfach die Frage, wie ein Tier aussieht. Ist es groß, klein, braun, lila usw. - schwierig. Im Gegensatz dazu ist ein Hund ein "greifbares" Objekt. Den kann man per Instanzvariablen so "beschreiben", dass es hinterher auch ein Hund ist und nicht eine bellend schwimmende Katze oder so.


----------



## Reggie() (11. Aug 2011)

keiner der oben stehenden Antworten beantwortet die eigentliche Frage
und


muemmel_0811 hat gesagt.:


> Stell Dir vor, Du hast folgende Klasse:
> 
> ```
> public abstract class Tier {
> ...


ist doch das selbe wie:

```
public class Tier {
// Oberklasse
}

public class Hund extends Tier {
// Unterklasse
}
```
vielleicht sollte ich die Frage umformulieren:
Was kann ich mit abstrakten Klassen tun, was ich mit normalen Ober- und Unterklassen nicht kann? 

Reggie


----------



## Michael... (11. Aug 2011)

Reggie() hat gesagt.:


> vielleicht sollte ich die Frage umformulieren:
> Was kann ich mit abstrakten Klassen tun, was ich mit normalen Ober- und Unterklassen nicht kann?


Die Frage ist falsch herum gestellt: Was kann ich mit abstrakten Klassen nicht tun was ich mit konkreten Klassen kann? ;-)
Antwort: abstrakte Klassen können nicht instanziiert werden.

Die Verwendung und Eigenschaften abstrakter Klassen wurden allerdings bereits erläutert.

Mit abstrakten Klassen wird eine Schnittstelle definiert. Genauso wie mit Interfaces nur mit dem Unterschied, dass eine abstrakte Klasse teilweise bereits implementierte Methoden besitzen kann.

Ist Dir denn der Sinn und Zweck von Interfaces bekannt? Das wäre eine Voraussetzung für das Verständnis von abstrakten Klassen.

Abstrakte Klassen werden auch gerne als Adaption von Interfaces genutzt, wenn es nicht unbedingt notwendig ist alle durch ein Interface definierten Methoden zu implementieren. (siehe z.B. MouseAdapter). Dadurch bleibt der Code übersichtlicher und der Programmierer muss nur die Methoden implementieren, die in auch tatsächlich interessieren.


----------



## Reggie() (11. Aug 2011)

Michael... hat gesagt.:


> Ist Dir denn der Sinn und Zweck von Interfaces bekannt? Das wäre eine Voraussetzung für das Verständnis von abstrakten Klassen.


Nein.
aber so wie ich das sehe brauche ich keine abstrakten Klassen.... zumindest bis ich mehr drauf habe :rtfm:

Reggie


----------



## Illuvatar (11. Aug 2011)

Reggie() hat gesagt.:


> und
> 
> 
> muemmel_0811 hat gesagt.:
> ...



Ok, dann tun wir zu muemmels Beispiel mal etwas Inhalt:

```
public abstract class Tier {
  public abstract int getNumberOfLegs();
  // noch mehr
}

public class Hund extends Tier {
  public int getNumberOfLegs() {
    return 4;
  }
  // auch noch mehr
}
```
Was machst du jetzt?


----------



## Reggie() (11. Aug 2011)

Illuvatar hat gesagt.:


> ```
> public class Tier {
> public int getNumberOfLegs();
> // noch mehr
> ...


ohne abstract sollte es doch genauso gehen, oder? wenn nicht, dann bitte erklärt es mir. ich will wirklich lernen.

Reggie


----------



## Marco13 (11. Aug 2011)

Man braucht keine abstrakten Klassen. Und manche Leute postulieren sogar, dass es keinen Grund gibt, sie zu benutzen. Man kann mit Interfaces+NormalenKlassen alles machen, was man auch mit abtrakten Klassen machen kann. Die Begründung, DOCH abstrakte Klassen zu verwenden, ist, lapidar formuliert: Sie sparen Arbeit. Am schon angedeuteten Beispiel:

```
interface Tier {
    void friß();
    void gibLaut();
}

class AbstraktesTier implements Tier {
    public void friß() {
        System.out.println("Nom, nom, nom..."); // Ist bei allen Tieren gleich
    }

    public abstract void gibLaut(); // Ist nach wie vor abstract
}

class Hund extends AbstraktesTier implements Tier {
    public void gibLaut() {
        System.out.println("Wuff");
    }
}

class Katze extends AbstraktesTier implements Tier {
    public void gibLaut() {
        System.out.println("Muuuhhhh");
    }
}
```

Die Methode "friß()" ist bei allen Tieren gleich, und kann deswegen in der abstrakten Klasse stehen. Man KÖNNTE die abstrakte Klasse auch weglassen, und stattdessen die Methode (zwei mal gleich!) in den konkreten Klassen implementieren.

Das ist etwas vereinfacht, aber darauf läuft's meistens raus. Trotzdem sollte man sich überlegen, wie und wo man Abstrakte Klassen verwendet. Sie können die Strukturen ein bißchen "unschöner" machen. Ein bißchen was steht dazu auch in Practical API Design: Confessions of ... - Google Books


----------



## muemmel_0811 (11. Aug 2011)

Reggie() hat gesagt.:


> ohne abstract sollte es doch genauso gehen, oder? wenn nicht, dann bitte erklärt es mir. ich will wirklich lernen.
> 
> Reggie


Nein, denn durch die abstrakte Methode gibLaut() - schau mal genau hin - da ist ein Semikolon hinter der Methode und keine geschweiften Klammern, muss die Klasse abstract sein. Und abstrakte Methoden bedeuten, dass die Erben der Klasse diese Methoden implementieren müssen. In unserem Fall müssen also alle konkreten Tiere diese Methode implementieren.
Jetzt klar?


----------



## TheDarkRose (11. Aug 2011)

Marco13 hat gesagt.:


> Man braucht keine abstrakten Klassen. Und manche Leute postulieren sogar, dass es keinen Grund gibt, sie zu benutzen. Man kann mit Interfaces+NormalenKlassen alles machen, was man auch mit abtrakten Klassen machen kann. Die Begründung, DOCH abstrakte Klassen zu verwenden, ist, lapidar formuliert: Sie sparen Arbeit. Am schon angedeuteten Beispiel:
> [...]
> Die Methode "friß()" ist bei allen Tieren gleich, und kann deswegen in der abstrakten Klasse stehen. Man KÖNNTE die abstrakte Klasse auch weglassen, und stattdessen die Methode (zwei mal gleich!) in den konkreten Klassen implementieren.
> 
> Das ist etwas vereinfacht, aber darauf läuft's meistens raus. Trotzdem sollte man sich überlegen, wie und wo man Abstrakte Klassen verwendet. Sie können die Strukturen ein bißchen "unschöner" machen. Ein bißchen was steht dazu auch in Practical API Design: Confessions of ... - Google Books



Warum haußt du da noch ein Interface dazwischen? Das macht es doch die Struktur erst unschon. Nur weil es vom Begriff eine Abstrakte Klasse ist, ist eine abstrakte Klasse von der Definition auch eine Schnittstellen Vereinbarung.



```
public abstract class AbstraktesTier {
    public void friß() {
        System.out.println("Nom, nom, nom..."); // Ist bei allen Tieren gleich
    }

    public abstract void gibLaut(); // Ist nach wie vor abstract
}

public class Hund extends AbstraktesTier {
    public void gibLaut() {
        System.out.println("Wuff");
    }
}

public class Katze extends AbstraktesTier {
    public void gibLaut() {
        System.out.println("Muuuhhhh");
    }
}
```
Das reicht ja vollkommen. Statt AbstraktesTier kann man auch einfach Tier schreiben


----------



## Marco13 (11. Aug 2011)

Genau das meinte ich mit der potentiell unschönen Struktur  OO-Nazis definieren eben ALLES erstmal als Interface. Eine Abstrakte Basisklasse als "Wurzel" der Vererbungshierarchie macht i.a. keinen Sinn - weil dadruch quasi das "erzwungen" wird, was bei der Hierarchie "Interface->Abstract->Impl" nur als unschöner Nebeneffekt auftritt: Es gibt Leute, die sich darauf verlassen, dass das, womit sie es da zu tun haben, von der Abstrakten Basisklasse erbt. Zumindest gibt es einige APIs, bei denen bestimmte abstrakte Basisklassen einfach "zu mächtig" sind (oder zu viele Methoden enthält, die eigentlich ins Wurzelinterface gepackt werden könnten oder sollten), und niemand mehr das Interface verwendet, sondern alle die abstrakte Klasse. 

Am konkreten Beispiel: Wenn ein Tier nun eine andere Implementierung von "friß" haben sollte, würde man die (einzige) konkrete Methode aus der abstrakten Klasse überschreiben, und sie damit ad absurdum führen, und ihre Funktion auf das reduzieren, was sie von vornherein hätte sein sollen: Ein Interface.


----------



## TheDarkRose (11. Aug 2011)

Architektonisch sind Interfaces und abstrakte Klassen das selbe, nämlich Schnittstellen. Ich finde es ad absurdum, wenn man für eine abstrakte klasse noch extrig ein Interface macht.


----------



## Marcinek (11. Aug 2011)

TheDarkRose hat gesagt.:


> Architektonisch sind Interfaces und abstrakte Klassen das selbe, nämlich Schnittstellen. Ich finde es ad absurdum, wenn man für eine abstrakte klasse noch extrig ein Interface macht.



Ich habe ein Interface "Remote", dieses wird hauptsächlich von einer abstrakten klasse implementiert. Also ich finde das nicht ganz absurd. Diese eine Klasse kann aber nicht alle Methoden implementieren.



Reggie() hat gesagt.:


> public class Tier {
> public int getNumberOfLegs();
> // noch mehr
> }
> ...



Nein das geht nicht. wenn du eine Instanz der Klasse Tier machen würdest, und dann die abstrakte Methode aufrufen würdest was dann?



Reggie() hat gesagt.:


> Nein.
> aber so wie ich das sehe brauche ich keine abstrakten Klassen.... zumindest bis ich mehr drauf habe
> 
> Reggie



Ja das stimmt. In einem kleinen Programm wird das sicher nicht notwendig sein. Wenn du etwas größeres programierst, dann wirst du ohne kaum auskommen. Es sei den du baust iwas, was nicht weit verbreitet werden soll und nix kostet ;D


----------



## Marco13 (12. Aug 2011)

TheDarkRose hat gesagt.:


> Architektonisch sind Interfaces und abstrakte Klassen das selbe, nämlich Schnittstellen. Ich finde es ad absurdum, wenn man für eine abstrakte klasse noch extrig ein Interface macht.



Sie können in gewissen Grenzen gleichwertig sein. Man könnte sagen, sie sind gleichwertig, wenn die abstrakte Klasse keine nicht-privaten Methoden hat, die nicht auch im Interface stehen würden. 

```
class AbstraktesTier {
    public void friß() { ... }
    public abstract void gibLaut();

    public void legDichInsKörbchen() { ... }
}
```
Das Funktioniert bei Hunden und Katzen, und jeder kann sich "Tier" holen und sich das Tier ins Körbchen Legen lassen, weil ... es ist ja ein AbstraktesTier. Bis jemand eine Kuh implementieren will.

Oder kurz: Ein Interface ist eine Schnittstelle. Eine Abstrakte Klasse ist eine Schnittstelle - UND (vielleicht) Implementierungen, die nicht notwendigerweise zur Schnittstelle gehören oder gehören sollten.


----------



## RySa (12. Aug 2011)

Also irgendwie hat der TO den Topic "verlassen" und ihr fangt an, sich selber noch zu "streiten" xD

@Marco13

Ich glaube du hast das abstract, bei der Klasse abstraktesTier vergessen (schreibst ja die ganze Zeit, "bei der abstrakten Klasse") - ist aber nicht so wichtig 

Was ich aber lustig fand, ist, dass deine Katze eher eine Kuh ist ^^:


> class Katze extends AbstraktesTier implements Tier {
> public void gibLaut() {
> * System.out.println("Muuuhhhh");*
> }



Aber jetzt zum Thema:



> ```
> public abstract class Tier {
> public abstract int getNumberOfLegs();
> // noch mehr
> ...





> ohne abstract sollte es doch genauso gehen, oder? wenn nicht, dann bitte erklärt es mir. ich will wirklich lernen.
> 
> Reggie



Und wie bitte schön, willst du dann die *Anzahl der Beine* von *Tier* bestimmen ? Wie viele Beine hat deiner Meinung nach ein Tier ? Also für mich hängt das irgendwie von dem ab, was für ein Tier es ist. Und wieso soll deiner Meinung nach ein Tier instanziert werden können ? Hast du schon mal gesehen, dass ein Tier geboren wurde ? (also ein Tier, das weder ein Hund, noch ein anderes Tier ist, also keine Gattung hat und unbekannte Anzahl an beinen etc....) Also ich glaube auch wenn ich nichts mit Programmieren zu tun hätte, würde ich es nach all den deutlichen Erklärungen hier verstehen. Ich weiß nicht wirklich was dein Problem ist...


----------



## Reggie() (12. Aug 2011)

RySa hat gesagt.:


> Und wie bitte schön, willst du dann die *Anzahl der Beine* von *Tier* bestimmen ? Wie viele Beine hat deiner Meinung nach ein Tier ? Also für mich hängt das irgendwie von dem ab, was für ein Tier es ist. Und wieso soll deiner Meinung nach ein Tier instanziert werden können ? Hast du schon mal gesehen, dass ein Tier geboren wurde ? (also ein Tier, das weder ein Hund, noch ein anderes Tier ist, also keine Gattung hat und unbekannte Anzahl an beinen etc....) Also ich glaube auch wenn ich nichts mit Programmieren zu tun hätte, würde ich es nach all den deutlichen Erklärungen hier verstehen. Ich weiß nicht wirklich was dein Problem ist...


wenn es um die Anzahl der Beine von der Oberklasse (oder halt abstract) "Tier" geht würde ich in der Tier-Klasse eine public static final int numberOfLegs = 4; eintragen. sollte man allerdings Tier-Unterklassen erstellen wollen mit Beine != 4, dann würde ich eine Konstante in jeder der Unterklassen definieren. 
hier gehts doch um den exklusiven Nutzen von abstrakten klassen. und genau den habe ich bisher nicht gelesen. Gab ja schon einige Antworten und manche bestätigten diese Sicht und andere schrieben, dass sich eine normale oberklasse von einer abstrakten klasse nur darin unterscheidet, dass man diese nicht instanzieren kann. wenn man das auch nie vorhatte, macht es also keinen Unterschied, ob man eine abstrakte klasse benutzt.
aber ich schließe auch nicht aus, dass ich den Nutzen und die besondere Funktion von abstract nicht erkenne, weil ich mich noch zu wenig in java auskenne. statt mich zu fragen, wie ich das Beispielproblem sonst lösen wollte, würde ich mir lieber ein Beispiel wünschen, dass NUR mit abstract funktioniert UND erklärt, warum es ohne abstract nicht funktionieren würde.

Reggie


----------



## RySa (12. Aug 2011)

Es gibt kein Beispiel und es wird keins geben (soweit ich weiß), bei dem du *unbedingt* eine abstrakte Klasse nutzen *musst*. Wie es schon zig mal gesagt wurde, es ist alles auch mit normalen Klassen und Interfaces möglich zu realisieren.

Jetzt aber vielleicht mal von der anderen Seite. Du würdest kein Verwendungszweck dafür finden, da du sowieso nie vor hättest die Klasse zu instanzieren. Ist ja auch in Ordnung. Ich persönlich habe auch noch *nie* abstrakte Klassen benutzt. Jetzt stell dir aber mal vor, du willst ein Framework/Tool schreiben, der den anderen das Leben leicher machen soll. Du schreibst ne Klasse, die aber an sich nicht funktionieren wird, sondern von anderen Klassen (also von den Klassen, die die Benutzer schreiben) abgeleitet werden muss. In diesem Fall willst du verhindern, dass solche Klasse, ohne Ableitung Instanziert werden kann. Und das kannst du ja mit einer abstrakten Klasse realisieren. Außerdem, wird ja deine Klasse Methoden beinhalten, die Teilweise von dir implementiert sind, aber auch solche, die von der Konkreten Implementierung des Benutzers abhängen (also je nach seinen Anforderungen). Solch eine Klasse *kann nicht* ohne Ableitung Instanziert werden, und genau das ist ja dein Vorhaben.

Man kann das ganze aber *auch* mit einer "normalen" Klasse und Interfaces realisieren, in dem sie einfach mal die Interfaces implementiert. Solch eine Klasse kann man aber Instanzieren und das - nochmal zur Verdeutlichung, *willst du ja verhindern, weil man mit solcher Klasse nichts machen kann, sie ist also unnützlich, solange man sie nicht mit den entsprechenden Implementierungen ableitet, und es also kein Sinn hat sie zu Instanzieren*
Ist das jetzt vlt. klarer geworden ?


----------



## maki (12. Aug 2011)

TheDarkRose hat gesagt.:


> Architektonisch sind Interfaces und abstrakte Klassen das selbe, nämlich Schnittstellen. Ich finde es ad absurdum, wenn man für eine abstrakte klasse noch extrig ein Interface macht.


Sie sind nicht 100% gleichwertig, der Unterschied machts, abstrakte Klassen die Schnittstellen implementieren sind üblich und oft vorteilhaft, siehe zB. das Collection Framework, Bloch hat das ganz gut in Effective Java beschrieben.

Interface <- abstrakte Klasse <- konkrete Implementierung 1..n

abstrakte Klassen sind nicht ganz so abstrakt wie Interfaces, d.h. wenn man von abstrakten Klassen abhängt ist man meist immer noch von einer Implementierung abhängig, das hat man bei Interfaces nicht mehr. Dafür kann man in abstrakten Klassen zB. Änderungen am Interface vor den konkreten Klassen "verstecken", wenn zB. das Interface erweitert wird, implementiert man diese neuen Methoden in der abtrakten Klasse, fertig, die konkreten Klassen brauchen keine Änderung, laufen genauso wie vorher und nix bricht.
Diese flexibilität bekommt man eben nur wenn man Interfaces und abstrakte Klassen kombiniert.


----------



## Sonecc (12. Aug 2011)

Tipp: Durchlesen, drüber nachdenken, sich nicht kategorisch dagegen stemmen mit Aussagen wie "Geht ja auch ohne" und drüber nachdenken, was es dir und (vor allem) anderen an Vorteilen liefert: Abstrakte Klasse ? Wikipedia


----------



## Reggie() (12. Aug 2011)

RySa hat gesagt.:


> Du schreibst ne Klasse, die aber an sich nicht funktionieren wird, sondern von anderen Klassen (also von den Klassen, die die Benutzer schreiben) abgeleitet werden muss. In diesem Fall willst du verhindern, dass solche Klasse, ohne Ableitung Instanziert werden kann. Und das kannst du ja mit einer abstrakten Klasse realisieren. Außerdem, wird ja deine Klasse Methoden beinhalten, die Teilweise von dir implementiert sind, aber auch solche, die von der Konkreten Implementierung des Benutzers abhängen (also je nach seinen Anforderungen). Solch eine Klasse *kann nicht* ohne Ableitung Instanziert werden, und genau das ist ja dein Vorhaben.
> [...]
> Ist das jetzt vlt. klarer geworden ?


ja, eine gute Erklärung. danke 

Reggie


----------



## Gonzo17 (12. Aug 2011)

Reggie() hat gesagt.:


> wenn man das auch nie vorhatte, macht es also keinen Unterschied, ob man eine abstrakte klasse benutzt.



Meiner Meinung nach ein wichtiger Satz. Du gehst im Moment vielleicht davon aus, dass du der einzige Entwickler an einem Programm bist und deshalb solche kleinen Unterschiede nicht tragisch sind, weil du ja weißt, was getan werden soll.

Jetzt stell dir mal vor du arbeitest in einem Team mit vier Entwicklern im gleichen Haus und nochmal vier Entwickler aus dem Ausland. Nicht jeder weiß, was dein Modul so genau kann und wie es funktioniert. Übergibst du nun die Aufgabe an jemand anderen, dann erwartet er, dass er alles machen darf, was der Code so zulässt. Also könnte er auf die blöde Idee kommen eine Instanz einer Klasse zu erstellen, die eigentlich abstrakt sein könnte. Und natürlich gibts da noch mehr Fälle, in denen etwas ungewolltes passieren könnte. Wenn du dein Design eben so sicher machst, dass sowas nicht passieren kann, dann ist der Code wartbar(er) und verständlich(er).


----------



## Noctarius (12. Aug 2011)

Guice hat ein sehr schönes Beispiel welches ohne abstrakte Klasse möglich aber nicht schön wäre.

Wir gehen davon aus, es gibt ein Interface Module, welches ein Modul in irgendeiner Art und Weise definiert und einen Binder, welcher in irgendeiner Form Bindings erzeugt.


```
public interface Module {

    void configure(Binder binder);

}
```

So jetzt könnte man mit dem Interface Binder alles mögliche machen indem man das Interface Module implementiert.


```
public class MyModule implements Module {

    @Override
    public void configure(Binder binder) {
        binder.bind(Foo.class).to(FooImpl.class);
        binder.bindProvider(SomeProvider.class);
        // ... whatever
    }

}
```

Das ist auch ganz nett aber irgendwie doof immer binder. davor zu schreiben, ergo wurde zusätzlich eine abstrakte Klasse eingeführt um die Konfiguration einfacher zu machen.


```
public abstract class AbstractModule implements Module {
    private Binder binder;

    @Override
    public final void configure(Binder binder) {
        try {
            this.binder = binder;
            configure();

        } finally {
            binder = null;
        }
    }

    protected abstract void configure();

    protected BindBuilder bind(Class<?> clazz) {
        return binder.bind(clazz);
    }

    protected void bindProvider(Class<? extends Provider> providerClass) {
        binder.bindProvider(providerClass);
    }

}
```

So ab hier sieht die das neue Modul nur noch so aus:


```
public class MyModule extends AbstractModule {

    @Override
    public void configure() {
        bind(Foo.class).to(FooImpl.class);
        bindProvider(SomeProvider.class);
        // ... whatever
    }

}
```

Wir sehen also, erstens zwingt uns die abstrakte Klasse in Subclasses die Methode configure() zu implementieren und zweitens haben wir den Code (wenn hier auch nicht viel) verkürzt und übersichtlicher gemacht. Die abstrakte Klasse könnte nun zusätzlich noch in den protected Methode Überprüfungen machen ohne, dass wir die Module anpassen müssten.

Auch werden abstrakte Klassen oft als Adapter genutzt um nachträglich zum Beispiel Interfaces weiterzuentwickeln. Alle Klassen die dann von der abstrakten Klasse erben (anstatt das Interface direkt zu implementieren) merken dann nichts davon, dass sich eventuell Methoden im Interface geändert haben, dazu muss die abstrakte Klasse halt nur eine passende Standardimplementierung mitbringen.

Der eigentliche Sinn von abstrakten Klassen ist also nur, wie meine Vorredner schon sagten, ANDERE (nicht dich selber) daran zu hindern diese Klassen direkt zu instanzieren und um eventuell zusätzliche Funktionalität oder Standardimplementierungen zu liefern.


----------



## RySa (12. Aug 2011)

Noch vielleicht kurz zur Ergänzung (weiß nicht ob das schon gesagt wurde):

Jetzt nehmen wir mal an, du bist kategorisch gegen abstrakte Klassen, und entscheidest dich für eine "normale" Hauptklasse, die ein Interface implementiert, du aber für die Methoden des Interfaces noch keine Implementierungen vornehmen kannst, da die Benutzer-spezifisch sind. Dann denkst du dir, joah, dann implementiere ich sie einfach mal leer. Nun gut, man kann die Methode in der Unterklasse immer noch überschreiben, dazu wird der Benutzer aber nicht mehr gezwungen, da die Methode schlichtweg sonst einfach mal nichts tut. Das mag in manchen Fällen sinnvoll und beabsichtigt sein, manchmal willst du aber den Benutzer "zwingen" die Methoden zu implementieren/überschreiben und gleichzeitig willst du manche Methoden schon "fertig zur Verfügung stellen". Und wenn du im gleichen Anwendungsfall eine abstrakte Klasse machen würdest, die das Interface implementiert (bzw. auch selber diese Methode als abstract definieren kann), wirst du gezwungen, in der ableitenden Klasse die Methoden zu überschreiben hast aber auch die "fertigen" Methoden der Klasse zur Verfügung. 

Interface, für beide Beispiele gleich:

```
public interface Tier {

	public String gibLaut();
}
```

Beispiel 1 (gegen abstract Class):

```
public class AbstractTier implements Tier{

	private String name;
	private double gewicht;
	
	public double getGewicht(){
		return gewicht;
	}
	
	public String getName(){
		return name;
	}
	
	public void setName(String name){
		this.name = name;
	}
	
	public void setGewicht(double gewicht){
		this.gewicht = gewicht;
	}
	
	@Override
	public String gibLaut() {
		return null;
	}
	
}
```
Wenn jetzt eine Klasse Hund diese Klasse ableitet, kann der Entwickler vielleicht übersehen, dass es eine Methode gibLaut() gibt, die er eigentlich überschreiben müsste, und sein Hund wird nicht bellen können  (also wird "null" bellen ^^):

```
public class Hund extends AbstractTier{

	String rasse;
	
	public Hund(String name, double gewicht){
		super();
		setName(name);
		setGewicht(gewicht);
	}
	
	public void setRasse(String rasse){
		this.rasse=rasse;
	}
}
```

Wenn du aber eine abstrakte Klasse dafür nimmst, wird der Entwickler in der Klasse Hund dazu gezwungen, gibLaut() zu implementieren

Beispiel 2 (für abstract Class):

```
public abstract class AbstractTier implements Tier{

	private String name;
	private double gewicht;
	
	public double getGewicht(){
		return gewicht;
	}
	
	public String getName(){
		return name;
	}
	
	public void setName(String name){
		this.name = name;
	}
	
	public void setGewicht(double gewicht){
		this.gewicht = gewicht;
	}
	
}
```
Und das obere Beispiel für Hund, wird nicht mehr funktionieren _"The Type Hund must implement the inherited abstract method Tier.gibLaut()"_ , also wird es so aussehen müssen:

```
public class Hund extends AbstractTier{

	String rasse;
	
	public Hund(String name, double gewicht){
		super();
		setName(name);
		setGewicht(gewicht);
	}
	
	public void setRasse(String rasse){
		this.rasse=rasse;
	}

	@Override
	public String gibLaut() {
		return "woof";
	}
}
```



Ps. Natürlich ist es eine Ansichtssache, ob der "Hund gezwungen werden soll Laut zu geben". Hängt alles von der Architektur des Programms ab.

Und @ den Post unter meinem

Ob du Vererbung/Interfaces schön findest oder nicht. Es ist ein sehr großes und wichtiges Gebiet in Java.Ich hatte auch glaube ich noch nie wirklich ein Nutzen von Vererbung/Interfaces machen können, es hängt aller dings mit der Art meiner Projekte. Es Ändert aber nichts an der frage des TO's, die hier doch noch von vielen ausführlich beantwortet wird. Wenn du mir/uns aber einreden willst, das Vererbung allgemein "böse" ist, dann bitte mal auch konkreter, mit Begründungen/Beispielen...


----------



## bygones (12. Aug 2011)

will mitstreiten 

Vererbung ist eins der meistgehypten und meist missverstandenen/missbrauchten feature seit erfindung von Programmieren... lieber weglassen und nur nehmen wenns ueberhaupt nicht geht.

Die "alte" Frage von IS-A ist meiner ansicht nach so und so falsch.. nur bei "Behaves-like" kann man es in betracht ziehen.

Ansonsten immer beachten: Komposition >>>>> Vererbung.

-----
und nu schoen alle erzaehlen warum Vererbung doch gut ist bzw wie ich sachen denn ohne Vererbung machen will...


----------



## Marco13 (12. Aug 2011)

EDIT: Peinlich, ich hatte die komplette zweite Seite übersehen  Hab ich wohl gepennt :gaen:



Reggie() hat gesagt.:


> statt mich zu fragen, wie ich das Beispielproblem sonst lösen wollte, würde ich mir lieber ein Beispiel wünschen, dass NUR mit abstract funktioniert UND erklärt, warum es ohne abstract nicht funktionieren würde.



So ein Beispiel gibt es nicht (*). Jedes Programm, das eine abstract class verwendet, könnte auch ohne abstract class geschrieben werden. 

(*) Zumindest gibt es so ein Beispiel nicht ohne Aspekte, die schwer zu vermitteln sein könnten. Ich versuch's trotzdem: Methoden, die in einem interface stehen, sind automatisch 'public'. Methoden, die einer Abstrakten Klasse stehen, können auch 'protected' oder 'package private' sein. 

```
interface Tier
{
    void friß();       // Diese Methoden sind immer 'public'
    void gibLaut(); //  (auch wenn kein 'public' davor steht!)
}

abstract class AbstraktesTier implements Tier
{
    protected void verdaueFutter() 
    {
        // Diese Methode erfüllt eine Funktion, die "oft" gebraucht wird,
        // wenn man ein konkretes Tier implementieren will. Allerdings
        // ist die Methode 'protected', d.h. sie sollte NUR von Klassen
        // aufgerufen werden, die von "AbstraktesTier" erben - und 
        // nicht von irgendwelchen anderen Klassen!
    }

    // Diese Methoden sind immernoch abstrakt:
    //public abstract void friß();
    //public abstract void gibLaut();
    
}

class Hund extends AbstraktesTier implements Tier
{
    public void friß()
    {
        System.out.println("Nom, nom, nom");
        verdaueFutter(); // Ruft die 'protected'-Methode aus AbstraktesTier auf
    }
    public void gibLaut()
    {
        System.out.println("Wuff");
    }
}
```

IMHO ist dieser Aspekt auch die EINZIGE _echte_ Existenzberechtigung für abstrakte Klassen, die mir spontan einfallen würde (wenn man das Vermeiden von Doppelimplementierungen nicht als solche ansieht)


----------



## Gregorrr (12. Aug 2011)

bygones hat gesagt.:


> will mitstreiten
> 
> Vererbung ist eins der meistgehypten und meist missverstandenen/missbrauchten feature seit erfindung von Programmieren... lieber weglassen und nur nehmen wenns ueberhaupt nicht geht.
> 
> ...



Bester Beitrag zum Thema, wie ich finde!


----------

