# was bringt Interface



## paul3 (23. Nov 2007)

hallo!

Ich wollte wissen, was eine Interface ist und hab deshalb ein paar sachen im web dazu durchgelesen. Nun steht da, dass eine Interface, wie zB. "kann fliegen" Funktionen bereitstellt (in unserem Fall, damit etwas fliegen kann), die von beliebig vielen Klassen eingebunden werden können. Man muss also immer nur die eine Interface implementieren. Das tolle sei, dass man bei neuer Funktionalität nur einmal die Interface erweitern muss und nicht gleich alle Klassen, die die Funktionalität der Interface benötigen.

Nun habe ich aber festgestellt, dass man in einer Interface gar keine Fuktionskörper haben kann. Was bringt es denn bitteschön einer Klasse "Vogel", die "kann fliegen" implementiert, wenn in der Interface nur Sachen stehen, wie:


```
void flügelHoch();
void flügelRunter();
boolean starten();
boolean landen();
```


----------



## ARadauer (23. Nov 2007)

Du kannst verschiedene Vögel implementieren, die unterschiedlich fliegen und du kannst sie alle gleich verwenden, weil sie ja Vögel sind.

Ei


----------



## Niki (23. Nov 2007)

Interfaces verwendest du dann, um dem Programmierer ein Gerüst bereit zu stellen. Der Vorteil ist, dass die Klassen, die das Interface kennen, nicht die Implementierung kennen müssen. Dadurch lässt sich die Implementierung austauschen, ohne das andere Klassen direkt davon betroffen sind.
Außerdem ist in Java Mehrfachvererbung nicht möglich, man kann aber mittels Interfaces die Mehrfachvererbung ein wenig abbilden, weil eine Klasse durch Interfaces von mehreren Typen (kann man mittels instanceof) sein kann.

Ein super Beispiel sind zum Beispiel die EventListener Klassen von Swing. Beim Registrieren eines Listeners wird nur ein Interface übergeben, von dem Interface wird dann die jeweilige Methode ausgeführt. Du kannst daher eine Klasse schreiben, die mehrere Interfaces implementiert und die du bei unterschiedlichen Komponenten als EventListener registrieren kannst. Einmal als ActionListener, einmal als ItemListener...

Ich hoffe ich konnte dir ein wenig weiter helfen. Interfaces zu verstehen ist am Anfang nicht leicht, hat man es aber einmal verstanden weiß man auch wann man am besten Interfaces verwendet.


----------



## ms (23. Nov 2007)

Das, was in einem Interface steht sind Vereinbarungen dessen, was eine implementierende Klasse können muss.

Dein genanntes Interface zb. "kann fliegen" stellt die beiden Methoden starten() und landen() zur Verfügung.
Somit kann eine Klasse Vogel aber auch eine Klasse Flugzeug dieses Interface implementieren.
Der eigentliche Code muss aber in den beiden Klassen unterschiedlich sein, denn ein Vogel schlägt mit den Flügeln und ein Flugzeug wird vom Piloten gesteuert, der Schubkraft und Höhenruder betätigt.

ms


----------



## stevieboy (23. Nov 2007)

Weiterhin sollte man eventuell noch einmal erklären, dass man am besten gegen das Interface (deutsch: Schnittstelle) programmiert.

Ein Beispiel, was einem oft unterkommen wird ist: List.

Statt in einer Klasse 

```
public class ListAction {
        //...
	private void doThingsWithList(ArrayList<String> list){ //Schlecht: Parameter ist eine normale Klasse
		for (String entry : list) {
			System.out.println(entry);			
		}
	}
        //...
}
```

zu verwenden, ist es flexibler und sinnvoller folgendes zu verwenden:


```
public class ListAction {
	private void doThingsWithList(List<String> list){ // Gut der Parameter ist nur das Interface!!!
		for (String entry : list) {
			System.out.println(entry);			
		}
	}
}
```

Weiterhin kannst Du - wie  Niki schon sagte - mit Hilfe der Interfaces (wie der Name schon sagt) Schnittstellen zu Deinen Programmteilen anbieten. So kann Sun zB mit der Schnittstelle List eine Vereinbarung herausgeben, was eine "Liste" alles können muss (wobei teilweise auch eine UnsupportedMethod-Exception geworfen werden darf während der Implementierung). So kann man einfach neue Listtypen programmieren, die sich von außen genau so verhalten wie ArrayList oder LinkedList.

Klingt doch sinnvoll,oder?


----------



## ARadauer (23. Nov 2007)

> Ich hoffe ich konnte dir ein wenig weiter helfen. Interfaces zu verstehen ist am Anfang nicht leicht, hat man es aber einmal verstanden weiß man auch wann man am besten Interfaces verwendet.


Das stimmt, wenn mans ein paar mal verwendet hat, bekommt man ein Gefühl dafür.


----------



## paul3 (23. Nov 2007)

Erst mal vielen Dank für eure zahlreichen Tipps!

