Interface

Stefan Dreis

Mitglied
Interfaces beschreiben ja Schnittstellen. Mich würde jetzt mal interssieren wie Interfaces anständig benutzt werden von euch. Schreibt ihr in Interfaces alle public Funktionen der Implementierten Klasse rein? Also z.B.

Code:
interface MyInterface {
              public funcA();
              public funcB();
              public funcC();
}

class MyClass implements MyInterface {
                public funcA();
                public funcB();
                public funcC();
}

oder doch eher nur die Funktionen auf die von anderen Klassen drauf zugriffen wird. z.B. im folgenden Beispiel wird z.B. ( aus was für Gründe auch immer ) die funcC zwar nur intern verwendet, aber bewusst nicht als protected gekennzeichnet

Code:
interface MyInterface {
              public funcA();
              public funcB();
}

class MyClass implements MyInterface {
                public funcA();
                public funcB();
                public funcC();
}

public MyCallClass {
          public myfunc() {
                    MyClass.funcA();
                    ...
                    MyClass.funcB();
           }
}

Und wie ist in der Praxis die übliche Benennung einer Interface und eine von einem Interface abhängigen Klasse? So z.B.

Code:
interface User {
}

class UserImpl extends User {
}

In einigen Beispielen habe ich ferner gesehen (da java ja Namespaced Datenstrukturen hat) das in einer die Package in der obersten Schicht die Interface Dateien beinhaltet und in untergeordneten Verzeichnis die eigentlichen klassen also wie z.B.

- Personenverzeichnis ( Dateiverzeichnis )
--- Person.java ( Interface Klasse)
--- User.java ( Interface Klasse )
-------- Impl ( Dateiverzeichnis )
------------ PersonImpl.java ( eigentliche Implementierungs Klasse )
------------ UserImpl.java ( eigentliche Implementierungsklasse )

Ist das in Firmen eine übliche Orderstruktur?
 
Zuletzt bearbeitet von einem Moderator:
oder doch eher nur die Funktionen auf die von anderen Klassen drauf zugriffen wird.
Ja, eher so. Aufgrund der Tatsache, dass Klassen mehrere Interfaces implementieren können, kann man jedes Interface tendenziell eher schmal halten (weniger Methoden). Denn je mehr Methoden (die möglicherweise garnicht gebraucht werden) ein Interface definiert, desto schwieriger wird es für einen Implementierer.
- Personenverzeichnis ( Dateiverzeichnis )
--- Person.java ( Interface Klasse)
--- User.java ( Interface Klasse )
-------- Impl ( Dateiverzeichnis )
------------ PersonImpl.java ( eigentliche Implementierungs Klasse )
------------ UserImpl.java ( eigentliche Implementierungsklasse )

Ist das in Firmen eine übliche Orderstruktur?
Nenn die Verzeichnisse packages und schreib sie mit kleinem Anfangsbuchstaben, dann ist das durchaus eine übliche Vorgehensweise.
 
Um den richtigen Umgang mit Interfaces zu verstehen sollte man sich erst einmal angucken, was Interfaces ausmacht, worin sie ihre Sträken haben... z.B. gegenüber abstract Classes

Vorteile:
-Mehrfachvererbung Möglich
-Man kann Programmierer dazu zwingen Methoden zu programmieren

Nachteile:
-Alle Methoden eines Interfaces müssen immer komplett neu implementiert

Wichtig hier bei ist wie immer, eine ordentliche Bezeichnung der Klassen, Methoden, Interfaces, etc..

Und wie ist in der Praxis die übliche Benennung einer Interface und eine von einem Interface abhängigen Klasse?
Java:
Code:

interface User {
}

class UserImpl extends User {
}

Zunächst einmal extends ist hier falsch >implements< müsste da stehen. Desweiteren kannst du auch über Subinterfaces ein normales Interface erweitern. Näheres kannst du in z.B. Java ist eine Insel lesen.

Hier der Link:
Java ist auch eine Insel – 6.11 Schnittstellen
 
Zur Benennung der Klassen: Ich hab auch schon öfter gesehen, dass das Interface mit einem I beginnt, also zB IBird und die konkreten Klassen, die dieses Interface implementieren, dann "normale" Namen wie Duck oder Pigeon. Ob das jetzt so üblich ist, kann ich aber nicht beurteilen. Ich finde, dass beides in Ordnung ist.
 
