web-dev-qa-db-ja.com

インターフェースを拡張するのは誰ですか?なぜ?

AFAIK、私のクラスextends親クラスとimplementsインターフェース。しかし、implements SomeInterfaceを使用できない状況に遭遇します。ジェネリック型の宣言です。例えば:

public interface CallsForGrow {...}

public class GrowingArrayList <T implements CallsForGrow>  // BAD, won't work!
                              extends ArrayList<T> 

ここでは、implementsの使用は構文的に禁止されています。最初に、<>内でのインターフェースの使用はまったく禁止されていると思いましたが、禁止されていません。可能です。extendsの代わりにimplementsを使用するだけです。その結果、私はインターフェースを「拡張」しています。この別の例は機能します:

public interface CallsForGrow {...}

public class GrowingArrayList <T extends CallsForGrow>  // this works!
                              extends ArrayList<T> 

私にとっては、それは統語論的矛盾のようです。しかし、Java 6の巧妙さを理解できないかもしれません。インターフェイスを拡張する必要のある他の場所はありますか?拡張するつもりのあるインターフェイスに、いくつかの特別な機能がありますか?

20
Gangnus

ジェネリック型変数の場合、コンパイラーはTがクラス、インターフェース、列挙型、または注釈であるかどうかを実際には気にしません。重要なのは、サブタイプとスーパータイプのセットが指定されたタイプであることだけです。

そして、他の場所(実際にインターフェースを実装する場所)でクラスとインターフェースの区別が関連しているという理由だけで構文を複雑にする理由はありません(たとえば、インターフェースをimplementする場合、すべてを実装する必要がありますextend(非抽象)クラスの場合は、それが定義するメソッドですが、必要はありません)。

ここでimplementsを記述する必要があると仮定すると、enum値(<E extends Enum<E>>を単に記述するのではなく)と注釈( <A extends Annotation>)を使用して簡単に宣言できます。

implementsを書き込む必要がある必要がある場所は、実際にインターフェイスを実装する場所のみです。 thatポイント(およびそのポイントのみ)では、インターフェイスで定義されたメソッドを実装する必要があるため、違いは重要です。他のすべての人にとって、与えられたABの基本クラスまたは実装されたインターフェースであるかどうかは関係ありません。それはスーパータイプであり、それだけが重要です。

また、インターフェースでextendsを使用する場所が他にも1つあることに注意してください。

interface A {
}

interface B extends A {
}

この時点では、implementsは間違っています。Bは実装されていませんA

25
Joachim Sauer

Java 5、特にジェネリックが最初に、関心を登録した開発者が利用できるようになったとき、構文はまったく異なりました。Set<? extends Foo>Set<? super Bar>の代わりに、 Set<+Foo>およびSet<-Foo>。ただし、フィードバックは、+より具体的であるかどうかが明確ではないというものでしたまたはより広い(より多くのクラス)。Sunは構文を変更することによってそのフィードバックに応答しましたが、新しいキーワードを導入しないという制約の中で、後方互換性のための問題。

結果はどちらもかなり自然です。お気づきのように、extendsは、「拡張」インターフェースのクラスについて話すためにオーバーロードされています。これは、他のコンテキストで使用される言語ではありません。およびsuperは、「スーパークラスである」を意味するようにオーバーロードされています。これは、以前にキーワードで表現された関係の逆方向、つまりスーパークラスを指します。

ただし、インターフェイスが何であるかの基本はこの変更の影響を受けず、新しい方法で拡張された特別なインターフェイスは導入されません。

5
Peter Taylor

このような構文の許可と禁止の両方に欠点があり、allowingの欠点ははるかに大きくなります。

考えてみてください。

インターフェイスと実装の分離 は、基本的なプログラミングイディオムの1つです。そのため、綴りを許可する構文「インターフェイスは何かを実装する」は、プラス記号を使用してを表すのと同じくらい悪いでしょうオペランドの乗算

2
gnat