Jetzt hab ich noch zwei Fragen. Niki sagt: 





> Ein super Beispiel sind zum Beispiel die EventListener Klassen von Swing. Beim Registrieren eines Listeners wird nur ein Interface übergeben, von dem Interface wird dann die jeweilige Methode ausgeführt.


Aber wie kann denn von einem Interface eine Methode ausgeführt werden, wenn in einem Interface nicht einmal die Körper von Funktionen enthalten dürfen?
Wie kann etwas wie 

```
public interface WindowListener extends EventListener {
   
public void windowOpened(WindowEvent e);

public void windowClosing(WindowEvent e);

public void windowClosed(WindowEvent e);
   
public void windowIconified(WindowEvent e);

...
```

Denn irgendetwas machen? Das ist doch nur ein Gerüst !?

Nehmen wir doch mal weiter die Interface "WindowListener" als Beispiel.  Wenn jetzt eine Klasse den "WindowListener" implementiert und einige Funktionen vervollständigt: 
	
	
	
	





```
public final void windowClosing(final WindowEvent e)
{
	System.exit(0);
}
```
Woher weiß dann Java, dass wenn das "Window Event e" eintritt dann das Programm beendet wird? Ok "e" tritt ein. Aber wer registriert das bitteschön? Ok das muss wohl die Interface sein, denn die brauche ich ja, damit das registriert wird. Aber wie der Quellcode des Interface "WindowListener" zeigt, steht da kein Meter drin, dass die Funtkion "windowClosing()" in einem bestimmten Fall aufgerufen werden muss. In dieser Interface stehen nur öde Funktionsskelette ohne Inhalt.


----------



## dirk.be (23. Nov 2007)

paul3 hat gesagt.:
			
		

> Aber wie kann denn von einem Interface eine Methode ausgeführt werden, wenn in einem Interface nicht einmal die Körper von Funktionen enthalten dürfen?
> Wie kann etwas wie
> 
> ```
> ...


Stimmt, das Interface ist nur das Gerüst. Wenn eine Funktion einen WindowListener als Parameter erwartet, heißt das soviel wie "übergebe das Objekt einer Klasse, die den WindowListener implementiert". Diese Klasse muss dann wirklich alle Methoden, die der WindowsListener vorschreibt, implementieren. (Wenn man tatsächlich nur eine Methode benötigt, erstellt man die anderen einfach mit leerem Rumpf - das macht übrigens auch schon der WindowAdapter, so dass man auch von dieser Klasse erben und nur die erforderliche Methode überschreiben kann.)



> Woher weiß dann Java, dass wenn das "Window Event e" eintritt dann das Programm beendet wird? Ok "e" tritt ein. Aber wer registriert das bitteschön? Ok das muss wohl die Interface sein, denn die brauche ich ja, damit das registriert wird. Aber wie der Quellcode des Interface "WindowListener" zeigt, steht da kein Meter drin, dass die Funtkion "windowClosing()" in einem bestimmten Fall aufgerufen werden muss. In dieser Interface stehen nur öde Funktionsskelette ohne Inhalt.


Die Klasse JFrame z.B. verschickt ein Event vom Typ WindowEvent immer dann, wenn ein besonderes Ereignis auf dem Fenster statt findet, also wenn es beispielsweise minimiert, geöffnet oder geschlossen wird. Allerdings müssen sich die potenziellen Empfänger dieses Ereignisses zuvor mit einem entsprechenden EventListener beim Fenster angemeldet haben.

```
public class MyWindowListener implements WindowListener {  // oder: extends WindowAdapter
// ...
}
```


```
public class MyFrame extends JFrame {
    public MyFrame() {
        //...
        addWindowListener(new MyWindowListener());
    }
}
```


----------



## paul3 (23. Nov 2007)

ah danke! jetzt verstehe ich das! Oft dienen Interfaces also einfach nur der Markierung von Klassen.

und jetzt meine zweite Frage:

Stevieboy sagte, es sei besser den Code so zu schreiben:


```
public class ListAction { 
   private void doThingsWithList(List<String> list){ // Gut der Parameter ist nur das Interface!!! 
      for (String entry : list) { 
         System.out.println(entry);          
      } 
   } 
}
```

Aber wo wird denn da eine Interface implementiert ?


----------



## Beni (24. Nov 2007)

> ah danke! jetzt verstehe ich das! Oft dienen Interfaces also einfach nur der Markierung von Klassen.


Vielleicht meinst du das Richtige und sagt es einfach falsch, aber so kann man das nicht stehen lassen.
Interfaces dienen der Definition einer *Schnittstelle* zwischen Klassen oder Modulen die sich gegenseitig nicht kennen.
Interfaces definieren welche Methoden
- der Benutzer aufrufen kann
- der Lieferant bereitstellen muss

--------
Derjenige der "doThingsWithList" aufruft, muss eine konkrete Implementation einer List übergeben.


```
List<String> list = new LinkedList<String>();
list.add( "bla bla" );
doThingsWithList( list );
```

Natürlich kann sich das hinter Indirektionen verstecken:

```
public void start(){
  List<String> list = new LinkedList<String>();
  list.add( "bla bla" );
  middle( list );
}

