L'uso della versione parametrica dà
- Ulteriori informazioni per gli utenti della funzione
- Vincola il numero di programmi che puoi scrivere (controllo bug gratuito)
Come esempio casuale, supponiamo di avere un metodo che calcola le radici di un'equazione quadratica
int solve(int a, int b, int c) {
// My 7th grade math teacher is laughing somewhere
}
E poi vuoi che funzioni su altri tipi di numeri come cose oltre a int
. Puoi scrivere qualcosa come
Num solve(Num a, Num b, Num c){
...
}
Il problema è che questo non dice quello che vuoi. Dice
Give me any 3 things that are number like (not necessarily in the same way)
and I'll give you back some sort of number
Non possiamo fare qualcosa come int sol = solve(a, b, c)
se a
, b
e c
sono int
s perché non sappiamo che il metodo restituirà un int
nel fine! Questo porta a qualche balletto imbarazzante con downcasting e preghiera se vogliamo usare la soluzione in un'espressione più grande.
All'interno della funzione, qualcuno potrebbe darci un float, un bigint e gradi e dovremmo aggiungerli e moltiplicarli insieme. Vorremmo rifiutare staticamente questo perché le operazioni tra queste 3 classi saranno incomprensibili. I gradi sono mod 360 quindi non sarà il caso che a.plus(b) = b.plus(a)
e simili ilarità si presenteranno.
Se usiamo il polimorfismo parametrico con sottotipizzazione possiamo escludere tutto ciò perché il nostro tipo in realtà dice cosa intendiamo
<T : Num> T solve(T a, T b, T c)
O con le parole "Se mi dai un tipo che è un numero, posso risolvere equazioni con questi coefficienti".
Questo succede anche in molti altri posti. Un'altra buona fonte di esempi sono funzioni che si astraggono su una sorta di contenitore, ala reverse
, sort
, map
, ecc.