Utilizzando la versione parametrica dà
- Ulteriori informazioni per gli utenti della funzione
- Limita il numero di programmi che puoi scrivere (verifica dei bug gratuita)
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 le cose oltre int
. Puoi scrivere qualcosa del genere
Num solve(Num a, Num b, Num c){
...
}
Il problema è che questo non dice quello che vuoi. Dice
Dammi 3 cose che sono numeri (non necessariamente allo stesso modo) e ti restituirò una sorta di numero
Non possiamo fare qualcosa come int sol = solve(a, b, c)
if a
, b
e c
siamo int
s perché non sappiamo che il metodo restituirà un int
alla fine! Questo porta ad alcune danze imbarazzanti con abbattimenti e preghiere se vogliamo usare la soluzione in un'espressione più ampia.
All'interno della funzione, qualcuno potrebbe consegnarci un float, un bigint e gradi e dovremmo aggiungerli e moltiplicarli insieme. Vorremmo rifiutarlo staticamente perché le operazioni tra queste 3 classi saranno incomprensibili. I gradi sono mod 360 quindi non sarà così a.plus(b) = b.plus(a)
e sorgeranno simili simili.
Se usiamo il polimorfismo parametrico con il sottotipo possiamo escludere tutto questo perché il nostro tipo dice effettivamente cosa intendiamo
<T : Num> T solve(T a, T b, T c)
O a parole "Se mi dai un tipo che è un numero, posso risolvere equazioni con quei coefficienti".
Questo succede anche in molti altri posti. Un'altra fonte buona di esempi sono funzioni che astratto su una sorta di contenitore, ala reverse
, sort
, map
, etc.