Reputation: 35
I'm having the following issue to do with generics. I have the following:
InterfaceA as:
public interface InterfaceA {
public <T extends DTOInterface> Object methodName (T dto) {}
}
DTOInterface is just an empty interface.
Then my implementation would be:
public class ImplementationA implements InterfaceA {
public Object methodName(DTOImplementation dto) {
return null;
}
}
DTOImplementation is just a class implementing DTOInterface.
This is failing because the method in ImplementationA is not recognized as a valid implementation of the method in InterfaceA.
However, if I define the parameter at interface level i.e.
public interface InterfaceA **<T extends DTOInterface>** {
public Object methodName (T dto) {}
}
And then define the implementation as:
public class ImplementationA implements **InterfaceA<DTOImplementation>** {
public Object methodName(DTOImplementation dto) {
return null;
}
}
It does work. The method is recognized as a valid implementation.
Does anyone know why this is happening?
Upvotes: 2
Views: 2135
Reputation: 61168
Your interface
definition has a generic method
public <T extends DTOInterface> Object methodName (T dto) {}
This method states that it takes any type T
that extends DTOInterface
. If you want to implement the interface
you need to provide the exact same method in the implementation.
You cannot restrict the method in an implementation because what would happen if you did this:
AnotherDTOImplementation adi = new AnotherDTOImplementation();
InterfaceA obj = new ImplementationA();
ojb.methodName(adi);
This obviously breaks type safety.
In your second example you have a generic interface. This means that when you implement the interface
you either have to declare the generic type of specify the implementation as a generic class
.
This means that ImplementationA
is of type InterfaceA<DTOImplementation>
which in turn means that you have type safety.
Upvotes: 2
Reputation: 14035
The first declaration says that in order to implement InterfaceA
, the subclass needs to provide a method methodName
that works for any type T
that extends DTOInterface
of the method caller's choice. In other words, T
is a parameter that the caller of methodName
gets to choose; the class that implements InterfaceA
doesn't get to choose it. So when you provide an implementation that attempts to choose a particular value of T
for methodName
and only implement that, the compiler rejects your program.
The second declaration, on the other hand, is an interface that allows the implementor to provide a particular value for T
and only implement its methods for that particular choice. ImplementationA
choose to implement InterfaceA
only for one particular subtype of DTOInterface
(namely, DTOImplementation
) and provides a method only for that choice of T
. That's perfectly fine.
Upvotes: 4