Benoît Vernier
Benoît Vernier

Reputation: 125

Type Variable with class and interface: inheritence problems

My project uses an external library which provides classes A and B (where B extends A). I want to add a few methods to A, but I want them to be in B too, so I have created an interface Custom and created the classes:

I now want to uses those 2 new classes interchangeably in class C, as both attributes and method arguments. I have found this question: Declare an attribute that both extends a class and implements an interface, so I have tried the following code:

public class C<T extends A & Custom>{
   private T attr1;
   private T attr2;
   public void createAttrs() {
       attr1 = new CustomA();
       attr2 = new CustomB();
   }
   public void setAttr1(T attr1) {
       this.attr1 = attr1;
   }
   public void setAttr2(T attr2) {
       this.attr2 = attr2;
   }
}

However this code did not compile because of "Incompatible types" in the createAttrs() method. But CustomA and CustomB both extend A (directly or indirectly) and implement Custom, so it matches the pattern of the Type Variable T.

How can I make this code work?

Edit: What I'm really looking for is a way to use CustomA and CustomB interchangeably, in the same fashion I could originally store both an A and a B object in a variable typed A.

Upvotes: 1

Views: 53

Answers (2)

Andrew
Andrew

Reputation: 49656

Neither a new CustomA() nor a new CustomB() can't be used within the createAttrs since you're describing a template and at this time you don't know what the type T is gonna be.

It can be a CustomA or a CustomB, but it also can be any class that follows the rule T extends A & Custom.

It makes no sense to make a class generic and use a concrete implementation inside it. So I would suggest getting these attributes from method parameters:

class C<T extends A & Custom> {
    private T attr1;
    private T attr2;

    public void createAttrs(T attr1, T attr2) {
        this.attr1 = attr1;
        this.attr2 = attr2;
    }

    public static void main(String[] args) {
        new C<>().createAttrs(new CustomA(), new CustomB());
    }
}

Upvotes: 2

lexicore
lexicore

Reputation: 43709

What you say in C is that attr1 and attr2 must be of the same type T which extends A, implements Custom and both CustomA and CustomB are assignment-compatible to it.

No such type exists.

Upvotes: 0

Related Questions