Reputation: 355
I have a game that runs on a similar system to games like terraria or minecraft, at least in the aspect of being blocky.
I have constructed it in a way where each block is an Object, and there is a specific class (extends a BlockObject archetype) for each type of block.
I have the game save the blocks in a file like following
I get the name of the instance of the Object i am saving, and store it in a string I start writing the information of the given Object in a string that has the Name of the Class(signifieing what type of block it is Ex. a block that is an object of BlockGrass.java would be stored as BlockGrass). Normally when reading information from a save file I am reading the save file, when it gets to the info of the blocks it first saves the Block type in a local string (BlockGrass in this case), also saves the positions (x cordinate, and y cordinate). Then it would run through a series of if statements like the following
if(blockType.equals("BlockGrass"))
{
blocksArray.add(new BlockGrass(...));
}
else if(blockType.equals("BlockStone"))
{
blocksArray.add(new BlockStone(...));
}
etc
now I want to make my game vary dynamic, and want it so that if someone decides to make a new Block class (Modding the game) they do not have to modifiey the MapReader class. so instead of running through a series of if statements as shown above (where everytime a new block class is created, a new if statement must be placed for that block), i want it so that it make a new object of a class that has the same name as the BlockType. to give you a better idea look at the following
BlocksArray.add(new blockType(...));
the reason what is shown above does not work is because blockType is a string that holds the name of the class i want to use. not a Class Name
How could i do something like that?, without using if-statements.
Upvotes: 3
Views: 105
Reputation: 4434
What you are trying to do is to take advantage of polymorphic behaviours from your BlockObject hierarchy. Therefore using class.forName
is the good approach. Once you have invoked newInstance()
on the Class variable you will need to cast it to the base class (the archetype as you called it) of your hierarchy of BlockObject class. We have guarantee that since the real class is extending BlockObject, it is a BlockObject according to the definition of inheritance.
Here is an example
public class GameLoader {
private List<BlockObject> blocksArray = new ArrayList<BlockObject>();
public Object getNewBlock(String blockClassName) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class blockClass = Class.forName(blockClassName);
return blockClass.newInstance();
}
public void addNewBlockType(String typeName) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
BlockObject castedType = (BlockObject)getNewBlock(typeName);
blocksArray.add(castedType);
}
}
Any method of the base class invoked on such object will display polymorphic behaviours.
Upvotes: 1
Reputation: 1192
This is not compiled and checked but it is just to indicate what must be done.
// first get the class
Class<?> rawclass = Class.forName(String);
// then check an object will fit where you want it.
if (BlockObject.class.isAssignableFrom(rawclass)){
// create the object, cast it to the correct type and add it
BlockObject object = (BlockObject) rawclass.newInstance();
blockArray.add(object);
}
There will be some exceptions to catch out of the forName and newInstance methods.
Upvotes: 0