public void middle( List<String> list ){
  doThingsWithList( list );
  Collections.sort( list );
  doThingsWithList( list );
}
```


----------



## ms (24. Nov 2007)

paul3 hat gesagt.:
			
		

> ```
> public class ListAction {
> private void doThingsWithList(List<String> list){ // Gut der Parameter ist nur das Interface!!!
> for (String entry : list) {
> ...



Genau diese Frage ist in diesem Kontext uninteressant. Demjenigen, der das Interface benutzt interessiert nicht, wer bzw. wo es implementiert ist. Denn hier wird es nur verwendet. Damit kann man sehr schön den Code in seine verschiedenen Aufgabenbereiche unterteilen. 

ms


----------



## byte (24. Nov 2007)

Vielleicht wirds auch deutlicher, wenn man den Kommentar im Code mal korrigiert: Der Parameter der Methode *ist* nicht *das* Interface, sondern er *ist vom Typ* des Interfaces. Wo es implementiert ist, spielt keine Rolle. Man weiss an der  Stelle, dass *irgendein* Objekt übergeben wird, das aber auf jeden Fall das Interface implementiert. Somit weiss man also genau, welche Methoden man auf diesem Objekt aufrufen kann (nämlich genau diejenigen, die durch das Interface definiert sind).

Sinn und Nutzen von Interfaces kann man eigentlich an einer Zeile Code deutlich machen, die da z.B. lauten kann:

```
List list = new ArrayList();
```

Wenn Du begriffen hast, warum man das so schreiben kann, was das für Auswirkungen hat und warum das besser ist als _ArrayList list = new ArrayList();_ dann hast Du Interfaces begriffen.


----------



## sowieso (24. Nov 2007)

Ah, das hat auch mir geholfen!


----------



## paul3 (24. Nov 2007)

> Vielleicht wirds auch deutlicher, wenn man den Kommentar im Code mal korrigiert: Der Parameter der Methode ist nicht das Interface, sondern er ist vom Typ des Interfaces.


Stimmt, das klärt auch für mich einiges! 

Nur Kann ich ja nun nicht einfach 
	
	
	
	





```
List arrList  = new ArrayList();
```
 schreiben. Der Compiler kennt "List" nicht. Die List aus awt ist ja wohl eine andere, denn sie weist ganz andere Funktionen auf, als die Interface "List" aus "util" vorgibt.

Ich mein ich könnte es ja so schreiben:

```
AbstractList <String> arrList  = new ArrayList <String>();
```
 Jede Unterklasse von "AbstractList" muss ja auch die selben Funktionen wie das Interface List aufweisen, weil die abstrakte Klasse "AbstractList" ja das Interface List implementiert. Aber das meint ihr ja wohl nicht?!

Was für eine Klasse muss ich denn importieren, damit ich den Code so schreiben kann, wie ihr das vorgeschlagen habt?


----------



## ms (24. Nov 2007)

paul3 hat gesagt.:
			
		

> Nur Kann ich ja nun nicht einfach
> 
> 
> 
> ...



java.util.List mußt du importieren.
java.awt.List ist eine GUI-Komponente zur darstellung von Listen.

Schau dich mal in den JavaDocs um, dann bekommst auch ein wenig Gefühl für Klassen und Interfaces.
http://java.sun.com/j2se/1.4.2/docs/api/java/util/List.html

ms


----------



## paul3 (24. Nov 2007)

Achso, man kann Interfaces auch infach importiere udn nicht nur implementieren !!

Das ist ja klasse !

Das heißt, unsere Funktion nimmt alle Objekte an, die sich wie eine List verhalten, das heißt, die alle Funktionen enthalten, die die Interface List vorgibt.

Wenn wir der Funktion eine LinkedList übergeben, dann soll die Funktion alle Elemente der List ausgeben (sagen wir jetzt mal). Was ist aber, wenn jemand irgendeine ganz komische Klasse schreibt, die überhaupt nichts listenartiges hat, und er die Interface "List" importiert und auch alle Funktionen in die Klasse aufnimmt (allerdings mit leerem Funktionskörper). 
Dann wird der Funktion ja zwar eine List übergeben, aber die Funktion kann gar keine Elemente ausgeben, weil das erhaltene Objekt sich keinen Meter wie eine List verhält.

Dieses Szenario legt es doch nahe, dass man das lieber so schreiben sollte:

```
AbstractList <String> arrList  = new ArrayList <String> ();
```

Denn jede Unterklasse von "AbstractList" bringt notwendiger weise für Listen typisches mit sich, weil jede Unterklassen notwendigerweise auch die Variablen von "AbstractList" enthält. Erst Funktionen und Variablen können doch bestimmte Charakteristika (hier einer Liste) erzwingen. Die Interface List erzwingt nur Funktionen, aber keine Variablen.

Oder wo liegt mein Denkfehler ?


----------



## Guest (24. Nov 2007)

> Was ist aber, wenn jemand irgendeine ganz komische Klasse schreibt, die überhaupt nichts listenartiges hat, und er die Interface "List" importiert und auch alle Funktionen in die Klasse aufnimmt (allerdings mit leerem Funktionskörper).
> Dann wird der Funktion ja zwar eine List übergeben, aber die Funktion kann gar keine Elemente ausgeben, weil das erhaltene Objekt sich keinen Meter wie eine List verhält.



Das wäre doch aber bei Deinem angegebenem Beispiel das gleiche. Stelle Dir vor die Leute von Sun die die ArrayList
geschrieben haben hätten da auch die Methodenkörper leer gelassen, oder den von AbstractList.Das die Methodenkörper
schon eine Funktionalität haben solten dafür musst Du schon selber sorgen tragen. Merk Dir folgendes:


```
List myList = new LinkedList();
```

List ist hier der Typ von myList. Du kannst myList nur Objekte zuweisen die das Interface List implementieren. Der Typ
gibt also an, was Du alles mit dem Objekt machen kannst, nicht mehr und nicht weniger. Das Object was Du übergibst
kann auch mehr können, aber es hat aufjedenfall die Methoden die List auch hat. Ich habe mich damals immer gefragt,
warum ich nicht einfach in dem oberen fall folgendes schreiben kann.


```
LinkedList myList = new LinkedList();
```

anstatt


```
List myList = new LinkedList();
```

In dem Fall ist es eigentlich nur der Sinn den Typ von der Implementierung zu trennen. Wenn Du nämlich mal später auf
die Idee kommst, dass eine LinkedList nicht mehr zum Programm passt, machst Du einfach eine ArrayList draus.
Aber für andere Probleme wird es klarer, wenn man z.B eine Methode schreibt soll die sortieren kann, der man aber
verschiedene Objekte übergeben kann. Jetzt hast Du das Problem: "Woher weiss ich denn jetzt wie ich die Objekte die
ich nicht kenne sortieren kann?". Und dann machts Klick, da gibt es doch das Interface Comparable, wenn ich einfach dafür sorge das z.B das alles in dem Array was ich an die Methode übergebe Comparable implementiert, weiss ich das
jedes Element in dem Array eine Methode compareTo hat mit der ich vergleichen kann. Dir ist auch egal wie die Aussieht
Du weisst einfach, dass der jenige der die Methode aufruft, dafür sorgen muss das alle Elemente in diesem Array das
Interface implementieren.

Viele Grüße
Waldi


----------



## ms (24. Nov 2007)

paul3 hat gesagt.:
			
		

> Achso, man kann Interfaces auch infach importiere udn nicht nur implementieren !!


Ja, sonst kennt der Compiler ja die Liste nicht. Hat nichts mit dem Verwenden oder Implementieren von Interfaces direkt zu tun.



			
				paul3 hat gesagt.:
			
		

> Das ist ja klasse !


ähh ... interface !!! :lol: 



			
				paul3 hat gesagt.:
			
		

> Das heißt, unsere Funktion nimmt alle Objekte an, die sich wie eine List verhalten, das heißt, die alle Funktionen enthalten, die die Interface List vorgibt.


Bingo



			
				paul3 hat gesagt.:
			
		

> Was ist aber, wenn jemand irgendeine ganz komische Klasse schreibt, die überhaupt nichts listenartiges hat, und er die Interface "List" importiert und auch alle Funktionen in die Klasse aufnimmt (allerdings mit leerem Funktionskörper).
> Dann wird der Funktion ja zwar eine List übergeben, aber die Funktion kann gar keine Elemente ausgeben, weil das erhaltene Objekt sich keinen Meter wie eine List verhält.


Dann wird sich wohl das gesamte Programm demensprechend verhalten.
Wenn die einzige Vereinbarung die Verwendung einer Liste (java.util.List) ist dann genügt es, die Methoden mit leerem Funktionsblock zu implementieren bzw. null bei Referenzen zurückzuliefern.



			
				paul3 hat gesagt.:
			
		

> Dieses Szenario legt es doch nahe, dass man das lieber so schreiben sollte:
> 
> ```
> AbstractList <String> arrList  = new ArrayList <String> ();
> ```


Grundsätzlich spricht nichts dagegen.
Was aber wenn du eine ultimativ hochperformante und ultraspeicherminimierende Implementierung einer Liste schreibst , die nicht auf AbstractList basiert und dann in deinem Programm einbauen möchtest. Dann müßtest du alle deine 357365 AbstractList-Referenzen auf MeineSuperListe ändern.
Viel spaß!



			
				paul3 hat gesagt.:
			
		

> Denn jede Unterklasse von "AbstractList" bringt notwendiger weise für Listen typisches mit sich, weil jede Unterklassen notwendigerweise auch die Variablen von "AbstractList" enthält. Erst Funktionen und Variablen können doch bestimmte Charakteristika (hier einer Liste) erzwingen. Die Interface List erzwingt nur Funktionen, aber keine Variablen.
> 
> Oder wo liegt mein Denkfehler ?


Egal ob du jetzt List, AbstractList oder ArrayList verwendest, letztendlich ist es immer eine ArrayList wenn du diese instanzierst. Nur die Sicht des Benutzers ist sozusagen eine reduzierte.

ms


----------



## paul3 (24. Nov 2007)

Super!

Ich glaube ich hab jetzt wirklich verstanden, wozu Interfaces da sind! Vielen Dank dafür an alle, die geschrieben haben!!

Jetzt würde ich nur noch gerne wisse, wie z.B. die Klasse JFrame checken kann, ob eine andere Klasse einen WindowListener implementiert hat. es wurde ja gesagt, dass der JFrame das checkt, und wenn die Interface implementiert ist, die entsprechende von der Interface vorgegebene Funktion (z.B. Windowclosing(Event e)) aufruft.

Also, wie checkt z.B. ein JFrame das ?


----------



## ms (24. Nov 2007)

In der Klasse JFrame bzw. einer Superklasse davon gibt es eine Methode wo du einen WindowListener registieren kannst.
Schau in der javadoc nach.

http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JFrame.html

ms


----------



## sowieso (24. Nov 2007)

Wenn ich kurz eure Diskussion unterbrechen dürfte. Ich bin auch noch recht neu bei Java und frag mich jetzt folgendeszum Thema Interface:

Angenommen, man will eine Ampel programmieren. Es gibt ja Europäische Ampeln, Afrikanische... (unterscheiden sich bezüglich z.B. der Schaltreihenfolge). Also schreiben wir erst mal eine Abstrakte Klasse Ampel:


```
abstract class AbstractAmpel extends AbstractVerkehrsobjekt
{
    boolean rot;
    boolean gelb;
    ...

    abstract void schalten();
    
    Zustand getZustand()
    {
        if(rot) return(new Zustand("rot"));
        if(gruen) return(new Zustand("gruen"));
        ...
    }
    ...
}
```

wenn ich jetzt z.B. eine europäische Ampel schreiben will:


```
class EuropeAmpel extends AbstractAmpel
{
    ....
}
```

Sollte man da jetzt also gemäß dem Sinn von Interfaces schreiben:


```
class EuropeAmpel extends AbstractAmpel implements Ampel
{
    ....
}
```

Und in der Interface "Ampel" steht dann:


```
interface Ampel extends Verkehrsobjekt
{
    void schalten();
    Zustand getZustand();
    ...
}
```

Soll ich das dann machen, damit ich eine klar definierte Schnittstelle ("Ampel") hab (wenn mal z.b. eine Funktion eine Ampel als Parameter braucht und überhaupt).

Oder sollte ich lieber nur ein Interface implementieren oder lieber nur extenden und nicht implementieren??


----------



## HLX (24. Nov 2007)

Ein Interface Ampel würdest du nicht benötigen. Das gehört alles in AbstractAmpel.

Ein Interface benötigst du für Dinge, die nicht direkt dem Gegenstand zuzuordnen sind. In deinem Falle wäre das z.B. ein Interface Verkehrsregler:


```
interface Verkehrsregler
{ 
    void stoppeVerkehr(); 
    void gibVerkehrFrei(); 
}
```

Dieses Interface implementieren nun die Ampel und der Verkehrspolizist. Durch die implementierung wird z.B. geregelt, wie die Objekttypen den verkehr anhalten (ampel = rot  / Verkehrspolizist = Handzeichen). 

Nun kannst du von außen den Verkehr regeln unabhängig, ob ein Polizist oder eine Ampel auf der Kreuzung steht.


----------



## sowieso (24. Nov 2007)

ah kapito !

Aber würde man das "implements Verkehrsregler" nicht besser in die "AbstractAmpel" reinschreiben, und dann in die "EuroAmpel" nur noch "extends AbstractAmpel" ? Dann ist gleich festgelegt, dass alle möglichen Ampeln Verkehrsregler Funktionen haben?


----------



## HLX (24. Nov 2007)

Ja, das macht Sinn.


----------



## paul3 (24. Nov 2007)

Ich find das Ampelbeispiel klasse!

Ich wollte mich noch ein wenig mit folgendem Zitat auseinandersetzen:
"Interfaces sind da nur eine kastrierte Alternative zur Mehrfachvererbung, da sie es erfordern dass der Code jedes mal neu implementiert wird. Das kann wirklich nicht die Lösung sein."

Aber das stimmt doch gar nicht, oder? Wenn eine Klasse eine Interface implementiert und man diese Klasse mittels "extends" erweitert, dann hat die Unterklasse doch zwingenderweise auch die Funktionen der (in der Oberklasse) implementierten Interface ?! Da muss die Unterklasse die Interface doch nicht auch noch implementieren?!!


----------



## byte (24. Nov 2007)

paul3 hat gesagt.:
			
		

> Ich wollte mich noch ein wenig mit folgendem Zitat auseinandersetzen:
> _"Interfaces sind da nur eine kastrierte Alternative zur Mehrfachvererbung, da sie es erfordern dass der Code jedes mal neu implementiert wird. Das kann wirklich nicht die Lösung sein."_


Ich weiss nicht, von wem dieser Kommentar stammt, aber er scheint wohl selbst noch in der Lernphase zu stecken und noch nicht sehr lange zu programmieren.

Du kannst auch ohne Mehrfachvererbung mit Interfaces problemlos Implementierungen mehrerer Typen auslagern:


```
public interface Interface1 {
   public void method1();
}

public interface Interface2 {
   public void method2();
}

public class Impl1 implements Interface1{
   public void method1() {
      // tu irgendwas
   }
}

public class Impl2 implements Interface2{
   public void method2() {
      // tu irgendwas
   }
}

public class NoNeedForMultipleInheritance implements Interface1, Interface2 {
   private Interface1 impl1 = new Impl1();
   private Interface2 impl2 = new Impl2();

   public void method1() {
      impl1.method1();
   }

   public void method2() {
      impl2.method2();
   }
}
```


----------



## paul3 (24. Nov 2007)

Naja, also dem Zitat (das ich gegoogelt hab) kann ich auch nichts abgewinnen. Aber was ich mit Interfaces ein wenig merkwürdig (im Gegensatz zur Mehrfachvererbung) finde, ist folgendes:

Methode 1:  
Nehmen wir das Ampel / Verkehrspolizist Beispiel von oben. Jede Ampel leitet sich ja von der "AbstractAmpel" ab. Genauso leitet sich jeder Verkehrspolizist von "AbstractMensch" ab. Nun kann man sagen, beide können die Funktionalitäten haben, die man zum Regeln des Verkehrs benötigt. Also implementieren beide die Interface "Verkehrsregler" und gut ist. 

Methode 2:  
Nur könnte man genauso sagen: Jede Ampel leitet sich von der abstrakten Klasse "Verkehrsregler" ab. Auch jeder Verkehrspolizist leitet sich von dieser Klasse ab (macht auch Sinn, denn sowohl Ampel, als auch Verkehrspolizist sind speziellere Formen von Verkehrsreglern). Da eine Ampel aber auch noch die Funktionalitäten einer Ampel hat, die nichts mit Verkehrsregeln zu tun haben (oben haben wir auch berücksichtig, dass ein Verkehrspolizist nicht nur Verkehrsregler sondern auch Mensch ist) implementiert die Klasse Ampel die Interface "Stahlgerüst" (enspricht oben Mensch bei Verkehrspolizist). Außerdem implementiert die Klasse Verkehrspolizist die Interface "Mensch".

Beides kommt ja auf das selbe hinaus, nur das man im ersten Fall eben zwei abstrakte Klassen und eine Interface hat und unten eine abstrakte Klasse und zwei Interfaces hat.

Bei der Mehrfachvererbung würden wir einfach sagen: 





> Ampel extends Verkehrsregler, Stahlgerüst





> Verkehrspolizist extends Verkehrsregler, Mensch


. wir haben hier 3 abstrakte Klassen (bzw. Unterklassen) und keine Interfaces.

Man sieht 

Methode 1 --> Summe 3 (2 abstrakte 1 Interface)
Methode 2 --> Summe 3 (1 Interface 2 abstrakte)
mehrfachvererbung --> Summe 3 (3 Abstrakte)

Letztendlich kann man zu keinem der der 3 Wege sagen, dass macht keinen Sinn. Nur sieht man an Methoden 1 und 2, dass Interfaces genauso gut von abstrakten Klasse übernommen werden können, wenn man dafür die Interfaces mit absrakten Klassen austauscht. Der Weg der Mehrfachvererbung zeigt nochmal ganz klar, dass man eigentlich nur darum herumhüpfen muss 3mal das selbe zu nehmen, weil es keine Mehrfachvererbung gibt. Und wie man die 3 eigentlich identischen Sachen zwischen abstrakt und Interface aufteilt, ist sehr willkürlich (siehe entweder Methode 1 oder auch Methode2).

Man kann mit Interfaces Mehrfachvererbung vielleicht ersetzen und in anderen Fällen, um die es hier aber nicht geht, ist sie auch noch für anderes sinnvoll, aber strikt logischer ist die Mehrfachvererbung.

Seht ihr das anders?


----------



## stevieboy (24. Nov 2007)

Man kann Interfaces und AbstractClasses imho nicht äquivalent verwenden. 

Wenn ich mich recht erinnere, kann man ja von einer AbstractClass kein Objekt erstellen (sondern nur von erbenden Unterklassen). Dies führt dazu,dass ich zwar schreiben kann


```
List myList = new ArrayList();
myList.add("bla");
```

aber eben nicht


```
MyAbstractList myAList = new MySubAbstractList();
```

Oder liege ich da falsch?

Der nächste Unterschied ist imho, dass Interfaces dem Programmierer (fast) völlige Implementierungsfreiheit geben, weil sie ja nur die Mindestmethoden sowie deren Signaturen vorgeben. Wie der Programmierer diese Methoden mit Leben füllt bleibt ihm überlassen. (Natürlich *muss* er sie eben auch implementieren.)


----------



## paul3 (24. Nov 2007)

Mit welcher der beiden beschriebenen Methoden (1 oder 2 aus meinem vorherigen Kommentar) könnte man denn dann deiner Meinung nach, nicht alles problemslos darstellen ? Meiner Meinung nach klappt das mit beiden, obwohl man mit der zweiten quasi die Interface mit abstrakten Klassen ersetzt und umgekehrt.


----------



## ms (24. Nov 2007)

Auch wenn ein Polizist den Verkehr regelt ist er in erster Linie ein Mensch. Daher sehe ich Mensch als primäre Klasse und Verkehrsregler als zusätzliche Qualifikation. Aber es ist durchaus legitim es auch anders zu betrachten. Hängt vom Anwendungsfall ab. Hier ist es für mich eindeutig.

Zu den abstrakten Klassen.
Eine abstrakte Klasse ohne einer einzigen implementierten Methode ist letztlich nichts anderes als ein Interface. 
Darum enthält eine abstrakte Klasse in der Regel implementierungen die man als Template betrachten kann. Also gemeinsame Funktionen, die nicht Subtypenspezifisch sind. Diese Implementierungen sind aber trotzdem schon ein Teil des "WIE" dieser Klasse. (Also wie diese Klasse funktioniert/implementiert ist) Und genau das ist der Punkt den man vermeiden will/soll.
Derjenige, der eine List verwendet, soll sich nicht darum kümmern, wie diese funktioniert.

Abgesehen davon ist es bei Verwendung von zB AbstractList nicht mehr möglich einer anderen Klasse, die vielleicht schon eine primären Zweck erfüllt (und eine andere Klasse erweitert) eine List-Funktionalität zu geben, da sie ja ebenfalls von AbstractList erben müsste. Da Mehrfachvererbung nicht geht stehen wir an. Sowas würde ich dir als schweren Designfehler um die Ohren werfen.  

ms


----------



## paul3 (24. Nov 2007)

Deine Argumente leuchten mir ein   

Also möchte ich nun feierlich verkünden, dass ich nur noch DIE EINE Frage stellen möchte, bevor ich den Häkchen Buttonklicke   

Ich wollte nun das hier gelernte anwenden. bis dato hatte ich eine Funktion

```
private double startSimulate(final TreeMap <String, Integer> map)
{		
    map = (TreeMap <String, Integer>) map.clone();
}
```

Jetzt wollte ich das verbessern. Die Funktion sollte keine TreeMap mehr fordern, sondern nur noch eine Interface. Also habe ich geschaut, welche Interface denn eine TreeMap implementiert. Sie implementiert die Interface "NavigableMap". Also wollte ich das ganze so schreiben:

```
private double startSimulate(final NavigableMap <String, Integer> map)
{		
    map = (NavigableMap <String, Integer>) map.clone();
}
```

nur leider klappt das nicht, denn die TreeMap lässt sich nur klonen, weil erst die Klasse TreeMap die Interface "Cloneable" implementiert. 

Damit letzterer code funktioniert müsste das Objekt, dass an die Funktion gegeben wird ja nicht nur die Interface NavigableMap, sondern auch die Interface Cloneable implementiert haben.
Und ich weiß nicht einmal, ob es dann gehen würde, weil die NavigableMap gar nicht die Funktion clone() vorschreibt. Ich muss aber sichergehen können, dass das an die Funktion weitergegebene Objekt sich selber klonen kann. clone() bringt erst die AbstractMap mit (die Oberklasse von TreeMap).

Wie soll ich das mit dem Interface Parameter also in diesem Fall hinkriegen?


----------



## ms (24. Nov 2007)

Es sollte reichen, wenn du java.util.Map() verwendest. Das ist das Topinterface aller Maps.

Frage: Ist es wirklich Aufgabe der Methode startSimulate(..) zu entscheiden ob auf dem original oder auf einem clone arbeitet?
Wenn nicht, dann sollte schon der Aufrufer dafür sorgen, dass ein clone übergeben wird.
Es sollte dann auch die Map als Übergabeparameter reichen.

Übrigens, wiedermal ein Verweis auf die javadocs, diesmal von java.util.Map.
Dort steht in der 2 Zeile der Beschreibung


> This interface takes the place of the Dictionary class, which was a totally abstract class rather than an interface.


ms


----------



## paul3 (24. Nov 2007)

mach dir über den Sinn der Funktion mal keine Gedanken, die ist, so wie sie hier steht nur exemplarisch.


```
private double startSimulate(final Map <String, Integer> map) 
{       
    map = (Map <String, Integer>) map.clone(); 
}
```
geht verständlicherweise aber auch nicht, obwohl ich jetzt das top Interface benutze. Der Compiler sagt immer noch 





> The method clone() is undefined for the type Map<String,Integer>



Ich verstehe ja, warum das so ist, weiß aber nicht, wie ich das Problem lösen kann, wenn ich dem Objekt, das der Funktion überreicht wird, nur die Implementation einer Interface vorschreibe soll (was ihr ja meintet).


----------



## ms (25. Nov 2007)

paul3 hat gesagt.:
			
		

> mach dir über den Sinn der Funktion mal keine Gedanken, die ist, so wie sie hier steht nur exemplarisch.


Auch wenn es nur exemplarisch ist, auf die Sichtweise kommt es in der OOP an.

Es fehlt ein Klammernpaar und du müßtest natürlich auf TreeMap casten, da dort die clone()-Methode implementiert ist.

```
private double startSimulate(final Map <String, Integer> map) 
{       
    map = ((TreeMap <String, Integer>) map).clone(); 
}
```

ms


----------



## Beni (25. Nov 2007)

Die clone-Methode ist nicht immer öffentlich und wird auch durch kein Interface vorgeschrieben. Von dem her würde ich sagen, dass es hier keine wirklich gute Lösung gibt.

Eine erste Variante die mir einfällt:

```
public double startSimulate( TreeMap <String, Integer> map ){
        return startSimulate( (Map<String, Integer>)map.clone() );
    }
    
    public double startSimulate( HashMap<String, Integer> map ){
        return startSimulate( (Map<String,Integer>)map.clone() );
    }
    
    public double startSimulate( Hashtable<String, Integer> map ){
        return startSimulate( (Map<String,Integer>)map.clone() );
    }
    
    private double startSimulate( Map <String, Integer> map ){
        map.put( "bla", 47 );
        return 3.4;
    }
```

Man könnte vielleicht auf das "clone" verzichten, und direkt eine spezielle Map (welche für diese Methode geeignet ist) verwenden:

```
private double startSimulate( Map <String, Integer> map ){
        Map<String, Integer> copy = new HashMap<String, Integer>( map );
        return 3.4;
    }
```

Eine ziemlich aufwändige Variante: selbst ein Interface definieren, welches "clone" vorschreibt, und implementieren. Von einem OOP-Standpunkt aus, würde ich das fast als die schönste Variante bezeichnen:

```
private double startSimulate( CloneableMap<String, Integer> map ){
    CloneableMap<String, Integer> clone = map.clone();
    return 3.4;
}

public interface CloneableMap<K, V> extends Map<K, V>, Cloneable{
    public CloneableMap<K, V> clone();
}

public class CloneableTreeMap<K, V> extends TreeMap<K, V> implements CloneableMap<K, V>{
    public CloneableTreeMap() {
        super();
    }

    public CloneableTreeMap( Comparator<? super K> c ) {
        super( c );
    }

    public CloneableTreeMap( Map<? extends K, ? extends V> m ) {
        super( m );
    }

    public CloneableTreeMap( SortedMap<K, ? extends V> m ) {
        super( m );
    }

    @Override
    @SuppressWarnings( "unchecked" )
    public CloneableMap<K, V> clone() {
        return (CloneableMap<K, V>)super.clone();
    }
}
```


----------



## paul3 (25. Nov 2007)

Das letzte find ich irgendwie witzig  Aber eben auch sehr allgemein gehalten - im positiven Sinne.

So jetzt da ihr mir alles über Interfaces so super erklären konntet, beende ich diesesn riesen Thread mit einem Klick auf das Häckchen! Vielen Dank an alle, die mir geholfen haben!!!!


----------



## Guest (3. Apr 2008)

stevieboy hat gesagt.:
			
		

> ```
> public class ListAction {
> private void doThingsWithList(List<String> list){ // Gut der Parameter ist nur das Interface!!!
> for (String entry : list) {
> ...




Sorry das ich diesen alten Thread nochmal hochhole aber ich versteh hier einiges nicht! 

z.B:
	
	
	
	





```
private void doThingsWithList(List<String> list)
```

Hier wird ein List-Objekt übergeben. Aber List selber ist ja nur ein Interface. Wie kann man dann
davon eine Instanz bilden? Und was hat es mit dem <String> auf sich? 


```
for (String entry : list) {
```

Das versteh ich am allerwenigsten. Ich kenne for-Schleifen nur so das in den Funktionsklammern
drei Anweisungen stehen (Vereinfacht ausgedrückt). Jetzt steht hier aber nur eine? Und dazu: Was soll der ":"
für ne bedeutung haben? Den hab ich in Java noch nie gesehen.

Kann mir das mal jemand erklären?

Danke im Voraus!


----------

