2009-02-27 1 views

Antwort

18

Ich denke an eine andere Verwendung als die von Eric P verknüpften: Definieren einer Standard/No-Op-Implementierung der Schnittstelle.

./alex

interface IEmployee 
{ 

    void workHard(); 
    void procrastinate(); 

    class DefaultEmployee implements IEmployee 
    { 
     void workHard() { procrastinate(); }; 
     void procrastinate() {}; 
    } 

} 

Noch eine weitere Probe - Implementierung von Null Object Pattern:

interface IFoo 
{ 
    void doFoo(); 
    IFoo NULL_FOO = new NullFoo(); 

    final class NullFoo implements IFoo 
    { 
     public void doFoo() {}; 
     private NullFoo() {}; 
    } 
} 


... 
IFoo foo = IFoo.NULL_FOO; 
... 
bar.addFooListener (foo); 
... 
+0

Ooh, Ich mag diese Idee. – Herms

+0

@Totophil: froh, dass Sie die Idee und den Dank für die Verbesserung meiner Antwort bekommen haben. @herms: froh, dass es Ihnen gefällt! – alexpopescu

+1

Allgemein Null-Objekt könnte auch ein Singleton sein, da es keinen Zustand hält oder irgendwelche anderen Objekte mutiert - das ist eigentlich eine großartige Antwort, da ich von nun an anfangen werde, Dinge wie diese zu tun, das ist schlau! – Esko

5

ich ohne zu zögern sagen kann, dass ich das nie getan habe. Ich kann mir keinen Grund vorstellen, warum du es auch tun würdest. Klassen innerhalb von Klassen verschachtelt? Sicher, viele Gründe, das zu tun. In diesen Fällen tendiere ich dazu, diese inneren Klassen als ein Implementierungsdetail zu betrachten. Offensichtlich hat eine Schnittstelle keine Implementierungsdetails.

8

Ich denke, this page erklärt ein Beispiel ziemlich gut. Sie würden es verwenden, um einen bestimmten Typ fest an eine Schnittstelle zu binden.

riss Schamlos aus den obigen Link aus:

interface employee{ 
    class Role{ 
      public String rolename; 
      public int roleId; 
    } 
    Role getRole(); 
    // other methods 
} 

In der obigen Schnittstelle Sie die Rolle stark an die Mitarbeiter-Schnittstelle (employee.Role) Typ sind verbindlich.

2

Ich denke, Sie könnten eine Klasse definieren, die als Rückgabetyp oder Parametertyp für Methoden innerhalb der Schnittstelle verwendet wird. Scheint nicht besonders nützlich. Sie können die Klasse auch einfach separat definieren. Der einzige mögliche Vorteil ist, dass die Klasse in gewisser Weise als "zugehörig" zur Schnittstelle deklariert wird.

1

Dies zu tun scheint zu haben "Bad Design Entscheidung" über alles geschrieben.

1

Ich würde zur Vorsicht mahnen, wenn es wie eine gute Idee scheint eine nicht-private verschachtelte Klasse zu erstellen. Sie sind fast sicher besser dran für eine äußere Klasse. Wenn Sie jedoch eine öffentliche verschachtelte Klasse erstellen möchten, ist es nicht sonderlich seltsam, sie in eine Schnittstelle zu schreiben. Die Abstraktheit der äußeren Klasse hängt nicht notwendigerweise mit der Abstraktheit einer verschachtelten Klasse zusammen.

2

Google Web Toolkit solche Klassen verwendet ‚normale‘ Schnittstelle zum asynchronen Aufruf Schnittstelle zu binden:

public interface LoginService extends RemoteService { 

    /** 
    * Utility/Convenience class. 
    * Use LoginService.App.getInstance() to access static instance of LoginServiceAsync 
    */ 
    class App { 

     public static synchronized LoginServiceAsync getInstance() { 
      ... 
     } 
    } 
} 
6

Eine Verwendung (zum Besseren oder Schlechteren) würde für die Tatsache, wie dieses Problem zu umgehen, dass Java nicht unterstützt statische Methoden in Schnittstellen.

