3

私は2つのインターフェースを持っています。インターフェイスAと、インターフェイスAを拡張するインターフェイスB。今、私はAまたはBを実装するオブジェクトの参照を保持したいクラスを持っています。そして、そのセッターを提供したいと思います。以下で試してみましたが、型の不一致例外が発生します。

public interface A {
}

public interface B extends A {
}

public class AB {
private Class<? extends A> object;

public void setObject(Class<? extends A> o){
   this.object = o;
}
}

したがって、基本的には、setObject メソッドがインターフェイス A または B を実装するオブジェクトを受け入れるようにしたいと考えています。

4

4 に答える 4

4

簡単な答え:

次のように入力しますAsetObject(A a)

を実装するクラスは、Bも実装しAます。完全なコード:

public class UsesA {
  private A a;

  public void setObject(A a){
    this.a = a;
  }
}

さて、本当に作業したい場合はB、と入力します。これにより、継承するBため、として扱うこともできます。AB

public class UsesB {
  private B b; // can call A's methods on this field

  public void setObject(B b) {
    this.b = b;
  }
}

Aただし、 (静的)参照をに渡すことはできませんsetObject。本当にこれを実行したい場合は、最初にそれをとしてダウンキャストする必要がありBます。これは実行時に失敗する可能性があります。ジェネリックはこれを改善しません。

于 2012-09-05T02:48:30.887 に答える
2

を実装するオブジェクトがある場合B、それはのインスタンスにもなりますA。このため、setObject任意のを受け入れることができます。これにより、またはAのインスタンスを受け入れることができます。AB

public void setObject(A a){
    this.object = a;
}
于 2012-09-05T02:49:17.337 に答える
2

あなたのコードは実際にはあなたの質問と一致しません。あなたはそれを述べました

A または B を実装するオブジェクトの参照を保持するのが好きなクラスがあります

しかし、フィールド ( と呼ばれるobject) は実際にはクラスであり、オブジェクト (クラスのインスタンス) ではありません。

セッターに A を拡張するインターフェイスを受け入れさせようとしている場合、コードは機能します。しかし、おそらく他の回答からわかるように、実際には A のインスタンスが必要です:)

public class AB {
    private Class<? extends A> type; // renamed from object for clarity

    public void setObject(Class<? extends A> type) {
        this.type = type;
    }

    @Test
    public void testSetter() {
        setObject(A.class); // no errors
        setObject(B.class); // no errors
    }
}
于 2012-09-05T03:07:39.720 に答える
0

前に提案したように、(A a)を使用する場合、BはAのタイプであるため、機能します。したがって、子クラスは常にその親を表すことができます。

于 2012-09-05T02:53:37.647 に答える