Вы не можете сделайте это прямо в одном классе, так как определение класса ниже не может быть скомпилировано из-за стирания общих типов и декларации о двойном интерфейсе.
class TwoTypesConsumer implements Consumer<Apple>, Consumer<Tomato> {
// cannot compile
...
}
Любое другое решение для упаковки такой же потреблять операции в одном классе требует, чтобы определить свой класс как:
class TwoTypesConsumer { ... }
, который не имеет смысла, как вам нужно повторить/дублировать определение обеих операций и они на интерфейс не будет ссылаться. IMHO делает это плохое маленькое дублирование кода, которое я пытаюсь избежать.
Это может быть признаком того, что в одном классе слишком много ответственности, чтобы потреблять 2 разных объекта (если они не связаны).
Однако то, что я делаю, и то, что вы можете сделать, это добавить явный фабричный объект для создания подключенных потребителей следующим образом:
interface ConsumerFactory {
Consumer<Apple> createAppleConsumer();
Consumer<Tomato> createTomatoConsumer();
}
Если в действительности эти типы действительно связаны (связанно), то я рекомендовал бы создать реализацию таким образом:
class TwoTypesConsumerFactory {
// shared objects goes here
private class TomatoConsumer implements Consumer<Tomato> {
public void consume(Tomato tomato) {
// you can access shared objects here
}
}
private class AppleConsumer implements Consumer<Apple> {
public void consume(Apple apple) {
// you can access shared objects here
}
}
// It is really important to return generic Consumer<Apple> here
// instead of AppleConsumer. The classes should be rather private.
public Consumer<Apple> createAppleConsumer() {
return new AppleConsumer();
}
// ...and the same here
public Consumer<Tomato> createTomatoConsumer() {
return new TomatoConsumer();
}
}
преимущества заключается в том, что фабрика класс знает, как реализации, существует общее состояние (при необходимости), и вы можете вернуть более Вкупе потребитель, если это необходимо. Нет повторения декларации метода потребления, которые не выводятся из интерфейса.
Обратите внимание, что каждый потребитель может быть независимым (все еще закрытым) классом, если он не полностью связан.
Недостатком этого решения является более высокого класса сложности (даже если это может быть один Java файл а) и для доступа к потреблению метод вам нужен еще один вызов, так вместо:
twoTypesConsumer.consume(apple)
twoTypesConsumer.consume(tomato)
у вас есть:
twoTypesConsumerFactory.createAppleConsumer().consume(apple);
twoTypesConsumerFactory.createTomatoConsumer().consume(tomato);
Резюмируя можно определить 2 родовых потребителей в одном классе верхнего уровня с использованием 2 внутренних классов, но в случае вызова вам необходимо получить первую ссылку на соответствующие реализации потребитель, поскольку это не может быть просто одним потребительским объектом.
Зачем вам нужны два общих интерфейса одного и того же базового типа? – akarnokd
Из-за стирания типа вы не можете этого сделать. Храните его в двух разных классах, которые реализуют потребитель. Делает более маленькие классы, но сохраняет общий код (не используйте принятый ответ, он нарушает всю концепцию ... вы не можете рассматривать TwoTypesConsumer как потребитель, который является ПЛОХОЙ). –