Mario
Mario

Reputation: 369

How to create a new object based on interface implementation

Firstly, I believe my question is badly worded but don't really understand how to phrase it.

I have a starting interface that is being implemented by a number of classes. What I want to do is to see if there is a way to create a new object such that I am being passed the generic interface, then based on the method .getClass().getSimpleName(), create a new object based on that string.

Is the only way to create a switch case statement? As the number of implementing classes are too many (about 100 or so).

Reference code:

public interface MyInterface {
  public void someMethod();
}

then I would have my implementing classes:

public class MyClass1 implements MyInterface {
  public void someMethod() { //statements }
}

public class MyClass2 implements MyInterface {
  public void someMethod() { //statements }
}

public class MyClass3 implements MyInterface {
  public void someMethod() { //statements }
}

What I want to have in the end is another class which is passed an argument of type MyInterface, get the simple name from that and create a new instance of MyClassX based on that simple name.

public class AnotherClass {
  public void someMethod(MyInterface interface) {
    if (interface == null) {
      System.err.println("Invalid reference!");
      System.exit(-1);
    } else {
      String interfaceName = interface.getClass().getSimpleName();
      /**
       * This is where my problem is!
       */
      MyInterface newInterface = new <interfaceName> // where interfaceName would be MyClass1 or 2 or 3...
    }
  }
}

Any help is highly appreciated!

Upvotes: 1

Views: 950

Answers (2)

elbraulio
elbraulio

Reputation: 994

This is a common problem with many solutions. When I face it, I never use reflection because it is difficult to maintain if it is part of a big project.

Typically this problem comes when you have to build an object based on a user selection. You can try a Decorator pattern for that. So, instead of building a different object for each option. You can build a single object adding functionality depending on a selection. For instance:

// you have
Pizza defaultPizza = new BoringPizza();

// user add some ingredients
Pizza commonPizza = new WithCheese(defaultPizza);

// more interesting pizza
Pizza myFavorite = new WithMushroom(commonPizza);

// and so on ...

// then, when the user checks the ingredients, he will see what he ordered:
pizza.ingredients();
// this should show cheese, mushroom, etc.

under the hood:

class WithMushroom implements Pizza {
    private final Pizza decorated;
    public WithMushroom(Pizza decorated) {
        this.decorated = decorated;
    }
    @Override
    public Lizt<String> ingredients() {
        List<String> pizzaIngredients = this.decorated.ingredients();
        // add the new ingredient
        pizzaIngredients.add("Mushroom");
        // return the ingredients with the new one
        return pizzaIngredients;
    }
}

The point is that you are not creating an object for each option. Instead, you create a single object with the required functionality. And each decorator encapsulates a single functionality.

Upvotes: 1

Mark Bramnik
Mark Bramnik

Reputation: 42461

You can use reflection for this:

public void someMethod(MyInterface myInterface) {
Class<MyInterface> cl = myInterface.getClass();
MyInteface realImplementationObject = cl.newInstance(); // handle exceptions in try/catch block
}

Upvotes: 1

Related Questions