简体   繁体   English

指定超类构造函数中的哪个子类

[英]Specifying which subclass in super class constructor

I am trying to first populate a list of generic objects and later instantiate them, and when instantiating them, specify which of the objects each is. 我试图首先填充通用对象列表,然后实例化它们,并在实例化它们时,指定每个对象中的哪一个。

The use-case I am working on is reading a data file and constructing a map, which has various interactable objects. 我正在研究的用例是读取数据文件并构建一个具有各种可交互对象的地图。 The type of interactable each object is is stored in it's own data file that is directed from the map's data file. 每个对象可交互的类型存储在它自己的数据文件中,该文件来自地图的数据文件。 Some code for example: 一些代码例如:

in reading the map: 在阅读地图时:

    if ((char)map[i][j] == '*')
           mapObjects.add(new MapObject());

and afterward: 然后:

    for (int i = 0 ; i < mapObjects.size() ; i++)
            mapObjects.set (i, new MapObject(in.readLine())); 
            //in.readLine gives the path for the file

in MapObject's constructor: 在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*/
    }

and the Door class: 和门类:

    public class Door extends MapObject {
        public Door () {}
    }

I realize that this probably isn't the best way to solve this problem, but it raised the curiosity that this doesn't work. 我意识到这可能不是解决这个问题的最佳方法,但它提出了这不起作用的好奇心。 Is there any way to do this? 有没有办法做到这一点? Have the super's constructor choose which subclass it will be? 让super的构造函数选择它将成为哪个子类?

Not possible. 不可能。 Because subclass constructor must be invoked first, and it (explicitly or implicitly) calls super class constructor. 因为必须首先调用子类构造函数,并且它(显式或隐式)调用超类构造函数。 So Door's (for example) constructor MUST have already been invoked before the super class instructor, if this is to be an instance of Door. 所以Door(例如)构造函数必须已经在超类教师之前被调用,如果这是一个Door的实例。

Parent/child are not correct terms here. 这里的父母/子女不是正确的条款。 You seem to be talking about a class and one or more subclasses. 您似乎在谈论一个类和一个或多个子类。

Responding to edited question: 回应编辑过的问题:

You probably want to replace the MapObject constructor with a MapObject factory. 您可能希望用MapObject工厂替换MapObject构造函数。 Search for factory pattern or static factory method pattern. 搜索工厂模式或静态工厂方法模式。

What you want is the Abstract Factory pattern . 你想要的是抽象工厂模式

Briefly... 简单地说...

It's poor design to have a superclass know about subclasses, but it's OK to have a separate class that knows about both. 让超类知道子类的设计很糟糕,但是有一个知道两者的单独类是可以的。

The abstract factory defines a factory method that returns the abstract type (an interface or a superclass - in this case MapObject) and the method decides which exact class will be returned based on the parameters to the method. 抽象工厂定义了一个返回抽象类型(接口或超类 - 在本例中为MapObject)的工厂方法 ,该方法根据方法的参数决定返回哪个确切的类。

A simple example would be: 一个简单的例子是:

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

Then to invoke: 然后调用:

MapObjectFactory factory = new MapObjectFactory();

MapObject m = factory.create(Integer.parseInt(br.readLine()));

You could make the create() method static to avoid having to create an instance of MapObjectFactory just to invoke what is a stateless method: 您可以将create()方法设置为static以避免必须创建MapObjectFactory实例来调用无状态方法:

MapObject m = MapObjectFactory.create(Integer.parseInt(br.readLine()));

but then you couldn't swap in another implementation at runtime in case you wanted to make the selection criteria dynamic. 但是如果你想让选择标准变得动态,你就不能在运行时交换另一个实现。 In this case you'd make the factory class implement an interface and make load it using a class name for example (or even have an abstract factory for the abstract factory!). 在这种情况下,您可以使工厂类实现一个接口,并使用类名来加载它(或者甚至为抽象工厂设置一个抽象工厂!)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM