# Abstrakte Klasse vs. Interface



## kossy (26. Jun 2009)

Hallo Leute !

Ich muss mal etwas über strakte Klassen und Interfaces wissen. Wann genau baue ich in meinen Javacode Abstrakte Klassen und wann Interfaces ein? Ich habe einiges über diese beiden Dinge gelesen, in der Theorie bin ich also fit. Allerdings will mir nicht so recht in den Kopf, wann was in der Praxis eingesetzt wird. Hoffe, ihr könnt mir mal ein paar Stichwörter zukommen klassen!?

MFG


----------



## maki (26. Jun 2009)

Mehrfachvererbung ist mit (abstrakten) Klassen nicht möglich, mit Interfaces schon.
Interfaces definieren nur Schnittstellen, also Dinge die ein Objekt "kann", während bei Klassenvererbung eine "ist-ein" Beziehung erzeugt wird.


----------



## Marco13 (26. Jun 2009)

Ganz grob:

In einem Interface steht, was ALLE können sollen, die das Interface implementieren
In einer abstrakten Klasse steht, was ALLE können sollen, die von der Klasse erben, und ein Teil davon ist vielleicht schon implementiert


```
// Definieren, was alle Lebewesen können
interface Lebewesen
{
    void esse();
    void schlafe();
}

// Das, was bei allen Lebewesen gleich ist, schonmal implementieren,
// und das was unterschiedlich ist abstrakt lassen
abstract class AbstraktesLebewesen // Könnte schon implements Lebewesen machen...
{
    abstract void esse();

    void schlafe()
    {
        legDichHin();
        while (müde())
        {
           atmeEin();
           atmeAus();
        }
        wacheAuf();
    }

}


class Mensch extends AbstraktesLebewesen implements Lebewesen
{
    void esse()
    {
        dieSacheMitMesserUndGabel();
    }

    // Schlafe ist schon in der abstrakten BasisKlasse implementiert!
}


class Tier extends AbstraktesLebewesen implements Lebewesen
{
    void esse()
    {
        mampf();
    }

    // Schlafe ist schon in der abstrakten BasisKlasse implementiert!
}
```


----------



## kossy (26. Jun 2009)

Nettes Codebeispiel ! Danke schön. Wenn sich noch weitere Frage im Laufe der Zeit ergeben, dann wärme ich diesen Post nochmal auf !


----------



## 0815 (26. Jun 2009)

maki hat gesagt.:


> Mehrfachvererbung ist mit (abstrakten) Klassen nicht möglich, mit Interfaces schon.
> Interfaces definieren nur Schnittstellen, also Dinge die ein Objekt "kann", während bei Klassenvererbung eine "ist-ein" Beziehung erzeugt wird.



bei der mehrfach implementation von interfcaces handelt es sich nicht um mehrfachvererbung. da man keine methoden / eigenschaften erbe, sondern nur dazu gezwungen wird diese zu implementieren.

auch bei interfaces handelt es sich um eine "ist-ein" beziehung.
siehe listener: addActionListener(ActionListener l);

jede klasse, die ActionListener implementiert "ist ein" ActionListener.


----------



## maki (26. Jun 2009)

> bei der mehrfach implementation von interfcaces handelt es sich nicht um mehrfachvererbung. da man keine methoden / eigenschaften erbe, sondern nur dazu gezwungen wird diese zu implementieren.


Ein Interface kann von mewheren Erben, mit Klassen  geht das nicht.
Die Behauptung dass es sich nicht um Mehrfachvererbung handelt weil die Implementerung nicht mitvererbt wird sondern nur die Schnittstelle ist schlicht falsch.



> auch bei interfaces handelt es sich um eine "ist-ein" beziehung.
> siehe listener: addActionListener(ActionListener l);
> 
> jede klasse, die ActionListener implementiert "ist ein" ActionListener.


Nicht unbedingt, siehe "mix ins", durch Klassenvererbung wird eine viel höhere Kopplung erzeugt.
Der Actionlistener könnte aber auch "Comparable", "Serialiasable" sein, das ist keine "ist-ein" Beziehung.


----------



## kossy (26. Jun 2009)

Nochmal ne Frage zum Thema. Also ich kann ja eine Referenzvariable von einer abstrakten Klasse anlegen, aber selbst kein abstraktes Objekt erzeugen. Bei Interfaces kann eine Referenzvariable vom Typ eines Interfaces mit einer Klasse kompatibel sein, die dieses Interfaces implementiert. (Hoffe ich habe mich korrekt ausgedrückt).

