2017-01-16 50 views
4

是否有動態實例化抽象類的所有子代的方法?實例化動態給定抽象父類的所有子代

什麼我現在是與此類似:

public class CommandHandler { 

    private Command info  = new Info(); 
    private Command prefix  = new Prefix(); 
    private Command roll  = new Roll(); 
    private Command coin  = new Coin(); 
    private Command invite  = new Invite(); 
    private Command quit  = new Quit(); 
    private Command restart  = new Restart(); 

} 

隨着抽象父類是這樣的:

public abstract class Command { 

    protected String name; 
    protected String arguments; 

    protected abstract void execute(); 

} 

但如果我要實例擴展命令沒有所有類什麼每次單獨輸入它們並在每次添加命令時添加到列表中?

如果我可以動態實例化它們,我也可以動態地操縱它們嗎?即一旦將其實例化,就將每個類添加到列表中。

還是有更好的設計使用,以更簡單的方式完成我想要的嗎?

編輯:@Ash的解決方案在IDE中完美工作,但不能在使用jar時使用。所有你需要做的,使其在這兩個工作是改變

classPathList.addAll(ClasspathHelper.forClassLoader()); 

classPathList.addAll(ClasspathHelper.forJavaClassPath()); 

希望它可以幫助別人!

+2

如果我自己創建'Command'子類,該怎麼辦?你的'CommandHandler'如何知道這個類? (答案是:不,編寫代碼時不可能知道所有可能的子類。)如果在編譯期間確實已知各個子類,那麼是否考慮使用'enum'? – aioobe

+0

這可能有助於http://stackoverflow.com/q/492184/4338417 –

+0

@aioobe Java有這種問題的反思 - 它可以在運行時確定可用的其他類。 – Elemental

回答

4

如果你使用Maven的(如果沒有,你應該:P),添加以下的依賴:

<dependency> 
    <groupId>org.reflections</groupId> 
    <artifactId>reflections</artifactId> 
    <version>0.9.10</version> 
</dependency> 

然後你可以列出你想用下面的代碼的類(假設你有一個構造函數沒有參數):

public class Loader { 

    public static void main(String[] args) { 
     try { 
      Set<URL> classPathList = new HashSet<URL>(); 
      classPathList.addAll(ClasspathHelper.forClassLoader()); 
      Set<Class<? extends Command>> result = new Reflections(new ConfigurationBuilder().setScanners(new SubTypesScanner()).setUrls(classPathList)).getSubTypesOf(Command.class); 

      List<Command> commands = new ArrayList<Command>(); 

      for (Class<? extends Command> c : result) { 
       System.out.println(c.getSimpleName()); 
       commands.add(c.newInstance()); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

完美的作品!謝謝。我不知道存在這樣的事情。 另外,對於那些不想使用Maven的人來說,你需要下面的jar來運行它:reflection-0.9.10.jar,javassist-3.19.0-GA.jar,guava-15.0.jar和註釋-2.0.1.jar。 – Svetroid