was bringt Interface

Status
Nicht offen für weitere Antworten.

paul3

Mitglied
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:

Code:
void flügelHoch();
void flügelRunter();
boolean starten();
boolean landen();
 

ARadauer

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

Ei
 

Niki

Top Contributor
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

Top Contributor
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

Aktives Mitglied
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
Code:
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:

Code:
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

Top Contributor
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

Mitglied
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
Code:
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:
Code:
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

Mitglied
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
Code:
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 !?
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.
Code:
public class MyWindowListener implements WindowListener {  // oder: extends WindowAdapter
// ...
}
Code:
public class MyFrame extends JFrame {
    public MyFrame() {
        //...
        addWindowListener(new MyWindowListener());
    }
}
 

paul3

Mitglied
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:

Code:
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 ?
 
B

Beni

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

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

Natürlich kann sich das hinter Indirektionen verstecken:
Code:
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

Top Contributor
paul3 hat gesagt.:
Code:
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 ?

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

Top Contributor
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:
Code:
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. ;)
 

paul3

Mitglied
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
Code:
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:
Code:
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

Top Contributor
paul3 hat gesagt.:
Nur Kann ich ja nun nicht einfach
Code:
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.

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

Mitglied
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:
Code:
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 ?
 
G

Guest

Gast
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:

Code:
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.

Code:
LinkedList myList = new LinkedList();

anstatt

Code:
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

Top Contributor
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:
Code:
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

Mitglied
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 ?
 

sowieso

Aktives Mitglied
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:

Code:
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:

Code:
class EuropeAmpel extends AbstractAmpel
{
    ....
}

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

Code:
class EuropeAmpel extends AbstractAmpel implements Ampel
{
    ....
}

Und in der Interface "Ampel" steht dann:

Code:
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

Top Contributor
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:

Code:
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

Aktives Mitglied
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?
 

paul3

Mitglied
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

Top Contributor
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:

Code:
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

Mitglied
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

Aktives Mitglied
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

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

aber eben nicht

Code:
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

Mitglied
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

Top Contributor
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. :D

ms
 

paul3

Mitglied
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 :D

Ich wollte nun das hier gelernte anwenden. bis dato hatte ich eine Funktion
Code:
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:
Code:
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

Top Contributor
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

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

Code:
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

Top Contributor
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.
Code:
private double startSimulate(final Map <String, Integer> map) 
{       
    map = ((TreeMap <String, Integer>) map).clone(); 
}

ms
 
B

Beni

Gast
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:
Code:
    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:
Code:
    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:
Code:
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

Mitglied
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!!!!
 
G

Guest

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


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

z.B:
Code:
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?

Code:
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!
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
H Scanner nextLine() bringt Dateipfad Java Basics - Anfänger-Themen 1
H Was bringt der Decompiler javap? Java Basics - Anfänger-Themen 2
P Was genau bringt mir es ein Array in eine Liste zu bringen Java Basics - Anfänger-Themen 3
D Aufruf von mehreren Activities bringt die app zum Absturz Java Basics - Anfänger-Themen 5
T Was bringt das synchronized bei der Methode? Java Basics - Anfänger-Themen 12
A SelectionSort bringt keine konstanten Ergebnisse Java Basics - Anfänger-Themen 4
D Methoden ArrayList Rückgabe bringt komische Werte Java Basics - Anfänger-Themen 12
N Übungsaufgabe aus Java Buch bringt Fehler. Java Basics - Anfänger-Themen 10
K Java-Editor: "Starten" bringt Error Java Basics - Anfänger-Themen 15
D Serialisieren, was bringt das? Java Basics - Anfänger-Themen 8
M Was macht bzw. was bringt ein constructor? Java Basics - Anfänger-Themen 12
D setAlwaysOnTop(true); toFront(); - bringt alles nichts Java Basics - Anfänger-Themen 5
K Datentypen Über Collection iterieren bringt fehler Java Basics - Anfänger-Themen 8
S selectionListener bringt NullPointerException Java Basics - Anfänger-Themen 2
C GUI aktualisieren: repaint, validate, Fenstergröße ändern bringt nichts Java Basics - Anfänger-Themen 13
G RowSorter beim JTable bringt Programm durcheinander Java Basics - Anfänger-Themen 23
F Generische Methode - was bringt der Wildcard Operator? Java Basics - Anfänger-Themen 7
P mixer.getControl() bringt nur Fehlermeldung . Java Basics - Anfänger-Themen 7
O JOptionPane bringt Fehler Java Basics - Anfänger-Themen 2
A Wochentag über SimpleDateFormat bringt wirre Ergebnisse Java Basics - Anfänger-Themen 4
S Import Pakete oder auflösen . .*, bringt das was? Java Basics - Anfänger-Themen 5
M GregorianCalendar bringt mich um. Java Basics - Anfänger-Themen 8
R Klassen in getrennte Dateien - Was bringt das?! Java Basics - Anfänger-Themen 4
S Eingelesenes Array in JTable bringt kein Ergebnis Java Basics - Anfänger-Themen 8
I No Jakarta Enterprise Beans found with interface ignorieren? Java Basics - Anfänger-Themen 2
I No EJB found with interface of type Java Basics - Anfänger-Themen 12
wolei Java generic interface in a generic class Java Basics - Anfänger-Themen 6
Say Abstrakt oder Interface Java Basics - Anfänger-Themen 3
Say public/default Interface Java Basics - Anfänger-Themen 9
D Interface Methode wird ungewollt in der Subklasse überschrieben Java Basics - Anfänger-Themen 5
W Intuitive interface für Komponenten Java Basics - Anfänger-Themen 4
I Browser integriert in Desktop Applikation - Webcam interface not found Java Basics - Anfänger-Themen 26
U Beispiel Methode size() vom "Collection"-interface... Wie kann man sichtbar machen, was die Methode unter der Haube macht? Java Basics - Anfänger-Themen 8
J Interface Comparable<T> Java Basics - Anfänger-Themen 10
M Interface oder Vererbung? Java Basics - Anfänger-Themen 12
D Interface Verständisfrage Java Basics - Anfänger-Themen 8
U Interface | constructor injection Java Basics - Anfänger-Themen 5
J Interface Interface korrekt implementieren Java Basics - Anfänger-Themen 5
A Methoden Vererbung und Interface Java Basics - Anfänger-Themen 14
T Interface Map und Map.Entry Java Basics - Anfänger-Themen 4
U Interface als PAramter (Vergleich) und ein Error Java Basics - Anfänger-Themen 9
I Interface von einer EJB Klasse, um Code zu reduzieren Java Basics - Anfänger-Themen 1
M Interface als Parameter einer Klasse Java Basics - Anfänger-Themen 8
M Wie kann ich eine Methode aus einem Interface in eine Klasse implementieren, so dass sie ihre Funktion ausführt? Java Basics - Anfänger-Themen 7
I JSON und Interface Java Basics - Anfänger-Themen 3
Kotelettklopfer Kleines Testprogramm mit Interface und einer Usereingabe Java Basics - Anfänger-Themen 16
J Interface methode aufrufen (interface parameter) Java Basics - Anfänger-Themen 7
CptK Interface Functional interface mit mehreren Methoden Java Basics - Anfänger-Themen 6
L Interface & Comparable Java Basics - Anfänger-Themen 15
T Interface Java Basics - Anfänger-Themen 0
CptK Generics: Klassen die Interface implementieren, aber selbst nicht das Interface sind Java Basics - Anfänger-Themen 8
B Interface List - Objekt übergeben? Einzelnes Objekt geht, aber Liste nicht? Java Basics - Anfänger-Themen 4
B Best Practice Unschlüssig ob Vererbung oder Interface Java Basics - Anfänger-Themen 2
E abstrakte Klasse implementiert ein Interface Java Basics - Anfänger-Themen 40
C Interface und Konstruktor Java Basics - Anfänger-Themen 1
S Interface Equals und hashCode Java Basics - Anfänger-Themen 16
A Generische Klassen/Interface Java Basics - Anfänger-Themen 1
C Methoden-Parameter ist Interface Java Basics - Anfänger-Themen 5
B Collections Objektreferenz-ID in der Ausgabe (Comparator Interface) Java Basics - Anfänger-Themen 2
A Interface Kuddelmuddel Java Basics - Anfänger-Themen 4
C Collections List über Interface zugreifen Java Basics - Anfänger-Themen 32
S Interface Interface und seine Implementierung Java Basics - Anfänger-Themen 5
H abstract und interface Java Basics - Anfänger-Themen 4
F Interface Casting Java Basics - Anfänger-Themen 13
C Telefonliste mit interface implementieren Java Basics - Anfänger-Themen 30
L Klassen Kann eine Unterklasse einer abstrakten Klasse ein Interface implementieren? Java Basics - Anfänger-Themen 2
H Interface Java Basics - Anfänger-Themen 2
R Quicksort mit Interface Comparable Java Basics - Anfänger-Themen 6
T Interface Methode im Interface mit mehreren Parametern Java Basics - Anfänger-Themen 10
B Interface vs Abstract Java Basics - Anfänger-Themen 2
B Objekte zählen/ Vererbung/ Kopplung/ Interface/ Abstract Class Java Basics - Anfänger-Themen 5
pkm Interface Funktionales Interface lässt sich nicht implementieren. Java Basics - Anfänger-Themen 2
Kornblume Comparable Interface für Objektvergleiche nutzen Java Basics - Anfänger-Themen 15
I Comparator<T> Interface als Methodenparamter Java Basics - Anfänger-Themen 4
J OOP Wie sollte ich das organisieren (Abstract? Interface?) Java Basics - Anfänger-Themen 33
J Java Interface/abstrakte Klassen Java Basics - Anfänger-Themen 2
E Interface nur von abstrakter Klasse implementierbar?! Java Basics - Anfänger-Themen 1
J Vererbung Abstrake Klasse <-> Interface Java Basics - Anfänger-Themen 5
C Interface als Datentyp eines Attributes? Java Basics - Anfänger-Themen 6
U Interface Bedeutung "Code to an interface rather than to an implementation." Java Basics - Anfänger-Themen 4
M Erste Schritte Prüfungsbeispiel: Interface / abstrakte Klassen Java Basics - Anfänger-Themen 8
M Maven Main-Methode Interface und Klasse Java Basics - Anfänger-Themen 2
R Interface Eigene Objekte in Listen sortieren mit Interface Comparable Java Basics - Anfänger-Themen 5
D Interface Amazon Skill Kit, Interface but method in other class? Java Basics - Anfänger-Themen 3
A Interface Abstrakte Interface Methode kann nicht benutzt werden Java Basics - Anfänger-Themen 10
J Compiler-Fehler class interface or enum expected Java Basics - Anfänger-Themen 1
T Vererbung und interface. Java Basics - Anfänger-Themen 1
N Interface Interface Erstellung Java Basics - Anfänger-Themen 3
kilopack15 Beziehung Interface - (abstrakte) Klasse -Unterklasse Java Basics - Anfänger-Themen 3
C Interface Fragen zum Interface Java Basics - Anfänger-Themen 7
Azazel Ist die abstract class das selbe wie ein interface ? Java Basics - Anfänger-Themen 33
K Interface: wie damit arbeiten Java Basics - Anfänger-Themen 4
lBlKha0s Fehlermeldung : class interface or enum expected Java Basics - Anfänger-Themen 9
T error: class, interface, or enum expected Java Basics - Anfänger-Themen 5
T Vererbung Interface Java Basics - Anfänger-Themen 5
F Interface aus anderem Package nutzen Java Basics - Anfänger-Themen 10
N Interface Daten einem Implementierten Interface zuweisen Java Basics - Anfänger-Themen 37
B Erste Schritte Wie definiere ich in Java ein Interface? Java Basics - Anfänger-Themen 6
L OOP Interface Prinzip? Java Basics - Anfänger-Themen 6
K Nutzung einer Klasse die das Iterator-Interface implementiert Java Basics - Anfänger-Themen 0

Ähnliche Java Themen

Neue Themen


Oben