Использование параметрической версии дает
- Больше информации для пользователей функции
- Ограничивает количество программ, которые вы можете написать (бесплатная проверка ошибок)
В качестве случайного примера предположим, что у нас есть метод, который вычисляет корни квадратного уравнения
int solve(int a, int b, int c) {
// My 7th grade math teacher is laughing somewhere
}
И затем вы хотите, чтобы он работал на другие виды числа, как вещи, помимо int
. Вы можете написать что-то вроде
Num solve(Num a, Num b, Num c){
...
}
Проблема в том, что это не говорит о том, что вы хотите. Это говорит
Дайте мне любые 3 вещи, которые похожи на числа (не обязательно таким же образом), и я верну вам какое-то число
Мы не можем сделать что - то вроде , int sol = solve(a, b, c)
если a
, b
и c
это int
потому , что мы не знаем , что этот метод будет возвращать int
в конце концов! Это приводит к некоторым неловким танцам с удручением и молитвой, если мы хотим использовать решение в более широком выражении.
Внутри функции кто-то может передать нам число с плавающей запятой, бигинт и градусы, и нам придется сложить и умножить их вместе. Мы хотели бы статически отклонить это, потому что операции между этими 3 классами будут бессмысленными. Степени - мод 360, так что не будет случая, a.plus(b) = b.plus(a)
когда возникнут подобные забавы.
Если мы используем параметрический полиморфизм с подтипами, мы можем исключить все это, потому что наш тип фактически говорит о том, что мы имеем в виду
<T : Num> T solve(T a, T b, T c)
Или словами «Если вы дадите мне какой-то тип, который является числом, я могу решить уравнения с этими коэффициентами».
Это встречается и во многих других местах. Другой хороший источник примеров являются функции, абстрактной над каким - то контейнером, ала reverse
, sort
, map
и т.д.