Reputation: 63
I have an interface and a value class that look like this:
public interface ITest<T1> {
<T2> T1 test(OtherClass<T2> client);
}
Basically, it says that subtypes have to implement the method test
that returns a T1, whatever that is in the implementing subtype.
OtherClass:
public class OtherClass<T> {
public T contents;
}
However, when I want to write a subtype that implements test
and just returns the client instance it gets, I get compile errors. What I want is unify T1
and T2
:
public class Test<T1> implements ITest<T1> {
@Override
public <T1> T1 test(OtherClass<T1> client) { // compile error
return client.contents;
}
}
Is there any way to get this class to work?
Upvotes: 3
Views: 119
Reputation: 20760
In your interface declaration, you say that you want you test
function to accept any type (you did not specify any bounds for T2
).
In your implementation you only accept T1
, which is not any type.
Upvotes: 1
Reputation: 916
<T1>
basically tells any class "you pick what type T1 is going to be!". This means that in this case <T1>
and OtherClass<T1>
refer to the same type, while the return type T1
refers to the class's T1
. If you rename one you will see the error:
@Override
public <OtherClassType> T1 test(OtherClass<OtherClassType> client) {
return client.contents; //you can't do that without casting OtherClassType to T1
}
If you cannot edit the ITest
interface, the only way for this to compile would be by casting, but you need to make sure that you can actually cast before doing so (because OtherClass can return any type, not necessarily a subclass of T1.
EDIT: The exact reason the compiler does not allow this is because you are effectively restricting the test
method to only take in certain types, while the method it is overriding allows for any type.
Upvotes: 1
Reputation: 2199
I don't think think this is allowed since you are now restricting the T2
to be a T1
in the class Test<T1>
.
You can solve this problem as follows:
public interface ITest<T1, T2> {
T1 test(OtherClass<T2> client);
}
public class OtherClass<T> {
public T contents;
}
public class Test<T1> implements ITest<T1, T1> {
@Override
public T1 test(OtherClass<T1> client) {
return client.contents;
}
}
Upvotes: 1