【问题标题】:Create Class from String input从字符串输入创建类
【发布时间】:2017-05-18 18:55:40
【问题描述】:

我的目标是:能够将对象数组(在本例中为Animal)保存到磁盘。然后我希望能够加载它们。我已经使用 JSON 来执行此操作,但为了清楚起见,在此 sn-p 中省略了它。我希望能够制作更多的 Animal 类,它们将有更多的字段(请参阅下面的 Unicorn Class)。

无法预先知道对象的类别。如何让addAnimal 使用String 输入工作?

AnimalWrangler aw;

void setup()
{
  aw = new AnimalWrangler();

  aw.addAnimal("cat");
  aw.addAnimal("horse");
  aw.addAnimal("unicorn");
  aw.addAnimal("unknown");
}

class AnimalWrangler
{

  ArrayList<Animal> animals;

  AnimalWrangler()
  {
    animals = new ArrayList<Animal>();
  }

  void addAnimal(String type)
  {
    //makes an animal according to type        

    ///if type does not exist then throw

    //add to animals array 

  }
}



class Animal
{
  String type;

  Animal()
  {
  }
}

class Cat extends Animal
{
  Animal animal;
  Cat()
  {
    animal = new Animal();
    type = "cat";
  }
}

class Horse extends Animal
{
  Animal animal;
  Horse()
  {
    animal = new Animal();
    type = "horse";
  }
}

class Unicorn extends Animal
{
  Animal animal;
  float magic_level;
  /////classes can have any number of attributes

  Unicorn()
  {
    animal = new Animal();
    type = "unicorn";
  }
}

【问题讨论】:

  • 你的问题看起来真的像一个带有文档方法的 NoSQL 数据库......
  • 您的Animal 子类可能不应该有Animal animal 字段...
  • @king_nak 是的!这只是早期(不正确)方法的产物,应该被忽略。

标签: java processing


【解决方案1】:

典型的方法是创建一个字符串到类映射的注册表:

static Map<String, Class<? extends Animal>> registry;

然后使用类型填充地图:

static {
            registry = new HashMap<>();
            registry.put("cat", Cat.class);
        }

然后,对于AnimalWrangler.addAnimal("cat"); 添加到addAnimal 方法:

animals.add(registry.get("cat").newInstance());

应该解决它,只要每个类都有一个默认构造函数。

【讨论】:

  • 所以当我保存动物时,我会建立注册表并将其保存到光盘上?
  • 要将其保存到磁盘,您将使用序列化。使顶级父类实现Serializable,然后将每个实例写入单独的文件。回读:`registry.get("cat").cast(objectReadFromDeserialization);在此处查看如何 ser/deser javatpoint.com/serialization-in-java
  • 这是一个不那么冗长的解决方案,但是使用反射生成新实例会造成一些性能损失
【解决方案2】:

您可能正在寻找一个为您执行此操作的 switch 语句,例如:

switch (type)
{
    type.equals("cat"): // Note hardcoding isn't the best idea and doesn't account for case sensitivity
        animals.add(new Cat());
        break;
    type.equals("horse"):
        animals.add(new Horse());
        break;
    // Add other animals in a similar fashion.
    default:
        throw new exception();
        break;
    }
}

【讨论】:

  • 有没有硬编码的替代方案?如果我是一个懒惰的程序员,我怎么能避免每次创建一个新类时都写一个新的开关?
  • @jackoverflow 可以用枚举解决的硬编码,例如stackoverflow.com/questions/6667243/…。我不知道如何避免向开关添加新动物。
猜你喜欢
  • 1970-01-01
  • 2021-07-08
  • 1970-01-01
  • 1970-01-01
  • 2013-07-08
  • 2015-05-08
  • 1970-01-01
  • 1970-01-01
  • 2015-10-08
相关资源
最近更新 更多