interface Foo { 
    int[] getData(); 

    class _ { 
     static int sum(Foo foo) { 
      int sum = 0; 
      for(int i: foo.getData()) { 
       sum += i; 
      } 
      return sum; 
     } 
    } 
} 

Dann würden Sie es mit rufen:

int sum = Foo._.sum(myFoo); 
+0

Das ist so schlimm, dass ich es abstimmen muss. Ich liebe diese Art von Experimenten. – akuhn

+1

Sie müssen mich verarschen. Sie lassen das kompilieren ???!?!? (nice one, btw) – Overflown

3

Ein Ort, dieses Idiom stark in XMLBeans ist, verwendet wird. Der Zweck dieses Projekts besteht darin, ein XML-Schema zu erstellen und eine Reihe von Java-Klassen zu generieren, die Sie bidirektional verwenden können, um mit XML-Dokumenten zu arbeiten, die dem Schema entsprechen. So können Sie XML in XML-Beans analysieren oder die XML-Beans erstellen und an XML ausgeben.

Im Allgemeinen sind die meisten XML-Schematypen einer Java-Schnittstelle zugeordnet.Diese Schnittstelle hat in sich eine Fabrik, die verwendet wird Instanzen dieser Schnittstelle in der Standardimplementierung zu generieren:

public interface Foo extends XmlObject { 
    public boolean getBar(); 
    public boolean isSetBar(); 
    public void setBar(boolean bar); 

    public static final SchemaType type = ... 

    public static final class Factory { 
    public static Foo newInstance() { 
     return (Foo)XmlBeans.getContextTypeLoader().newInstance(Foo.type, null); 
    } 

    // other factory and parsing methods 
    } 
} 

Als ich das erste begegnet es schien falsch all diese Implementierung klebrige Masse in die Schnittstellendefinition zu binden. Wie auch immer, ich habe es wirklich gemocht, da es alles in Bezug auf Schnittstellen definiert hat, aber eine einheitliche Möglichkeit hat, Instanzen der Schnittstelle zu erhalten (im Gegensatz zu einer anderen externen Fabrik-/Erstellerklasse).

Ich nahm es für Klassen, wo dies Sinn machte (vor allem diejenigen, wo ich eine große Kontrolle über die Schnittstelle/impls hatte) und fand es ziemlich sauber.

1

Dieser Ansatz kann verwendet werden, um viele Klassen in derselben Datei zu definieren. Dies hat in der Vergangenheit gut funktioniert, wo ich viele einfache Implementierungen einer Schnittstelle habe. Wenn ich dies jedoch noch einmal machen würde, würde ich ein Enum verwenden, das eine Schnittstelle implementiert, die eine elegantere Lösung wäre.

+0

Kommentare ausblenden Ich dachte über die Implementierung durch Enum als gut nach, aber da jede Enum ist effektiv eine Sammlung von Singletons Ich hatte Mühe, an irgendwelche realen Proben dort denken würde jeder möchte eine Reihe von "Standard" Singletons, die für die gleiche Schnittstelle implementieren. –

2

Mit einer statischen Klasse innerhalb einer Schnittstelle haben Sie die Möglichkeit, ein gemeinsames Programmierfragment zu verkürzen: Überprüfen, ob ein Objekt eine Instanz einer Schnittstelle ist, und wenn ja, Aufruf einer Methode dieser Schnittstelle. Schauen Sie sich dieses Beispiel:

public interface Printable { 
    void print(); 

    public static class Caller { 
     public static void print(Object mightBePrintable) { 
      if (mightBePrintable instanceof Printable) { 
       ((Printable) mightBePrintable).print(); 
      } 
     } 
    } 
} 

Jetzt statt, dies zu tun:

void genericPrintMethod(Object obj) { 
    if (obj instanceof Printable) { 
     ((Printable) obj).print(); 
    } 
} 

Sie schreiben:

void genericPrintMethod(Object obj) { 
    Printable.Caller.print(obj); 
} 
Verwandte Themen