Використання параметричної версії дає
- Більше інформації для користувачів функції
- Обмежує кількість програм, які можна написати (безкоштовна перевірка помилок)
Як випадковий приклад, припустимо, у нас є метод, який обчислює корені квадратичного рівняння
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)
if a
, b
і c
є int
s, тому що ми не знаємо, що метод поверне int
в кінці! Це призводить до деяких незграбних танців з придушенням і молитвою, якщо ми хочемо використовувати рішення в більшому виразі.
Всередині функції хтось може подати нам поплавці, бігінти та градуси, і нам доведеться додавати та множувати їх разом. Ми хотіли б статично відкинути це, оскільки операції між цими 3 класами будуть химерними. Градуси є мод 360, тому не буде випадку, a.plus(b) = b.plus(a)
і подібні розбіжності виникнуть.
Якщо ми використовуємо параметричний поліморфізм з підтипом, ми можемо виключити все це, оскільки наш тип насправді говорить про те, що ми маємо на увазі
<T : Num> T solve(T a, T b, T c)
Або словами "Якщо ви дасте мені якийсь тип, який є числом, я можу вирішити рівняння з цими коефіцієнтами".
Це з'являється і в багатьох інших місцях. Інший хороший джерело прикладів є функції, абстрактної над яким - то контейнером, ала reverse
, sort
, map
і т.д.