我试图首先填充通用对象列表,然后实例化它们,并在实例化它们时,指定每个对象中的哪一个。
我正在处理的用例是读取数据文件并构建一个具有各种可交互对象的地图。每个对象可交互的类型存储在它自己的数据文件中,该文件来自地图的数据文件。一些代码例如:
阅读地图:
if ((char)map[i][j] == '*')
mapObjects.add(new MapObject());
之后:
for (int i = 0 ; i < mapObjects.size() ; i++)
mapObjects.set (i, new MapObject(in.readLine()));
//in.readLine gives the path for the file
在MapObject的构造函数中:
public MapObject (String in){
try{
BufferedReader br = new BufferedReader(new FileReader("src/data/" + in + ".txt"));
int temp = Integer.parseInt(br.readLine());
if (temp == 0)
this = new Door (); //this is apparently not allowed
/*continue to instantiate the Door's fields from the data file*/
}
和门类:
public class Door extends MapObject {
public Door () {}
}
我意识到这可能不是解决这个问题的最佳方法,但它提出了这不起作用的好奇心。有没有办法做到这一点?让super的构造函数选择它将成为哪个子类?
答案 0 :(得分:1)
不可能。因为必须首先调用子类构造函数,并且它(显式或隐式)调用超类构造函数。所以Door(例如)构造函数必须已经在超类教师之前被调用,如果这是一个Door的实例。
父/子在这里不是正确的术语。您似乎在谈论一个类和一个或多个子类。
回复已修改的问题:
您可能希望用MapObject工厂替换MapObject构造函数。搜索工厂模式或静态工厂方法模式。
答案 1 :(得分:1)
你想要的是Abstract Factory pattern。
...简言之
让超类了解子类是一种糟糕的设计,但是有一个知道两者的单独类是可以的。
抽象工厂定义了一个工厂方法,它返回抽象类型(接口或超类 - 在本例中为MapObject),该方法根据参数确定将返回哪个确切的类。方法
一个简单的例子是:
public class MapObjectFactory {
public MapObject create(int i) {
if (i == 0)
return new Door();
if (i == 1)
return new OtherSubClass();
// etc, then a "default" in case above conditions not met
return new MapObject();
}
}
然后调用:
MapObjectFactory factory = new MapObjectFactory();
MapObject m = factory.create(Integer.parseInt(br.readLine()));
您可以设置create()
方法static
以避免必须创建MapObjectFactory
的实例,只是为了调用无状态方法:
MapObject m = MapObjectFactory.create(Integer.parseInt(br.readLine()));
但是如果你想让选择标准变得动态,你就无法在运行时交换另一个实现。在这种情况下,您可以使工厂类实现一个接口,并使用类名来加载它(或者甚至为抽象工厂设置一个抽象工厂!)。