3

I have two interfaces. An interface A, and interface B, which extends interface A. Now, I have class which likes to keep reference of object that either implements A or B. And I would like to provide setter for it. I tried below, but getting type mis match exception.

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

So basically, I would like setObject method to accept an object that either implements interface A or B.

4

4 回答 4

4

Simple answer:

Type it as A: setObject(A a).

A class that implements B also implements A. Full code:

public class UsesA {
  private A a;

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

Now, if you really want to work with B, you'd type it as B, which would also allow you to treat it as an A, since B inherits from it:

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

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

But now you can't pass an A (static) reference to setObject. If you really want to do this, then you'd need to first downcast it as a B, which could fail at runtime. Generics will not improve on this.

于 2012-09-05T02:48:30.887 回答
2

If you have an object implementing B, it will also be an instance of A. Because of this, you can make setObject accept any A, which will allow instances of A or B to be passed to it.

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

Your code doesn't actually match up with your question. You've stated that

I have class which likes to keep reference of object that either implements A or B

but the field (called object) is actually a Class, not an Object (instance of a Class).

Your code works if you were truly trying to have your setter accept any interface that extends A. But as you probably realize now from the other answers, you actually want an instance of 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

As suggested earlier if you will use (A a) it will work since B is a type of A. Hence child class can always be represents it's parent.

于 2012-09-05T02:53:37.647 回答