0

我试图首先填充一个通用对象列表,然后实例化它们,并在实例化它们时,指定每个对象是哪个对象。

我正在处理的用例是读取数据文件并构建具有各种可交互对象的地图。每个对象的可交互类型存储在它自己的数据文件中,该文件来自地图的数据文件。一些代码例如:

在阅读地图时:

    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 () {}
    }

我意识到这可能不是解决此问题的最佳方法,但它引起了人们的好奇心,即这不起作用。有没有办法做到这一点?超级的构造函数是否选择了它的子类?

4

2 回答 2

1

不可能。因为必须首先调用子类构造函数,并且它(显式或隐式)调用超类构造函数。所以 Door 的(例如)构造函数必须在超类导师之前被调用,如果这是 Door 的一个实例。

父母/孩子在这里不是正确的术语。您似乎在谈论一个类和一个或多个子类。

回复编辑的问题:

您可能想用 MapObject 工厂替换 MapObject 构造函数。搜索工厂模式或静态工厂方法模式。

于 2013-08-26T05:10:06.477 回答
1

你想要的是抽象工厂模式

简要地...

让超类知道子类是很糟糕的设计,但是让一个单独的类知道这两者是可以的。

抽象工厂定义了一个返回抽象类型(接口或超类 - 在本例中为 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()));

但是如果你想让选择标准动态化,你就不能在运行时交换另一个实现。在这种情况下,您将让工厂类实现一个接口并使用例如类名来加载它(或者甚至为抽象工厂提供一个抽象工厂!)。

于 2013-08-26T15:22:56.267 回答