Nie możesz wykonaj to bezpośrednio w jednej klasie, ponieważ definicja klasy poniżej nie może zostać skompilowana z powodu usunięcia typów ogólnych i zduplikowania deklaracji interfejsu.
class TwoTypesConsumer implements Consumer<Apple>, Consumer<Tomato> {
// cannot compile
...
}
Każde inne rozwiązanie do pakowania takie same zużywają operacje w jednej klasie wymaga, aby określić swoją klasę jako:
class TwoTypesConsumer { ... }
który jest bezcelowe, jak trzeba powtarzać/powielać definicję obu operacji i nie będzie odwoływać się z interfejsu. IMHO robi to źle i powielam kod, którego staram się unikać.
Może to być również wskaźnik, że w jednej klasie jest zbyt duża odpowiedzialność za pochłonięcie 2 różnych przedmiotów (jeśli nie są połączone).
Jednak to, co robię i co można zrobić, to dodać wyraźny obiekt fabryczny stworzyć podłączonych odbiorników w następujący sposób:
interface ConsumerFactory {
Consumer<Apple> createAppleConsumer();
Consumer<Tomato> createTomatoConsumer();
}
Jeśli w rzeczywistości te typy są naprawdę połączony (związane) potem polecam utworzyć wdrożenie w taki sposób:
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();
}
}
zaletą jest to, że klasa fabryka wie obie implementacje, istnieje wspólny stan (jeśli to konieczne) i można powrócić bardziej powiązanych z konsumentów w razie potrzeby. Nie ma powtarzania deklaracji metody konsumowania, która nie pochodzi z interfejsu.
Należy pamiętać, że każdy konsument może być niezależną (wciąż prywatną) klasą, jeśli nie są całkowicie spokrewnieni.
Wadą tego rozwiązania jest to klasa wyższa złożoność (nawet jeśli może to być jeden plik Java) i dostęp do spożywania metoda trzeba jeszcze jedną rozmowę więc zamiast:
twoTypesConsumer.consume(apple)
twoTypesConsumer.consume(tomato)
masz:
twoTypesConsumerFactory.createAppleConsumer().consume(apple);
twoTypesConsumerFactory.createTomatoConsumer().consume(tomato);
Podsumowując można określić 2 konsumentom generycznych w jednej klasie najwyższego poziomu za pomocą 2 klas wewnętrznych, ale w przypadku wywoływania trzeba się najpierw odniesienie do odpowiednich realizacji konsument, ponieważ nie może to być po prostu jeden obiekt konsumencki.
Dlaczego potrzebujesz dwóch ogólnych interfejsów tego samego typu podstawowego? – akarnokd
Z powodu usunięcia typu nie można tego zrobić. Zachowaj dwie różne klasy, które implementują konsumenta. Tworzy więcej małych klas, ale zachowuje ogólny kod (nie używaj zaakceptowanej odpowiedzi, łamie całą koncepcję ... nie możesz traktować TwoTypesConsumer jako konsumenta, który jest ZŁY). –