我有一个抽象类:
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的类,我在编译时不知道这个类,但是我不确定将什么作为其返回类型而不是Room。因为makeRoom返回一个Room,如果我尝试使用属于继承类的字段,我会得到一个异常:
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 :(得分: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);
答案 1 :(得分:2)
您必须将Room对象强制转换为MagicRoom。
MagicRoom magicRoom = (MagicRoom) MazeGame.makeRoom(MagicRoom.class);
另外,我知道这只是一个例子,但你应该将这些属性设为私有并使用accessor / mutator方法。
e.g。
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;
}
}