2009-02-27 5 views

答えて

18

私はEric Pによってリンクされているもの以外の使用法を考えています:インターフェースのデフォルト/ノーオペレーションの実装を定義しています。

./alex

interface IEmployee 
{ 

    void workHard(); 
    void procrastinate(); 

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

} 

さらに別のサンプル - 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

をああ、私はそのアイデアが好きです。 – Herms

+0

@トトフィル:あなたのアイデアを得て、私の答えを高めることに感謝してうれしいです。 @Herms:うれしいよ! – alexpopescu

+1

一般的にNullオブジェクトは、状態を保持したり、他のオブジェクトを変更したりしないため、シングルトンになることもあります。これは実際にはこれからのようなことを始めるつもりだから実際には素晴らしい答えです。 – Esko

5

私は、私はそれをやったことがないことをためらうことなく言うことができます。私はあなたがどちらかの理由を考えることができません。クラス内にネストされたクラス?確かに、そうする理由はたくさんあります。そのような場合は、それらの内部クラスを実装の詳細とみなす傾向があります。明らかに、インタフェースに実装の詳細はありません。

8

私はthis pageとよく考えています。これを使用して、特定のタイプをインターフェイスに強くバインドします。あなたは従業員のインターフェース(employee.Role)に強くロールタイプを結合している上記のインターフェースで

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

恥知らずは、上記のリンクから食い物に。

2

私は、インターフェイス内のメソッドの戻り値の型またはパラメータの型として使用されるクラスを定義できると思います。特に有用とは思われません。クラスを別々に定義することもできます。可能な唯一の利点は、クラスをある意味でインターフェースに「所属する」と宣言することです。

1

これを行うには、「悪い設計の決定」が書かれているようです。

1

非プライベート入れ子になったクラスを作成するために、良いアイデアのように思える時はいつでも私は注意を促します。あなたは外のクラスのためにまっすぐ行くのがほぼ確実です。しかし、パブリックのネストされたクラスを作成しようとしている場合、それはクラスよりもインターフェイスに配置することはそれほど奇妙ではありません。外部クラスの抽象度は必ずしも入れ子クラスの抽象度に関係しているとは限りません。

2

Googleウェブツールキットは、非同期呼び出しインターフェースに「通常の」インターフェースをバインドするために、このようなクラスを使用しています(良くも悪くも)

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

一つの使用Javaがサポートされていないという事実のための回避策としてだろうインタフェース内の静的メソッド頻繁に使用されるこのイディオムはXMLBeansである

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

それは私がそれを投票しなければならないほど悪いです。私はこの種の実験が大好きです。 – akuhn

+1

あなたは私を冗談にしなければなりません。彼らはこれをコンパイルしようとしましたか?!?!? – Overflown

3

一つの場所:

interface Foo { 
    int[] getData(); 

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

その後、あなたがそれを呼び出すと思います。このプロジェクトの目的は、XML Schemaを使用して、スキーマに対応するXML文書を処理するために双方向に使用できる一連のJavaクラスを生成することです。したがって、XMLをXML Beanに解析したり、XML Beanを作成してxmlに出力したりすることができます。

一般に、ほとんどのxmlスキーマタイプはJavaインターフェイスにマップされます。私が最初にそれがインターフェース定義にすべてのこの実装のネバネバしたものを結合するのに間違ったように見えたこの遭遇したとき

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 
    } 
} 

:そのインターフェイスは、その中にデフォルトの実装では、そのインタフェースのインスタンスを生成するために使用された工場を持っています。しかし、私は実際にはすべてがインターフェースの面で定義されるようになりましたが、(別の外部のファクトリー/ビルダー・クラスを持つのとは対照的に)インターフェースのインスタンスを取得するための統一された方法を持っていました。

私はこれが理にかなったクラス(とりわけ、私がインターフェイス上で多大なコントロールを行っていたもの/ impls)のためにそれを選んで、かなりきれいであることを発見しました。

1

このアプローチを使用して、同じファイル内に多くのクラスを定義できます。これは過去に私がインターフェイスの多くの簡単な実装を持っている私のためにうまくいきました。しかし、私がこれをやり直す場合、より洗練された解決策だったインターフェースを実装するenumを使用します。

+0

コメントを隠す 私はenumでも実装について考えていましたが、enumは効果的にシングルトンのコレクションなので、実際のサンプルを考えるのに苦労していました。誰もが "デフォルト"同じインタフェースに対してシングルトンが実装されています。 –

2

インターフェイス内の静的クラスを使用すると、一般的なプログラミングの断片を短縮することができます。オブジェクトがインターフェイスのインスタンスであるかどうかを確認し、そうであればこのインターフェイスのメソッドを呼び出します。この例を見てください:

public interface Printable { 
    void print(); 

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

代わりにこれを行う:

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

あなたが書くことができます。

void genericPrintMethod(Object obj) { 
    Printable.Caller.print(obj); 
} 
関連する問題