O uso da versão paramétrica fornece
- Mais informações para os usuários da função
- Restringe o número de programas que você pode escrever (verificação gratuita de erros)
Como exemplo aleatório, suponha que tenhamos um método que calcule as raízes de uma equação quadrática
int solve(int a, int b, int c) {
// My 7th grade math teacher is laughing somewhere
}
E então você quer que ele funcione em outros tipos de números, como outras coisas int
. Você pode escrever algo como
Num solve(Num a, Num b, Num c){
...
}
A questão é que isso não diz o que você deseja. Diz
Dê-me três coisas que são números (não necessariamente da mesma maneira) e eu devolverei algum tipo de número
Não podemos fazer algo como int sol = solve(a, b, c)
se a
, b
e c
somos int
s porque não sabemos que o método retornará umint
no final! Isso leva a uma dança desajeitada, com abatimento e oração, se quisermos usar a solução em uma expressão maior.
Dentro da função, alguém pode nos dar um float, um bigint e graus, e teríamos que adicioná-los e multiplicá-los. Gostaríamos de rejeitar estaticamente isso porque as operações entre essas três classes serão sem sentido. Os graus são mod 360, por isso não será o caso a.plus(b) = b.plus(a)
e hilaridades semelhantes surgirão.
Se usarmos o polimorfismo paramétrico com subtipagem, podemos descartar tudo isso, porque nosso tipo realmente diz o que queremos dizer
<T : Num> T solve(T a, T b, T c)
Ou em palavras "Se você me der um tipo que é um número, eu posso resolver equações com esses coeficientes".
Isso aparece em muitos outros lugares também. Outra boa fonte de exemplos são funções que abstrato sobre algum tipo de recipiente, ala reverse
, sort
, map
, etc.