I’ve got a framework here that uses an object to maintain state between other objects as they interact with it. I was hoping that the objects that interact with the state (“Actions”) could generically accept a type of interface, which the State object would implement, but I’m having trouble making this work.
I want to define the framework object itself in terms of a specific state implementation (or interface), and be able to add Actions to it, as long as they accept the defined state, either directly or through an interface that the state implements.
As I understand it, the <? super S> definition means “some type that is a parent of S”, but I am not sure that an Interface that is implemented by S fits this description, as it’s not exactly a parent class.
Here’s an example (not exactly compiling code):
Class Framework<State> {
addAction(Action<? super State> a) {} // adds to a list of actions to be run
run(State s) {
for(Action<? super State> a : actions) {
a.perform(s);
}
}
}
Interface IState1 {}
Interface IState2 {}
Interface Action<State> {
public void perform(State s);
}
Class Action1 implements Action<IState1> {}
Class Action2 implements Action<IState2> {}
Class CombinedState implements IState1, IState2 {}
public static void run() {
Framework<CombinedState> f = new Framework<CombinedState>();
// add is expecting Action<? super CombinedState> but getting Action<IState1>
f.add(new Action1()); // This doesn't seem to work
f.add(new Action2());
f.run(new CombinedState());
}
For the purposes of generics, do Interfaces count as parent classes? Is there any way to implement this that doesn’t require reflection?
This runs in CodeRunner on OSX.