0

Consider having a generic type:

public interface <T> Assigner {
    <S> S assign(T type);
}

Now, let's say I want to have different types of assigners that could assign an object of any type T to a group of any type S. Example:

interface PlayerAssigner extends Assigner<Player> {
    <S> S assign(Player player);
}

interface ManagerAssigner extends Assigner<Manager> {
    <S> S assign(Manager manager);
}

...

I would also like to introduce a group-type-based assigner, but this is where I got stuck. I tried:

interface CityBasedAssigner<T> extends Assigner<T> {
    City assign(T type);
}

, but this won't work, it says that both methods have the same erasure. I don't know whether it should be an abstract class or something different, or whether the whole concept could be simplified. What I want is to be able to instantiate different types of assigners from the combination of two type parameters, e.g. CityBasedPlayerAssigner, CountryBasedPlayerAssigner, CountryBasedManagerAssigner, etc., and this would have been the next step: combining the two extended interfaces and create many implementations based on these two.

What am I missing here?

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
Lois2B
  • 111
  • 1
  • 16
  • 1
    Does this answer your question? [How to make a Java class that implements one interface with two generic types?](https://stackoverflow.com/questions/1297972/how-to-make-a-java-class-that-implements-one-interface-with-two-generic-types) – Joe Aug 11 '22 at 10:45
  • @Joe Not really, that question seems to be more about a biconsumer where the input arguments are of the same type. However, I'm trying to implement a function where both the argument and the result could be of any type, separately. – Lois2B Aug 11 '22 at 11:02
  • 2
    I don't really see how what you're trying to do is different from a [`Function`](https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/util/function/Function.html), with your `assign` method being the equivalent of the `Function#apply(T)` method. – Slaw Aug 11 '22 at 12:21
  • 2
    In other words, you should have `interface Assigner { S assign(T type); }` and then your subtypes could be `interface CityAssigner extends Assigner {}`, for example. – Slaw Aug 11 '22 at 13:43
  • Seconding what @Slaw recommended, since your current approach will face a class explosion. If you truly want a GOF design pattern, I would say that you're looking for the [Decorator pattern](https://en.wikipedia.org/wiki/Decorator_pattern) – Rogue Aug 11 '22 at 15:11
  • @Slaw Indeed, I realized that it's Java's function what I was looking for, that's why I mentioned it in my previous comment. As you and Cheng's answer both suggested, I agree that the simplest way is probably just passing the types in the sub interfaces. I got confused because I'm not sure when to put a type parameter to class level instead of the method scope. – Lois2B Aug 12 '22 at 07:19

1 Answers1

2

Your sub interface inherits the method assign from Assigner. All you need to do in the sub interface is pass the types to the super interface.

interface Assigner<S, T> { S assign(T type);}
interface PlayerAssigner<S> extends Assigner<S,Player> {}
interface ManagerAssigner<S> extends Assigner<S,Manager> {}
interface CityBasedAssigner<T> extends Assigner<City,T> {}
Cheng Thao
  • 1,467
  • 1
  • 3
  • 9