Richard_Papen
Richard_Papen

Reputation: 127

Instantiate Object from Class

I am currently writing a library in which users can create own subclasses of a parent abstract class Module. So the library already contains some modules written by me, for example ModuleOne, ModuleTwo, ...

Each Module - subclass should be easily identifiable with an unique identifier, for example an integer, because I want to save multiple module configurations and connections in an xml file. So I can load the saved configurations later and instanciate objects of the desired type.

If I just use predefined classes this is easy, because I know the identifiers of ModuleOne or ModuleTwo, so I can create the Modules in a function:

public static Module getModuleByType(int type)
{
     if (type == ModuleOne.TYPE)
         return new ModuleOne();
     else if (type == ModuleTwo.TYPE)
         return new ModuleTwo();
     //and so on...
}

But if a user makes a subclass of Module, for example CustomModule, how can I assign unique identifiers to this class, so that all Instances of this class have the same type identifier?

How can I dynamically recreate these Modules from their identifiers? So I cannot create the Modules in getModuleByType(), because I do not know their constructor and their identifier.

Thank you for your help.

Upvotes: 0

Views: 107

Answers (2)

m0skit0
m0skit0

Reputation: 25873

I don't think that's a good design. How do you make sure a subclass doesn't reuse a type already used? What if someone has already their own subclasses with their unique identifiers, then imports another library and founds they have duplicate identifiers? Your design is prone to several errors.

Generally speaking it is impossible for you to do such a thing since a subclass can vary greatly from its parent.

If you don't know their constructors, you can never instantiate them because you don't know what the parameters of their constructors mean.

A relatively useful solution is to "force" subclasses to have one specific constructor, let's say no-arg constructor, then you can do the following:

public static Module getModuleByType(final Class<? extends Module> moduleSubClass) {
    Constructor<? extends Module> ctor = moduleSubClass.getConstructor();
    return ctor.newInstance();
}

Although this is slower then directly doing new ModuleSubClass() and you're forcing all subclasses to have a no-arg constructor.

Upvotes: 2

v.ladynev
v.ladynev

Reputation: 19956

You can use full class name (with packages) as an identifier and recreate it using this

Class<?> clazz = Class.forName(className);
Module module = (Module)clazz.newInstance();

Upvotes: 1

Related Questions