2015-09-07 12 views
12

私のプロジェクトで使用しているライブラリがあります。このライブラリは約15のメソッドを持つインタフェースを持っています。リスナーを表すインターフェイスのメソッドにデフォルトの実装を追加することはできますか?

このインターフェースの目的は、ライブラリーで生成されたいくつかのイベントをサブスクライブできるようにすることです。アプリケーションのリスナー・クラスは、このインタフェースを実装し、イベントを受け取るためにリスナーとして自身をリスナーとして登録できます。

このインターフェイスのすべてのメソッドは、実際にはイベントです。インターフェイスの多くのイベントから1つまたは2つのイベントのみを受信する必要があるリスナーが存在する可能性があります。リスナーは少数のイベントにのみ関心があるとしても、インターフェースを拡張するときにはすべてのメソッドを実装する必要があります。

私はこのライブラリの開発者に、インターフェイスのメソッドに空のデフォルトの実装を追加するよう依頼しました。

しかし、ライブラリの開発者は、デフォルトの実装を追加することを拒否し、Javaのベストプラクティスに違反し、インターフェイスメソッドのデフォルトの実装をインターフェイスの目的に反して使用すると述べています。

しかし、私が理解できるように、このインターフェイスのメソッドは、このインターフェイスの実装者ができるべきアクションを指定していません。このインタフェースのメソッドは、実装者が興味を持っている可能性のあるイベントを定義します。したがって、デフォルトの実装を追加しないという明確な理由はわかりません。

したがって、このインターフェイスにデフォルトの実装を追加して、Javaのベストプラクティスを破っていますか?

+0

インターフェイスを実装したいですか?それもコンパイルされません。私はあなたの質問を理解していない限り。 – Manu

+2

java 8では、インターフェイスメソッドのデフォルト実装を指定することができます。これにより、インターフェイスの実装者がメソッドを実装するためのオプションとなります。 –

+0

それを知らなかった。下位互換性のためにこの機能が提供されているようですが、インターフェイスの代わりに抽象クラスを使用するだけです。 (あなたは図書館員がいなくても、それを自分で作ってください) – Manu

答えて

6

しかし、ライブラリの開発者は はそれがJavaのベストプラクティスに違反することを知らせると、インタフェースメソッドで 実装は インタフェースの目的に反するデフォルトを使用して、デフォルトの実装を追加することを拒否。

この引数は、デフォルトのインターフェイスメソッドが導入されるまで有効でした。 あなたの同僚はJava 8のJVのインターフェースとJDKに今やインターフェースの目的に反するクラスが含まれていると主張する必要があります。それでも、これは実行可能な極端な観点ですが、無駄です。

ライブラリインターフェイスから独自のインターフェイスを派生させ、すべての継承されたメソッドに対して既定の空の実装を提供することで、説明を避けることができます。リスナーは、いくつかのイベントでだけに関心ある

にもかかわらず:

public interface MyInterface extends LibraryInterface { 
    @Override default public void event1() { 
    } 

    ... 
} 

それとも両方が私には怪しげなようで、以下の設計を見直すことができ、インタフェースのデフォルトの方法についてのあなたの議論につながりました、リスナ は、インターフェイスを拡張するときにすべてのメソッドを実装する必要があります。

解決策は、小さなインターフェースで大きなインターフェースを単純に分割することができます。

1

デフォルトメソッドでは、インターフェイスに新しい機能を追加することができるので、インターフェイスを実装するクラスを破ることなくインターフェイスを追加することができます。インターフェイスと抽象クラスの美しさを組み合わせているため、この「方法論」はJavaのCollections Framework全体で使用されているため、独自の骨格実装クラスを提供することを強くお勧めします。これは私の謙虚な意見です。

4

ライブラリの開発者はこれについて間違っています(私はIMHOを省略することもありえます)。

Javaのヘルパー(抽象クラ​​スとコンクリート)クラスの多くが過去に導入された理由の1つは、デフォルトのインターフェイスメソッド(たとえば、Swingのアダプタクラスあなたは約尋ねている)。

誤っていない場合、状況によっては複数の継承が望ましく、私たちが知っているように、Javaのヘルパークラスを拡張することで、他のものから継承する能力が失われてしまいます。

実は、これは公式Java tutorialに記載されている、セクション「インターフェースに比べて抽象クラス」:これらのステートメントのいずれかがあなたの 状況に該当する場合

、インターフェイスを使用して考えてみましょう:

  • あなたは無関係のクラスがあなたのインタフェースを実装すると期待しています。たとえば、ComparableとCloneableのインタフェースは、無関係の多くのクラスによって に実装されています。
  • 特定のデータ型の動作を指定したいが、その動作を実装する人は関係しない。
  • タイプの多重継承を利用したいと考えています。

2番目と3番目のポイントは、使用するケースに最適です。

関連する問題