It can be done using dynamic class loading. It is not loading class of different version but different sub-classes of a super class or interface.
The important steps are:
(1) Use Class.forName(...) to load a class by name. The class must be in the class path.
(2) Use aClass.newInstance() to instantiate the object. This is easy if there is no parameter needed for the constructor.
The following code should provide some idea for you. It does not handle exception which you have to do it.
class Context {
void moveUp();
void moveDown();
...
}
interface AI {
void action(Context con);
}
public class Game {
public Game() {
Context aContext = new Context();
String[] aAIClsNames = this.getAIClassNames("ai.list");
AI[] aAIs = this.loadAI(aAIClsNames);
this.run(aAIs);
}
String[] getAIClassNames(String pAIClassListFile) {
// .. Load the file containning the AI-class file names
}
AI[] loadAI(String[] pAIClsNames) {
AI[] AIs = new AI[pAIClsNames.length];
for(int i = 0; i < pAIClsNames.length; i++) {
String aAIClsName = pAIClsNames[i];
// (1) Get the class by name
Class<? extends AI> aAICls = Class.forName(aAIClsName);
// (2) Notice the cast as all of class in the list must implements AI
AIs[i] = (AI)aAICls.newInstance();
}
return AIs;
}
void run(AI[] pAIs) {
// ...
}
}
Hope this helps.