Gonzo17 hat gesagt.:
Ob das jetzt so üblich ist, kann ich aber nicht beurteilen. Ich finde, dass beides in Ordnung ist.
Ja, das ist genauso üblich, wie das andere. Viele Open Source Projekte (ich glaub u.a. auch Eclipse) benutzen diese Konvention. In einer großen Logistikfirma, für die ich gearbeitet habe, wurde auch diese Konvention verwendet. Ich denke auch, dass beides in Ordnung ist, mir gefällt das erste aber besser. Mich nerven die großen Is ;-))
 
Ja, das ist genauso üblich, wie das andere. Viele Open Source Projekte (ich glaub u.a. auch Eclipse) benutzen diese Konvention. In einer großen Logistikfirma, für die ich gearbeitet habe, wurde auch diese Konvention verwendet. Ich denke auch, dass beides in Ordnung ist, mir gefällt das erste aber besser. Mich nerven die großen Is ;-))

Ja, hauptsächlich ist das in der Eclipse-Welt Konvention (und C#). Allerdings gibt keinen Grund, warum man ein I vor alle Interface-Namen schreiben sollte. Ganz im Gegenteil. Die Lösung mit "interface User" und "UserImpl" ist eindeutig besser.
 
@maki

Hm, das was dort erklärt wird macht irgendwie Sinn. Zumal es ja tatsächlich so ist, dass jede IDE auch anzeigt, ob es ein Interface oder eine Klasse ist.
 
Ja Gonzo17, ich kann diese Argumentation auch gut nachvollziehen.

Das hat aber einen Nachteil:
Man muss die Problemdomäne gut kennen & verstehen, sonst findet man keine so gute Namen 😉
 
Es gibt Stimmen die behaupten, dass IInterface und InterfaceImpl beide gleich schlecht sind.
Sicherlich problematisch (wenn einem was anderes einfällt als "Impl"-Suffix, ist das natürlich noch besser), aber gleich schlecht würde ich nicht sagen. Im Quelltext schreibe und lese ich die Interface-Typen jedenfalls sehr viel häufiger als die Impl-Typen. Und da stört ein "I" doch ziemlich.
 
Threads zu diesem Thema gibt es zuhauf hier im Forum. Letztendlich ist es imho Geschmackssache wie man etwas löst.
 
Das I kenne ich in java auch nur von Eclipse RCP & Konsorten, ist mir sonst nie untergekommen.
Das Impl dagegen habe ich schon öfters gesehen, scheint üblicher zu sein.

Naja, muss zugeben, das ich mich hab schon "zwingen" lassen beides gleichzetiig zu machen, also I fürs Interface und gleichzeitig und Impl für die Implementierung... war nicht meine Entscheidung, aber ich war jung und brauchte das Geld... 😉
 
Mit dem ImplSuffix könnte ich doch jedes Interface nur ein mal implementieren? 😵
Bzw was wäre die Namenskonvention für ein Interface Vogel mit 2 implementierenden Klassen?
 
Ich glaub nicht dass irgendwo jemand geschrieben hat dass man Implementierungen immer
Code:
<interface>Impl
nennen sollte 😉
 
Könntest du mir bitte erläutern, warum ich ein Interface verwenden sollte, das nur von einer Klasse implementiert wird. Außer bei einer einfachen Implementierung des Observer Patterns als Uni-Hausaufgabe habe ich noch nie ein Interface nur mittels einer Klasse implementiert...
 
Zuletzt bearbeitet:
Hi,

ersteinmal sind die Methoden eines Interfaces immer public, auch ohne Zugriffsmodifizierer.

FangFrage: Macht es Sinn eine Methode in einem Interface private zu deklarieren?

Zur Bennung kann man das Interface mit I beginnen. z.B. IUser und die Klasse dann User, ist halt ne stilsache die jeder für sich entscheiden muss.

Interfaces zu benutzen macht Sinn, wenn man sich Instanzen eines Typs über eine Fabrikmethode hohlt. Dass heißt dass irgendwo in meinem Programm von einer externen Schnittstelle eine Klasse bereitgestellt wird, die je nach Anforderung eine Instanz einer Klasse erzeugt die das Interface implementiert.

Bsp.: Das Paket java.sql Hier gibt es eine Klasse Connection. Um jetzt z.B. eine Datenbankabfrage durchführen zu können benötigt man eine Instanz des Interfaces Statement. Da aber für jede unterschiedliche Datenbank die implementierende Klasse ganz anders aufgebaut ist/Ansprüche hat, definiert man durch das Interface die Funktionalitäten die jede Datenbankinteraktion bereitstellen sollte. Die Instanz der Klasse Statement wird durch den entsprechenden Treiber erzeugt/fabriziert.
Connection.createStatement (Fabrikmethode). In deinem Programm hast du die ganze Zeit über nur ein Interface deklariert mit dem dur arbeitest. Da drin befindet sich eine konkrete Klasse die uns ja auch völlig egal sein kann. Ferner gibt die Methode executeQuery des Interfaces Statement wieder ein Interface zurück nämlich das ResultSet. Auch hier wieder das gleiche Prinzip. In deinem Programm arbeitest du die ganze Zeit nur mit einer als Interface deklarierten Variable.

Für die Klasse User ist es nicht unbedingt sinnvoll vorher ein Interface zu deklarieren...
 
Mit dem ImplSuffix könnte ich doch jedes Interface nur ein mal implementieren? 😵
Bzw was wäre die Namenskonvention für ein Interface Vogel mit 2 implementierenden Klassen?

Ich glaube du hast da was falsch verstanden. Du kannst doch einfach frei nach EikeB's Beispiel folgendes machen:

interfaces Vogel
class SpechtImpl implements Vogel
class HabichtImpl implements Vogel

Es geht - meinem Verständnis nach - nicht darum, dass man zwingend den Interface-Namen wiederverwendet, sondern mehr darum, dass man erkennt was ein Interface und was eine Klasse ist.


Könntest du mir bitte erläutern, warum ich ein Interface verwenden sollte, das nur von einer Klasse implementiert wird. Außer bei einer einfachen Implementierung des Observer Patterns als Uni-Hausaufgabe habe ich noch nie ein Interface nur mittels einer Klasse implementiert...

Entsprechend auch hier, natürlich macht ein Interface mit nur einer Implementierung keinen Sinn.
 
Eine einzige Implementierung von einem Interface nutzt man in Java zB. um den Code testfähig zu halten wie bei TDD.
Das findet man auch häufiger, liegt IMHo an ein paar Einschränkungen von Java, konkrete Klassen/Methoden mocken kann zB. unter OSGi problematisch werden wenn diese Methoden zB. final sind.
 
Auch wenn man nur eine Implementierung eines Interfaces persönlich schreibt, heißt das nicht, dass es nur eine gibt. Zum Beispiel bei AOP oder Client/Server-Architekturen werden oft synthetische Proxy-Klassen erzeugt, die das Interface implementieren.
 
Hm, könntest du mir da ein konkretes Beispiel sagen?
Kein konkretes Beispiel, TDD konkret wäre eben Testgetrieben zu entwickeln 😉

Bei TDD fängt man mit dem Test an, die Klasse/Methoden oder allgemein den Code der getestet wird schreibt man danach 😉
Für Kolaborateure, also andere Objekte/Klassen welche die zu testende Klasse nutzt (Abhängigkeiten), verwendet man nur ein Interface (Mock Roles, not Objects!) welches gemockt wird, so isoliert man den Code der zu testen ist von code, den man nicht testen möchte .
So vermeidet man zB. ein echtes RDBMS zu benötigen wenn man zB. code testet, der ein DAO nutzt, das DAO wird gemockt und keine echte DB ist nötig.

Andere Sprachen können auch ohne extra Interface und Framework mocken, aber in Java sind Interfaces zum Mocken noch am besten geeignet, da man damit eben die Schnittstelle von der Implementierung entkoppelt.

Genaugenommen müsste man dann auch sagen, dass die Mocks eben alternative Implementierungen des Interfaces sind, aber nur zum testen genuzt werden.
 
Jetzt verstehe ich was du meinst. Ja, das hab ich durchaus auch schon so verwendet. In einem kleinen E-Mail-Client, den ich mit ATDD/TDD entwickelt habe, hatte ich das Interface MailServer, bei den Tests wurde ein FakeMailServer verwendet, der eben nur so tut als würde er Mails liefern, und in der Anwendung selbst gibt es dann verschiedene (reale) Implementierungen davon.

Aber wie du sagst, da macht man die Schnittstelle ja auch nicht nur für eine Implementierung, denn zumindest beim Testen wird das Interface nochmal genutzt.
 

Zurück
Oben