Random_Guy_a
Random_Guy_a

Reputation: 107

Problems with Interfaces and FactoryPattern

I have created a factory pattern to create my objects, but each of the objects are slightly different and i want them to implement different methods, with my current setup I have to declare all methods in the interface and in the subsequent object classes, how can I get around this?

This is an example of the structure

food class

public class Food extends MyObjects implements MyActiveObject, {

public Food(String name, Coordinates coordinates, int size, Color color) {
    super(name, coordinates, size, color);  
    }
}

Herbivore class

public class Herbivore extends Entity implements MyActiveObject {
public Herbivore(String name,Coordinates coordinates, int size, Color color){
    super(name, coordinates, size, color);
}

}

interface

public interface MyActiveObject extends EntityInterface {

    public Coordinates getCoordinates();
    etc...
}

Factory class

public class MyActiveObjectFactory {

public MyActiveObject createObject(String objectType, int objectCount, int x, int y, int scale){

    if(objectType == null){
         return null;
    }else{

        if(objectType.equalsIgnoreCase("HERBIVORE")){
            return new Herbivore();
        }
        else if(objectType.equalsIgnoreCase("CARNIVORE")){
            return new Carnivore();
        }
        else if(objectType.equalsIgnoreCase("FOOD")){
            return new Food();
        }
        else if(objectType.equalsIgnoreCase("DRINK")){
            return new Drink();
        }   
    }
    return null;
}

Object creation

MyActiveObject activeObject = activeObjectFactory.createObject("Herbivore", activeObjectCount, x, y, scale);

Ive removed any unessary code to save space, what im trying to do is store food and herbivore as an activeobject in an array but i want to be able to call different methods on each of them, I cannot change them to an abstract class due to the inheritence so im all out of ideas, can anyone help?

Thank you in advance

Upvotes: 0

Views: 74

Answers (1)

TommCatt
TommCatt

Reputation: 5636

Perhaps I'm misunderstanding your question, but why can't you have something like this? The getCoordinates method is defined in the interface and implemented in each class, but each class also has its own methods.

public class Test{
    private MyActiveObject[] mObjList = new MyActiveObject[ 4 ];

    public Test(){
        mObjList[0] = new Food();
        mObjList[1] = new Drink();
        mObjList[2] = new Herbivore();
        mObjList[3] = new Carnivore();
    }

    public void doTest(){
        for( MyActiveObject obj : mObjList ){
            obj.getCoordinates();  // No conversion required for common method

            if( obj instanceof Herbivore ){
                Herbivore newObj = ( Herbivore ) obj;
                newObj.doHerbivoreWork();
            }
            else if( obj instanceof Carnivore ){
                Carnivore newObj = ( Carnivore ) obj;
                newObj.doCarnivoreWork();
            }
            else if( obj instanceof Food ){
                Food newObj = ( Food ) obj;
                newObj.doFoodWork();
            }
            else if( obj instanceof Drink ){
                Drink newObj = ( Drink ) obj;
                newObj.doDrinkWork();
            }
        }
    }

    public static void main( String[] args ){
        new Test().doTest();
    }
}

The do<class>Word methods contain just a print statement as do the getCoordinates methods. The output of running the above is:

Getting Food Coordinates...
Working on Foods.
Getting Drink Coordinates...
Working on Drinks.
Getting Herbivore Coordinates...
Working on Herbivores.
Getting Carnivore Coordinates...
Working on Carnivores.

Update: Here is the definition of the interface:

public interface MyActiveObject{
    public Coordinates getCoordinates();
}

The classes Entity and MyObjects are empty. Drink and Food extend MyObjects:

public class Drink extends MyObjects implements MyActiveObject{
    @Override
    public Coordinates getCoordinates(){
        System.out.println( "Getting Drink Coordinates..." );
        return new Coordinates();
    }
    public void doDrinkWork(){
        System.out.println( "Working on Drinks." );
    }
}

Carnivore and Herbivore extend Entity:

public class Carnivore extends Entity implements MyActiveObject{
    @Override
    public Coordinates getCoordinates(){
        System.out.println( "Getting Carnivore Coordinates..." );
        return new Coordinates();
    }
    public void doCarnivoreWork(){
        System.out.println( "Working on Carnivores." );
    }
}

Update the second: I think I see the problem. The interface you are using has a lot of method signatures not needed in your classes. Is that it?

In that case, just create an empty marker interface just for the purpose of being able to place different classes in an array.

public interface Arrayable{};

Upvotes: 1

Related Questions