2013-12-21 6 views
2

У меня есть этот класс:Инстанцирование общего класса и реализуют общий интерфейс

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

Я еще один класс, который расширяет DrawItem.

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

Теперь, в общем классе CombinationGenerator<E>, я пытаюсь создать экземпляр объектов DrawItem/DrawNumber. Поскольку создание экземпляра типичного типа невозможно в java (например, new E(...)), я создал интерфейс Factory в соответствии с ответом this.

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

Тогда в CombinationGenerator<E> классе

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

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

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

А теперь DrawNumber класс реализует интерфейс DrawItemFactory<DrawItem>.

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

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

И я могу создать класс CombinationGenerator<DrawItem>.

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

До сих пор все в порядке. Но когда я пытаюсь создать DrawNumber класс, как это,

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

Это дает мне следующую ошибку:

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

Я пытался this решение, но я получил ту же ошибку. Есть ли другой способ сделать это?

+4

Почему вы делаете DrawItem фабрику DrawItem? Для создания DrawItem вам понадобится DrawIem. Довольно странно. Используйте отдельные классы как фабрики. –

+0

Спасибо .. решил проблему, создав два отдельных класса фабрики. –

ответ

1

Согласно комментарий @JB Nizet, я уже решил эту проблему путем создания двух отдельные фабрики классов, как это:

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); 
     }   
    } 
} 

В 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(...)); 
     ...... 
    } 
} 

И инстанцирован CombinationGenerator так:

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

List<DrawNumber> combinations = generator.generate(); 
1

Вместо того, чтобы использовать все эти заводы, вы могли бы сделать что-то вроде этого:

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);

+1

Отражение является злым и способствует слишком жесткой привязке к сигнатурам конструктора/метода, которые трудно реорганизовать, если это необходимо в значительной степени. Простой проход «Поставщик », а затем вызов '.get()' дает гораздо большую свободу. 'Функция ' тоже вариант. –

Смежные вопросы