Tenha cuidado com a sobrecarga de métodos

Andrei Baptista
3 min readJun 30, 2021

--

Logo no início dos estudos da carreira de todo dev que trabalha com alguma linguagem orientada a objetos, como o Java por exemplo, o mesmo se depara com importantes conceitos como Herança, Polimorfismo, Encapsulamento, Sobrecarga, Sobrescrita e por aí vai…

Porém, por vezes em nossos estudos ou durante as nossas implementações do dia-a-dia, esquecemos de detalhes sutis de alguns deste conceitos que acabam por fazer, com que surjam defeitos inexplicáveis em nosso código, acabamos por passar horas a fio para identificar determinado problema que, com alguns cuidados que vou apresentar agora, poderiam ser mitigados.

Veja este código:

O que este programa faz, basicamente é identificar uma determinada coleção, sendo ela uma lista, um Set ou algum outro tipo. Agora… Lendo o código acima, o que você acha que será escrito na console?

Se você respondeu que seria escrito um Set, seguido de um List de por último um Collection not know, respondeu errado. Na verdade, o retorno “Collection not know” seria exibido três vezes na nossa console.

Acontece que o método ‘classify()’ está sobrecarregado, a escolha de qual sobrecarga utilizar será feita em tempo de compilação para todas as três iterações, e este tipo para todas as três iterações será o mesmo: ‘Collection<?>’.

O tipo em tempo de execução não é o mesmo para as iterações mas isso não influencia a escolha da sobrecarga.

Notou que este código tem um problema tão grande quanto a sua implementação? Ele é totalmente contraintuitivo e aqui vai uma dica muito importante em relação a Sobrecarga x Sobrescrita, a seleção de métodos na sobrecarga é estática, já na sobrescrita é dinâmica. Ou seja, para a sobrescrita, a seleção do método correto é feita em tempo de execução baseada no tipo em tempo de execução do objeto. Agora veja este exemplo:

O método ‘name()’ é declarado na classe ‘Cocacola’ e é sobrescrito nas subclasses ‘Beer’ e ‘Water’. E desta vez, o resultado é exibido corretamente na ordem:

cocacola
beer
water

O tipo em tempo de compilação de um objeto acaba não afetando um método sobrescrito invocado, sempre o método sobrescrito mais aderente é invocado. Na sobrecarga a seleção é feita inteiramente no momento de compilação e é totalmente baseada nos tipos dos parâmetros em tempo de compilação.

Caso eventualmente no nosso exemplo 1, o método ‘classify()’ tivesse de ser estático, poderíamos substituir a sobrecarga e realizar testes de instanceof.

Conclusão

A escrita de códigos contraintuitivos é de muito mau gosto, a possibilidade de um código que tem um comportamento propenso a confundir os programadores pode gerar inúmeros problemas para o seu programa, caso eventualmente um usuário de sua API não saiba quais dos inúmeros métodos sobrecarregados será invocado, diversos erros poderão se manifestar e muitos programadores irão gastar horas para conseguir resolver um problema.

Uma dica: Nunca use duas sobrecargas com o mesmo número de parâmetros.

--

--

No responses yet