Wann genau macht es Sinn mit einer Referenzvariable vom Typ einer abstrakten Klasse zu arbeiten und wann mit der Referenzvariable vom Typ eines Interfaces. Der genaue Unterschied und jeweilige Vor- und Nachteil wäre für mich wichtig, damit man diese Programmierstile besser versteht und auch selbst bei Problemstellungen verwenden kann, wenn man selbst programmiert.


----------



## Leroy42 (26. Jun 2009)

Mit der Referenzvariablen des Typs einer (abstrakten) Klasse zu arbeiten macht Sinn,
wenn dort Instanzen einer von dieser Klasse abgeleiteten verwiesen werden soll.

Mit der Referenzvariablen des Typs eines Interfaces kannst du auf Instanzen 
verweisen deren Klasse dieses Interface implemtieren


----------



## Marco13 (26. Jun 2009)

Stark verallgemeinert würde ich sagen, dass man Referenzen auf abstrakte Klassen "selten" braucht, weil "oft" die abstrakte Klasse nochmal durch ein Interface verallgemeinert ist. Als Beispiel: Man würde nicht sowas machen
AbstractList<String> list = new ArrayList<String>();
sondern gleich
List<String> list = new ArrayList<String>();


----------



## kossy (26. Jun 2009)

Leroy42 hat gesagt.:


> Mit der Referenzvariablen des Typs einer (abstrakten) Klasse zu arbeiten macht Sinn,
> wenn dort Instanzen einer von dieser Klasse abgeleiteten verwiesen werden soll.
> 
> Mit der Referenzvariablen des Typs eines Interfaces kannst du auf Instanzen
> verweisen deren Klasse dieses Interface implemtieren



Jo das entspricht ja dem, was ich bereits gesgat hatte. Aber gibt es noch spezielle Vor- und Nachteile, wenn ich die eine oder andere Variante benutze?


----------



## Landei (26. Jun 2009)

Ein häufiges Muster ist:

interface Interface{}
abstract class AbstractClass implements Interface{}
class ConcreteClass extends AbstractClass{}

Beispiele aus der Java-API: 
- MouseListener (interface), MouseAdapter (abstract class), eigene Implementierung (konkrete Klasse)
- TableModel (interface), AbstractTableModel (abstract class), DefaultTableModel (konkrete Klasse)

Mit diesem Muster hat man immer ein interface, das man zurückgeben kann (und gegebenenfalls direkt implementieren, z.B. wenn man schon eine Klasse erweitert, also nicht von der abstrakten Klasse erben kann). Die abstrakte Klasse stellt nützliche Grundfunktionalität zusammen, erleichtert also das Erstellen konkreter Klassen.


----------



## kossy (26. Jun 2009)

Landei hat gesagt.:


> Mit diesem Muster hat man immer ein interface, das man zurückgeben kann (und gegebenenfalls direkt implementieren, z.B. wenn man schon eine Klasse erweitert, also nicht von der abstrakten Klasse erben kann).



Vielen Dank für deinen Post ! Was genau meinst Du mit *zurückgeben*? 




Landei hat gesagt.:


> Die abstrakte Klasse stellt nützliche Grundfunktionalität zusammen, erleichtert also das Erstellen konkreter Klassen.



Wobei man aber in Deinem Beispiel mit den "Listener-Klassen" auch darauf verzichten könnte. Es müssten nur alle Methoden des Interfaces implementiert werden. Sehe ich das richtig?


----------



## Marco13 (26. Jun 2009)

kossy hat gesagt.:


> Es müssten nur alle Methoden des Interfaces implementiert werden. Sehe ich das richtig?



Ja. Aber genau um das "nur alle" geht's  Das können ziemlich viele sein (MouseListener) von denen man nur wenige mit was sinnvollem überschreiben will, oder es können welche sein, die für viele abgeleitete Klassen gleich sein sollen, und deswegen schonmal in einer abstrakten Klasse vorgefertigt angeboten werden können.


----------



## André Uhres (27. Jun 2009)

Related reading: Abstract Classes vs. Interfaces
_Schnittstellen sind in vielen Fällen besser als abstrakte Klassen, obwohl wir die Schnittstelle gleich beim ersten Mal richtig definieren müssen. Das nachträgliche Ändern der Schnittstelle wird viel Code brechen. 
Abstrakte Klassen sind nützlich, wenn wir eine teilweise Umsetzung zur Verfügung stellen wollen. In diesem Fall sollten wir ebenfalls eine Schnittstelle definieren, und die Schnittstelle in der abstrakten Klasse implementieren._


----------



## 0815 (27. Jun 2009)

maki hat gesagt.:


> Ein Interface kann von mewheren Erben, mit Klassen  geht das nicht.
> Die Behauptung dass es sich nicht um Mehrfachvererbung handelt weil die Implementerung nicht mitvererbt wird sondern nur die Schnittstelle ist schlicht falsch.
> 
> 
> ...



