I have been using generics for sometime, but only in a simple straightforward fashion.
Now I would like to do this, I have been reading and trying many things, such as using interfaces and wildcards but with no success. I would like to learn if there is a valid way to achieve this with Java generics, or if I have misunderstood they way in which generics should be used.
Lets say I want to make a generic collection class, an ArrayList, and I want to create such arraylists for various differing types BUT IMPORTANTLY differing types which are ASSURED to implement a certain method. I would then like to be able to call that method from within my generic arraylist.
The following code is very simplistic, and clearly will not work, I know that. I have tried plenty more sophisticated ideas than this, however I include the following code just to sum up what I am trying to do, and to provide an example for answers.
See the line of code in DemonstrateProblem()...I would like to be able to call that on the understanding that I will only ever use types in TestContainer which implement the method StartGame()
public class TestContainer<T> extends ArrayList<T> {
public void DemonstrateProblem() {
// assumes we have populated the collection with 5+ objects...
// the line of code below is ultimately what I would like to acheive
this.get(4).StartGame(); // <-- my goal!
}
}
public abstract class Game () {
public abstract void StartGame() {}
public abstract void EndGame() {}
}
public class HockeyGame extends Game {
// ... overrides here
}
public class BaseballGame extends Game {
// ... overrides here
}
public class BasketballGame extends Game {
// ... overrides here
}
What you want to do is restrict the types that your genericized class will accept to only those that implement the behavior you are expecting. You can do this by:
ReplyDeleteImplementing an interface with your expected behavior
Restricting the bounds of your generic type to that interface.
Illustrated in an enhanced version of your pseudocode:
public interface Game {
public void StartGame();
}
public class TestContainer<T extends Game> extends ArrayList<T> {
public void DemonstrateProblem() {
// assumes we have populated the collection with 5+ objects...
// the line of code below is ultimately what I would like to acheive
this.get(4).StartGame(); // <-- my goal!
}
}
You do not need to keep your container generic on T: you can instantiate an existing generic container on Game, like this:
ReplyDeletepublic class TestContainer extends ArrayList<Game> {
public void DemonstrateProblem() {
this.get(4).StartGame(); // <-- should work
}
}