SaCh
SaCh

Reputation: 475

How to implement a generic interface that extends another generic interface in Java?

I am new to Java and working on implementing generic interfaces and that's where I'd love some help.

I want to implement a generic interface in Java that extends another interface. This is how the current interface structure looks like -

interface ItemsProviderInterface<ExtReq, ExtRes> 
extends GenericItemProviderInterface<ItemRequest, ExtReq, ExtRes, ItemResponse> {}


interface GenericItemProviderInterface<Req, ExtReq, ExtRes, Res>{
    ExtReq convertInput(Req req)
    Res convertResponse(ExtRes res)
    ExtRes request(ExtReq req)
}

I want to implement the ItemsProviderInterface interface and provide a definition for convertInput(), convertResponse(), request() methods.

Maybe something like -

class itemsProvider<> implements ItemsProviderInterface<>

I am not sure which generic type to define the class with.. the ones corresponding to ItemsProviderInterface or GenericItemProviderInterface. I read up a lot of blog posts and searched StackOverflow for a similar question but couldn't find one. Any help is HUGELY appreciated.

Upvotes: 2

Views: 1509

Answers (3)

Soumik Nandi
Soumik Nandi

Reputation: 21

In your use case, the class itemsProvider is implementing ItemsProviderInterface, so the class should only be dealing with the generic type of what the implementing interface holds.

In this class you want to implement the methods, you can go about in two ways. Since you said you want to provide an implementation of the methods, I am going by the thought that you would be needing specific return types on the methods. In that case, you could go about and do this

public class itemsProvider<String, Integer> implements ItemsProviderInterface<String, Integer> {

Here, I took for example that ExtReq and ExtRes are String and Integer type respectively during invocation

Upvotes: 1

Joachim Sauer
Joachim Sauer

Reputation: 308041

I think it's worth inspecting which identifier means what in this case. Let's look at the base interface first GenericItemProviderInterface<Req, ExtReq, ExtRes, Res>.

Here all 4 type parameters Req, ExtReq, ExtRes and Res are type parameters. That's important to remember, because they are not themselves types!

Then let's look at the definition of the derived interface: ItemsProviderInterface<ExtReq, ExtRes> only has 2 type parameters: ExtReq and ExtRes. Note that despite the identical names, those don't inherently have anything to do with the ones on the base interface. That connection comes now:

interface ItemsProviderInterface<ExtReq, ExtRes> 
extends GenericItemProviderInterface<ItemRequest, ExtReq, ExtRes, ItemResponse> 

This means that an ItemsProviderInterface is-a GenericProviderInterface with the 4 type parameters set like this:

  • Req of GenericItemProviderInterface is set to the actual type (class or interface) ItemRequest.
  • ExtReq of GenericItemProviderInterface is set to the type parameter ExtReq of ItemsProviderItnerface
  • ExtRes of GenericItemProviderInterface is set ot the type parameter ExtRes of ItemsProviderInterface
  • Res of GenericItemProviderInterface is set to the actual type ItemResponse.

So 2 of the 4 type parameters of the base-class are "fixed" to a specific type and the remaining two are left variable.

If you now implement ItemProviderInterface you could either also have 2 type parameters and route them to ExtReq/ExtRes or fix them to specific classes (or do 1-and-1, but that's probably not useful for this specific example.

So either

class MyItemProvider<ExtReq, ExtRes>
    implements ItemProviderInterface<ExtReq, ExtRes> {...}

or

class MySpecificItemProvider
    implements ItemProviderInterface<MySpecificExtReq, MySpecificExtRes> {...}

Upvotes: 1

John Bollinger
John Bollinger

Reputation: 180286

I am not sure which generic type to define the class with.. the ones corresponding to ItemsProviderInterface or GenericItemProviderInterface.

Class ItemsProvider directly implements ItemsProviderInterface, so it must specify values for the parameters defined by that interface. It is the responsibility of that interface (which it faithfully discharges) to defines the parameters applicable to its extension of GenericItemProviderInterface.

This is perhaps a bit obscure semantically, but it is unmistakable syntactically, especially in a case like this where the sub- and super-interfaces have different numbers of parameters. The parameter values you put between the angle brackets in this implements clause ...

implements ItemsProviderInterface<>

... are parameters for the interface named in the clause. And if you try to provide the wrong number of them then the compiler will reject your code.

Upvotes: 0

Related Questions