zu pkt1. 
vererbung ist laut verschiedenen definitionen in der objektorientierung "die möglichkeit einer KLASSE von einer anderen KLASSE zu erben deren sichtbare eigenschaften methoden zu zu verwenden/überschreiben/....(und weitere dinge tun.)
auch SUN's "Java Language Specification" verwendet den begriff "inheritance" nur im bezug auf KLASSEN.

nungut. 
wenn wir nun den begiff "vererbung" abweichend von der definition des objektorientierten programmierens;
und auch abweichend von der "Java Language Specification";

auf das erweitern von schnittstellen, deren hirarchie und der möglichkeit, dass ein subinterface mehrere superinterfaces haben kann, anwenden,
gebe ich dir recht.

da ich aber deine definition nich kannte, bezog sich mein beitrag auf "interface ~" bzw "multiple typ inheritance", (welche erst bei klaseendefinition am 'implements' ansetzen) was laut verschiedener quellen 'übliche begriffe' sind. und welche eine möglichkeit bieten mehrfachvererbung zu simulieren.

sry, dass meine ausführungen so missverständlich waren. (musste dringend weg und konnte meine gedanken nicht beenden)


zu pkt 2.
ich habe die "ist ein beziehung" nur an "objektes ist vom Typ" festgemacht.
class c extends superC implements if1, if2 ("ist ein" superC / if1 / if2)
ich werde mich mal nach "mix ins" und stärke der kopplung unschaun. 
>>zurückruder<<


----------



## André Uhres (28. Jun 2009)

_Nehmen wir z.B. eine Klasse "MyPoint", die geometrische X-, Y-Punkte definiert, mit den üblichen Konstruktor und Accessor-Methoden. Die Klasse implementiert drei Schnittstellen. Eine Schnittstelle wird verwendet, um einen Punkt mit einem anderen zu vergleichen, eine andere wird für die Berechnung der Distanz zwischen zwei Punkten benutzt, und die letzte definiert "MyPoint"-Objekte als serialisierbar. 
Ein alternativer Ansatz wäre, eine neue Schnittstelle Composite (eine sogenannte "Unterschnittstelle") zu definieren, die die drei Schnittstellen erweitert, und dann Composite in MyPoint zu implementieren. Dies ist ein Beispiel für ein "nonhierarchical type framework". 
Es ist einfach, eine bestehende Klasse nachzurüsten, um eine neue Schnittstelle zu implementieren. Dies wird manchmal auch als "Mixin" bezeichnet. In einem Mixin erklärt eine Klasse, dass sie ein optionales Nebenverhalten zusätzlich zu seiner Hauptaufgabe anbietet. "Comparable" ist ein Beispiel für ein Mixin._


----------



## titus (6. Jul 2009)

Ich wollte auch nur einmal Dankeschön sagen, für das obere Code-Beispiel. Das ist echt gut und idiotensicher - also genau richtig für mich! ;D Ich hatte gerade die selbe Frage unter den Fingern brennen und wollte schon einen neuen Thread aufmachen, bis mir einfiel, dass es doch auch eine Suchfunktion gibt.


----------



## sliwalker (6. Jul 2009)

Noch ein weiterer Aspekt ist, dass abstrakte Klassen dann sinnvoll sind, wenn man dennoch ausimplementierte Methoden bereitstellen möchte, die nicht überschrieben werden können. Diese Möglichkeit bietet sich Dir bei Interfaces nicht. Es kann zum Beispiel sein, dass ein Verhalten (Objekt zu EntityBean) unanhänig vom Typ des Objekts geschehen soll. Eine Implementierung eines Interfaces würde in diesem Fall schlicht zu viele Freiheiten lassen.

Ein wenig unprofessionell formuliert, aber der merksatz in meinem Kopf lautet etwas so, dass ich jederzeit gegen Interfaces implementiere bzw. Mix-In Beziehungen gegen Interfaces, außer ich möchte Verhalten explizit und nicht-änderbar vorgeben.


----------



## André Uhres (7. Jul 2009)

Wenn ich mir deinen Kopf so ansehe, ist es wohl kein Wunder, daß sowas drin ist :lol:


----------



## frapo (7. Jul 2009)

André Uhres hat gesagt.:


> Wenn ich mir deinen Kopf so ansehe, ist es wohl kein Wunder, daß sowas drin ist :lol:



:lol::applaus: Der war nicht schlecht André Uhres


----------



## Localtime (7. Jul 2009)

Jaja ... der Joda .... bildet 500 Jahre Jedi-Ritter aus, bekommt aber keinen einzigen Satz vernünftig über die Lippen.


----------



## Landei (7. Jul 2009)

Spotten du sollst nicht, Padawan!


----------

