Przykład, który prezentujesz w swoim Pytanie nie ma nic wspólnego z Javą 8 i wszystkim, co ma wspólnego z tym, jak generics działa w Javie. Function<T, Integer> function
i Function<T, Double> function
przejdą type-erasure po kompilacji i zostaną przekształcone na Function
. Regułą dla przeciążania metod jest posiadanie innej liczby, typu lub sekwencji parametrów. Ponieważ obie metody zostaną przekształcone, aby przyjąć argument Function
, kompilator narzeka na to.
Zgodnie z powyższym, srborlongan podał już jeden sposób rozwiązania problemu. Problem z tym rozwiązaniem polega na tym, że musisz nadal modyfikować klasę Test
dla każdego rodzaju operacji (dodawania, odejmowania itp.) Na różnych typach (liczba całkowita, liczba podwójna itd.). Alternatywnym rozwiązaniem byłoby wykorzystanie method overriding
zamiast method overloading
:
Zmień klasa Test
nieco następująco:
public abstract class Test<I,O extends Number> {
List<I> list = new ArrayList<>();
public O performOperation(Function<I,O> function) {
return list.stream().map(function).reduce((a,b)->operation(a,b)).get();
}
public void add(I i) {
list.add(i);
}
public abstract O operation(O a,O b);
}
utworzyć podklasę Test
że doda dwa Integer
s.
public class MapStringToIntAddtionOperation extends Test<String,Integer> {
@Override
public Integer operation(Integer a,Integer b) {
return a+b;
}
}
kod Klient może następnie wykorzystać powyższy kod w następujący sposób:
public static void main(String []args) {
Test<String,Integer> test = new MapStringToIntAddtionOperation();
test.add("1");
test.add("2");
System.out.println(test.performOperation(Integer::parseInt));
}
Zaletą stosowania tej metody jest to, że klasa Test
jest zgodny z zasadą open-closed
. Aby dodać nową operację, taką jak mnożenie, wystarczy dodać nową podklasę metody Test
i override
do pomnożenia dwóch liczb. Wymieszaj to z wzorcem Decorator i możesz nawet zminimalizować liczbę podklas, które musisz utworzyć.
Uwaga Przykład w tej odpowiedzi ma charakter orientacyjny. Istnieje wiele obszarów wymagających ulepszeń (takich jak sprawienie, że Test
jest funkcjonalnym interfejsem zamiast klasy abstrakcyjnej), które wykraczają poza zakres pytania. Zobacz
Tak samo, jak Java 7, 6 i 5: nie można . Tak mówi ci ten komunikat. –