3

Is there any way to avoid the clutter of adding all the types to the class definition when implementing an interface such as this?

MyInterface.java

import java.util.List;
abstract class BaseA {}
abstract class BaseB {}
abstract class BaseC {}

interface MyInterface<T extends BaseA, U extends BaseB, V extends BaseC> {
    public void foo( List<? extends T> list );
    public void bar( List<? extends U> list );
    public void baz( List<? extends V> list );
} 

MyImplementation.java

/* Some concrete implementations of the abstract classes used in the interface */
class A extends BaseA{}
class B extends BaseB{}
class C extends BaseC{}

class MyImplementation implements MyInterface<A,B,C> {
    public void foo( List<? extends A> list){}
    public void bar( List<? extends B> list){}
    public void baz( List<? extends C> list){}
}

What I don't like about this is that stuff that I find to be method specific, such as the type of parameters, is mixed with the class declaration. As in this case, where I for each generic method in the interface have to add one formal type in "the bracket section".

Is there another way of achieving the above (forcing a caller of the implementation to use a specific subclass of the parameter class in the interface) without all of the "clutter"?

I am not too into generics, and the above code is basically based on an answer to this question.

Community
  • 1
  • 1
oligofren
  • 20,744
  • 16
  • 93
  • 180
  • If anyone wonders what use a construct like this could have, you are advised to check out the last answer here: http://stackoverflow.com/questions/239645/overriding-a-method-with-generic-parameters-in-java The code above works as intended, I just wanted to see if there is some other way of achieving this without all the extra syntax. – oligofren Dec 12 '10 at 01:35

2 Answers2

1

This is how generics works, however if you find yourself adding to a long type-list, you might reconsider your design. I would in this case (without really knowing the purpose of your code), generalize the interface some more:

abstract class PlayBase {}
interface MyInterface<T extends PlayBase> {
    public void playWith(List<T> list);
}   

...and an example implementation:

class A extends PlayBase {}
class MyImplementationA implements MyInterface<A> {
    public void playWith(List<? extends A> list){}
}

This way the design is much more open to change of types in a nice way (no need to change the interface).

crunchdog
  • 13,078
  • 3
  • 23
  • 19
  • Using playWithA/B/C was a poor choice for function name. Sorry about that. They weren't actually meant to have anything in common, just be some random different function names. Edited the answer to reflect this by using the more common "random" names of foo,bar,baz :) – oligofren Dec 12 '10 at 00:56
0

How about this:

interface MyInterface {
    public <T extends BaseA> void playWithA( List<? extends T> list );
    public <U extends BaseB> void playWithB( List<? extends U> list );
    public <V extends BaseC> void playWithC( List<? extends V> list );
}   
starblue
  • 55,348
  • 14
  • 97
  • 151
  • This is how I tried to implement it at first, but this interface cannot achieve the goals stated above. – oligofren Dec 12 '10 at 01:12
  • (Continued) Due to type erasure, you cannot implement MyInterface as: class MyImpl { public void playWithA( List extends T> list ); ... etc } Thus MyImpl.playWitA() would have to accept any List of subclasses of BaseA, not just A (which was a stated goal). – oligofren Dec 12 '10 at 01:20