2

インターフェース定義 (以下を参照) は私を混乱させます:

public abstract interface Cursor {
    // hide details
}

public abstract interface Parcelable {
    // hide details
}

public interface Foo<T extends Bar> extends Cursor, Parcelable {
    // details omitted for brevity
};
  1. Java には多重継承がないため、extends1 つのクラスに複数のクラスを使用することはできないと考えていました。
  2. 一方、クラス/インターフェースは複数のインターフェースを実装できます。では、なぜextends代わりに 使用するのimplementsですか?
4

3 に答える 3

14

Java 7 以下でのクラス/インターフェースの継承と実装の規則は次のとおりです。

  1. クラスは単一のクラスからのみ継承できます (単一継承)
  2. クラスは 1 つ以上のインターフェースを実装する場合があります (複数のインターフェースの実装)。
  3. インターフェイスは 1 つまたは複数のインターフェイスから継承する場合があります (複数インターフェイスの継承)。

extends継承するときは、クラスがクラスから継承するとき、またはインターフェイスが 1 つ以上のインターフェイスから継承するときの両方で、キーワードを使用します。この用語extendsは、次のように理解されるべきです:このクラス/インターフェースは、その親クラス/インターフェースの拡張です。それは、親または親のすべてであり、場合によってはそれ以上です。

クラスがインターフェース (または複数) を実装する場合、キーワードを使用しますimplements。この用語implementsは次のように理解されるべきです:このクラスのインスタンスは、親インターフェースのメソッドの実装を提供することが保証されています

また、抽象クラス自体がインターフェイス メソッドを実装していない場合でも、親インターフェイスを参照するときabstract classにキーワードを使用することに注意してください。implementsこれは、上記の原則に違反しません。宣言されたすべてのメソッドを実装する必要がある具象クラスのインスタンスのみが存在できます。したがって、その抽象クラスのインスタンスは、実際には、インターフェイスのメソッドを実装するサブクラスのインスタンスでなければなりません。たとえば、これは完全に有効です: abstract class AnAbstractClass implements Cursor {}Cursor が多くのメソッドを宣言している場合でも。

あなたの例では、インターフェースは他の2つのインターフェース、つまりとFoo<T extends Bar>を継承しています。これは上記の3番目のポイントの例です。インターフェイスが何も実装していないためではなく、キーワードを使用します。親インターフェイスのメソッドの本体はまだ定義されていません! これら 2 つの親インターフェイスを実装するクラスがある場合は、次のようにします。CursorParcelableextendsimplementsFoo

class AClass implements Cursor, Parcelable {
  @Override public // ... method signature and implementation
                   // for every method in Cursor and Parcelable
}

また、インターフェイスを宣言するときにキーワードを使用する必要がないことに注意してください。abstract型とその宣言されたすべてのメソッドは暗黙のうちに抽象的です。インターフェイスの目的は正確に「オブジェクトのパブリック インターフェイス」を宣言することであるため、メソッドは暗黙的にパブリックでもあります (他のアクセス修飾子で宣言することはできません)。そのインターフェイスを実装するオブジェクト。


最後に、上記の概念のいくつかは、Java 8 でわずかに変更される可能性があります。そのリリースでは、インターフェイスを実装するクラスがそれらを実装しない場合に備えて、インターフェイスでメソッドの「デフォルト実装」を提供できます。 . 物事は「クラスの多重継承」に似ています。クラスは、実装されたメソッドを複数のソースから継承できますが、これは Java 7 以下では不可能です。例 (構文はまだ修正されていません):

interface NaturalNumber {
  void increment();
  default void add(int n) {
    for (int i = 0; i < n; i++) {
      increment();
    }
  }
}

class NaturalNumberImplementation implements NaturalNumber {
  private int n = 0;
  @Override public void increment() { n++; }
}

これは、可能/必要なときに「より良い」バージョンを実装できる一方で、不要なときにいくつかのメソッドの実装を無視できるようにするために存在します。例えば:

class HighPerformanceNaturalNumberImplementation implements NaturalNumber {
  private int n = 0;
  @Override public void increment() { n++; }
  @Override public void add(int n) { this.n += n; }
}
于 2013-06-21T05:07:06.317 に答える
2

答え 1.

Java クラスは、1 つの親クラスのみを拡張できます。多重継承は許可されていません。ただし、インターフェイスはクラスではなく、インターフェイスは複数の親インターフェイスを拡張できます。

答え 2.

親子関係がある場合は、常にクラス/インターフェースを拡張する必要があります。クラスまたはインターフェースを拡張する理由は他にあってはなりません。

于 2013-06-21T05:06:49.183 に答える
0

インターフェース:

  • インターフェイスはインターフェイスを拡張します。

  • インターフェイスは、複数のインターフェイスを拡張できます。

クラス:

  • クラスはクラスを拡張します。

  • クラスは単一のクラスのみを拡張できます。

  • インターフェイスを実装できるのはクラスだけです。

  • クラスは複数のインターフェースを実装できます。

于 2013-06-21T05:11:25.350 に答える