简体   繁体   中英

Generic method with return type from interface

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?

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;
    }
}

<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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM