Sarevok
Sarevok

Reputation: 437

Inheritance Generics

Suppose I an abstract class defined like this:

public class Response<T> {
    private List<Response<T>> subResponses;
}

and two subclasses defined like this:

public class SectionResponse extends Response<SectionResponse> {
}

public class FormResponse extends Response<FormResponse> {
}

Basically all subclasses of Response need to have a list of the same class. Now somewhere else in the code I want to have a list of Response objects that can contain either subclass.

What would be the best way to define this list without using raw types? I've tried List<? extends Response<?>> but I can't call the add method on a List defined like this because the parameter is a parameterized type.

Upvotes: 3

Views: 109

Answers (3)

Dolda2000
Dolda2000

Reputation: 25855

I'll admit I'm not sure exactly what you want to do, but this much works and at least touches on the problem you describe:

public class Response<T extends Response> {
    private List<T> sl = new LinkedList<T>();

    protected void add(T resp) {
        sl.add(this);
    }
}

public class FormResponse extends Response<FormResponse> {
    public FormResponse() {
        add(this);
    }
}

Upvotes: 0

newacct
newacct

Reputation: 122519

Your Response class should be defined like this:

public class Response<T> {
    private List<T> subResponses;
}

So that SectionResponse and FormResponse, as declared, will have a list of themselves.

Now, literally answering your question, for a list that can contain either, you can just have a List<Response<?>>.

However, you likely want more than that -- you probably want to take the elements out of the list and do something to them. If you can be more specific about what you need to be able to do, we can help you further.

Upvotes: 1

Andrew White
Andrew White

Reputation: 53516

Use the Put-Get-Rule. Namely, return List<? extends Response<?>> but accept List<? super Response<?>> as parameters. Internally you would store the the list as List<Response>

As a note, I would be wary of returning List<? extends Response<?>> on an interface since it can be invasive to the consumer. In most cases the it is better for an interface to nail down the generic type so that you are returning something like List<Response<MyType>> if at all possible.

Upvotes: 3

Related Questions