2

I have this class:

public DrawItem {
    protected String getSeperator() {
        return "";
    }
    .......
    // some other methods
}

I've another class which extends DrawItem.

public DrawNumber extends DrawItem {
    @Override
    protected String getSeperator() {
        return "-";
    }
}

Now, in a generic class CombinationGenerator<E>, I'm trying to instantiate objects of DrawItem/DrawNumber. As instantiating a generic type is not possible in java (like new E(...)), I've created a Factory interface according to this answer.

public interface DrawItemFactory<E> {
    E create(...);
}

Then in the CombinationGenerator<E> class,

public class CombinationGenerator<E> {
    DrawItemFactory<E> factory;

    public CombinationGenerator<E>(DrawItemFactory<E> factory) {
        this.factory = factory;
    }

    public List<E> generate() {
        ......
        list.add(factory.create(...));
        ......
    }
}

And now the DrawNumber class implements DrawItemFactory<DrawItem> interface.

public DrawItem implements DrawItemFactory<DrawItem> {
    protected String getSeperator() {
        return "";
    }

    @Override
    public DrawItem create(...) {
        return new DrawItem(...);
    }
    .......
    // some other methods
}

And I can create CombinationGenerator<DrawItem> class.

DrawItem drawItem = new DrawItem(...);
CombinationGenerator<DrawItem> generator = new CombinationGenerator<DrawItem>(drawItem);
List<DrawItem> combinations = generator.generate();

So far, everything is fine. But when I try to create a DrawNumber class like this,

public DrawNumber implements DrawItemFactory<DrawNumber> {
     ....
}

It gives me the following error:

The interface DrawItemFactory cannot be implemented more than once with different arguments: DrawItemFactory<DrawItem> and DrawItemFactory<DrawNumber>

I've tried this solution but I got the same error. Is there any other way to do this?

Community
  • 1
  • 1
Rafi Kamal
  • 4,522
  • 8
  • 36
  • 50
  • 4
    Why do you make DrawItem a factory of DrawItem? You would need a DrawIem to create a DrawItem. Quite strange. Use separate classes as factories. – JB Nizet Dec 21 '13 at 08:30
  • Thanks.. solved the problem by creating two separate factory classes. – Rafi Kamal Dec 21 '13 at 09:00

2 Answers2

1

Instead of using all those factories you could do something like this:

public class CombinationGenerator<E> {

    E instance;

    public CombinationGenerator(Class<E> clazz) {
        Constructor<?> con = clazz.getConstructor();
        this.instance = (E) con.newInstance();
    }
}

...
CombinationGenerator<DrawNumber> cg = new CombinationGenerator<DrawNumber>(DrawNumber.class);

bidifx
  • 1,640
  • 13
  • 19
  • 1
    Reflection is evil and promotes too tight binding to constructor/method signatures that are hard to refactor if necessary pretty much. Simple passing `Supplier` and then invoking `.get()` gives much more freedom. `Function` is an option either. – Lyubomyr Shaydariv Dec 21 '13 at 08:55
1

According to @JB Nizet's comment, I've solved the problem by creating two separate factory classes like this:

public interface ItemFactory<E> {
    E create(int[] values);

    public static class DrawItemFactory implements ItemFactory<DrawItem> {

        @Override
        public DrawItem create(int[] values) {
            return new DrawItem(values);
        }           
    }

    public static class DrawNumberFactory implements ItemFactory<DrawNumber> {

        @Override
        public DrawNumber create(int[] values) {
            return new DrawNumber(values);
        }           
    }
}

In the CombinationGenerator,

public class CombinationGenerator<E> {
    ItemFactory<E> factory;

    public CombinationGenerator<E>(ItemFactory<E> factory) {
        this.factory = factory;
    }

    public List<E> generate() {
        ......
        list.add(factory.create(...));
        ......
    }
}

And instantiated CombinationGenerator like this:

DrawNumber drawNumber = new DrawNumber();
CombinationGenerator<DrawNumber> generator = new CombinationGenerator<DrawNumber>(new ItemFactory.DrawNumberFactory());

List<DrawNumber> combinations = generator.generate();
Rafi Kamal
  • 4,522
  • 8
  • 36
  • 50