2014-02-07 94 views
2

不知道我有一個抽象類的類的實例:創建在編譯時

public abstract class Room { 

} 

和繼承的類未在編譯時已知的,如:

public class MagicRoom extends Room { 

    public MagicRoom(){ 
     System.out.println("Creating a MagicRoom."); 
    } 

    public String magic = ""; 
} 

或:

public class Dungeon extends Room { 

    public Dungeon(){ 
     System.out.println("Creating a Dungeon"); 
    } 

    public String keeper = ""; 
} 

我有一個類,我會從創建這些類的實例:

import java.lang.reflect.Constructor; 
import java.lang.reflect.InvocationTargetException; 

public class MazeGame { 

    public static Room makeRoom(Class roomClass) 
     throws IllegalArgumentException, InstantiationException, 
      IllegalAccessException, InvocationTargetException, 
      SecurityException, NoSuchMethodException{ 

     Constructor c = roomClass.getConstructor(); 
     return c.newInstance(); 

    } 

} 

makeRoom是我嘗試創建一個類,我不知道在編譯時間,但我不知道該怎麼把它作爲它的返回類型而不是Room。由於makeRoom返回房間我得到一個異常,如果我嘗試使用屬於繼承的類中的字段:

import java.lang.reflect.InvocationTargetException; 

public class FactoryTest { 

    public static void main(String[] args) 
     throws IllegalArgumentException, SecurityException, 
      InstantiationException, IllegalAccessException, 
      InvocationTargetException, NoSuchMethodException{ 

     MazeGame game = new MazeGame(); 

     Room magicRoom = MazeGame.makeRoom(MagicRoom.class); 

     /* 
     * Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
     * magic cannot be resolved or is not a field 
     */ 

     magicRoom.magic = "a"; 

    } 
} 
+0

我不明白,這個班被稱爲「MagicRoom」嗎? – 2014-02-07 16:33:04

回答

5

作出這樣的方法一般:

public static <T extends Room> T makeRoom(Class<T> roomClass) 
    throws IllegalArgumentException, InstantiationException, 
     IllegalAccessException, InvocationTargetException, 
     SecurityException, NoSuchMethodException{ 

    // This is enough, if you have 0-arg constructor in all your subclasses 
    return roomClass.newInstance(); 
} 

,然後調用它像:

MagicRoom magicRoom = MazeGame.makeRoom(MagicRoom.class); 
+0

經過測試並被接受,我沒有足夠的聲望點來不滿意答案。 –

+0

單擊答案評級下面的勾號以接受答案。我以爲任何人都可以upvote? –

+0

它說我需要至少15點聲望:( –

2

你必須投客房對象MagicRoom。

MagicRoom magicRoom = (MagicRoom) MazeGame.makeRoom(MagicRoom.class); 

另外,我知道這只是一個例子,但你應該使這些屬性爲私有的,並使用訪問器/增變器方法。

例如

public class MagicRoom extends Room { 

    public MagicRoom(){ 
    System.out.println("Creating a MagicRoom."); 
    } 

    private String magic = ""; 

    public String getMagic() { 
    return this.magic; 
    } 

    public void setMagic(String magic) { 
    this.magic = magic; 
    } 

} 
+0

羅希特的回答實際上是我的一個更好的選擇,但你還是應該避免的公共屬性。 –

+0

謝謝你的回答,你說得對使公共屬性。 –