Arjun Patel
Arjun Patel

Reputation: 353

Java interface - Generics

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.

Upvotes: 3

Views: 163

Answers (4)

James Bassett
James Bassett

Reputation: 9868

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

Upvotes: 2

Jord&#227;o
Jord&#227;o

Reputation: 56467

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.

Upvotes: 4

Manisha Mahawar
Manisha Mahawar

Reputation: 635

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.

Upvotes: 0

FThompson
FThompson

Reputation: 28687

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

Upvotes: 2

Related Questions