Vous ne pouvez pas le faire directement dans une classe car la définition de classe ci-dessous ne peut pas être compilée en raison de l'effacement des types génériques et de la déclaration d'interface en double.
class TwoTypesConsumer implements Consumer<Apple>, Consumer<Tomato> {
// cannot compile
...
}
Toute autre solution pour regrouper les mêmes opérations de consommation dans une classe nécessite de définir votre classe comme:
class TwoTypesConsumer { ... }
ce qui est inutile car vous devez répéter / dupliquer la définition des deux opérations et elles ne seront pas référencées depuis l'interface. IMHO faire cela est une mauvaise petite duplication de code que j'essaie d'éviter.
Cela peut également indiquer qu'il y a trop de responsabilité dans une classe pour consommer 2 objets différents (s'ils ne sont pas couplés).
Cependant, ce que je fais et ce que vous pouvez faire est d'ajouter un objet d'usine explicite pour créer des consommateurs connectés de la manière suivante:
interface ConsumerFactory {
Consumer<Apple> createAppleConsumer();
Consumer<Tomato> createTomatoConsumer();
}
Si en réalité ces types sont vraiment couplés (liés), je recommanderais de créer une implémentation de cette manière:
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();
}
}
L'avantage est que la classe de fabrique connaît les deux implémentations, il existe un état partagé (si nécessaire) et vous pouvez renvoyer davantage de consommateurs couplés si nécessaire. Il n'y a pas de déclaration de méthode de consommation répétée qui ne soit pas dérivée de l'interface.
Veuillez noter que chaque consommateur peut être une classe indépendante (toujours privée) s'il n'est pas complètement lié.
L'inconvénient de cette solution est une complexité de classe plus élevée (même s'il peut s'agir d'un seul fichier java) et pour accéder à la méthode de consommation, vous avez besoin d'un appel supplémentaire au lieu de:
twoTypesConsumer.consume(apple)
twoTypesConsumer.consume(tomato)
vous avez:
twoTypesConsumerFactory.createAppleConsumer().consume(apple);
twoTypesConsumerFactory.createTomatoConsumer().consume(tomato);
Pour résumer, vous pouvez définir 2 consommateurs génériques dans une classe de premier niveau en utilisant 2 classes internes, mais en cas d'appel, vous devez d'abord obtenir une référence au consommateur d' implémentation approprié car il ne peut pas s'agir simplement d'un objet consommateur.