2017-01-04 2 views
0

Моя цель такова: иметь возможность сохранять массив объектов (в данном случае; Animal) на диск. Тогда я хотел бы иметь возможность загружать их. Я использовал JSON для этого, но оставил его в этом фрагменте для ясности. Я хотел бы иметь возможность сделать еще много классов Animal, которые будут иметь еще много полей (см. UnicornClass ниже).Create Class from String input

Класс объекта не может быть известен заранее. Как я могу получить 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"; 
    } 
} 
+0

Ваша проблема действительно выглядит как база данных NoSQL с подходом к документу ... –

+0

Подклассы 'Animal', вероятно, не должны иметь поля« Животное животных »... –

+0

@king_nak да! это просто артефакт более раннего (неправильного) подхода и его следует игнорировать. – jackoverflow

ответ

0

Возможно, вы ищете распределительном заявление, что делает это для вас, что-то вроде:

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; 
    } 
} 
+0

Есть ли альтернатива жесткому кодированию? Если бы я был ленивым программистом, как я мог бы избежать записи нового переключателя каждый раз, когда я делаю новый класс? – jackoverflow

+0

@jackoverflow Hardcoding вы можете решить с перечислением, что-то вроде http://stackoverflow.com/questions/6667243/using-enum-values-as-string-literals. Я не знаю, как избежать добавления новых животных в переключатель. – VinKel

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

ДОЛЖНА решить ее, до тех пор, каждый класс имеет конструктор по умолчанию.

+0

Итак, когда я спасаю животных, я создаю реестр и сохраняю его на диске. – jackoverflow

+0

, чтобы сохранить его на диске, вы будете использовать сериализацию. Сделайте верхний родительский класс реализующим 'Serializable', затем напишите каждый экземпляр в отдельный файл. Для чтения: 'registry.get (« cat »). Cast (objectReadFromDeserialization); См., Как ser/deser здесь http://www.javatpoint.com/serialization-in-java –

+0

Это гораздо менее подробное решение, однако есть некоторые потери производительности при использовании отражения для создания нового экземпляра – CraigR8806