Sobrecarga de métodos
(method overloading)

Computação II - Ciência da Computação


Prof.: Danilo S. Carvalho

Nessa aula, aprenderemos sobre a importância de podermos atribuir o mesmo nome à várias implementações diferentes de um método.


Ao fim da aula, saberemos como e quando implementar múltiplas versões de um método.

Voltemos ao nosso mundo da biblioteca.

Sabemos que aqui temos livros e pessoas. E as pessoas estão aqui para ler livros.

Logo, podemos dizer que a ação principal de uma pessoa nesse mundo (a biblioteca) é ler.

"Reading" by camerazn, licensed under CC BY 2.0

Trazendo isso para o nosso código Java, dizemos que a classe Pessoa possui o método ler.

Vejamos o nosso arquivo Pessoa.java até o momento:

Como a pessoa lê um livro, esse será o tipo do parâmetro do método ler.

Vamos supor que a administração da biblioteca por algum motivo queira saber quantos livros e quantas páginas cada pessoa já leu.

Definimos então os atributos livrosLidos e paginasLidas para manter essa informação.

A cada livro lido incrementamos o valor de livros lidos em 1 e o valor de páginas lidas pelo número de páginas do livro.

                        
                            package br.ufrj.dcc.comp2.ple.aula_danilo.exemplos.biblioteca;
                            import java.time.LocalDateTime;

                            public class Pessoa {
                                String cpf;
                                String nome;
                                LocalDateTime dataNascimento; 
                                String endereço;
                                String telefone;
                            }
                        
                    
                        
                            package br.ufrj.dcc.comp2.ple.aula_danilo.exemplos.biblioteca;
                            import java.time.LocalDateTime;

                            public class Pessoa {
                                String cpf;
                                String nome;
                                LocalDateTime dataNascimento; 
                                String endereço;
                                String telefone;

                                public void ler(Livro livro) {

                                }
                            }
                        
                    
                        
                            package br.ufrj.dcc.comp2.ple.aula_danilo.exemplos.biblioteca;
                            import java.time.LocalDateTime;

                            public class Pessoa {
                                String cpf;
                                String nome;
                                LocalDateTime dataNascimento; 
                                String endereço;
                                String telefone;
                                int livrosLidos;
                                int paginasLidas;

                                public void ler(Livro livro) {

                                }
                            }
                        
                    
                        
                            package br.ufrj.dcc.comp2.ple.aula_danilo.exemplos.biblioteca;
                            import java.time.LocalDateTime;

                            public class Pessoa {
                                String cpf;
                                String nome;
                                LocalDateTime dataNascimento; 
                                String endereço;
                                String telefone;
                                int livrosLidos;
                                int paginasLidas;

                                public void ler(Livro livro) {
                                    this.livrosLidos += 1;
                                    this.paginasLidas += livro.numPaginas;
                                }
                            }
                        
                    

Mas um belo dia, a administração da biblioteca nos informa que além dos livros, vão disponibilizar revistas para as pessoas lerem.


Eles por algum motivo não querem que as revistas sejam contadas como livros, logo não vão entrar na conta de livros, mas contam como páginas lidas.


O que fazemos agora??

Em primeiro lugar, sabemos que as revistas são diferentes dos livros.

Olhamos algumas revistas e chegamos na seguinte classe:

Ela não parece muito diferente da classe Livro, mas vamos resolver isso mais tarde...

Agora precisamos encontrar uma maneira de tornar as pessoas capazes de ler revistas também.

                        
                            package br.ufrj.dcc.comp2.ple.aula_danilo.exemplos.biblioteca;

                            public class Revista {  
                                String titulo;
                                String editora;
                                int numPaginas;
                                String assunto;
                                int edicao;
                            }
                        
                    

A solução para isso será criar um outro método ler, que aceite revistas em vez de livros.

Diferente do que lê livros, esse apenas incrementa o número de páginas lidas.

Mas como o Java vai saber qual método quero chamar se ambos têm o mesmo nome?

Simples, através do tipo do argumento que for passado para o método.

Se ler for chamado passando uma referência a um Livro, o primeiro método será chamado, se for uma referência a uma Revista, será chamado o segundo.

                        
                            package br.ufrj.dcc.comp2.ple.aula_danilo.exemplos.biblioteca;
                            import java.time.LocalDateTime;

                            public class Pessoa {
                                String cpf;
                                String nome;
                                LocalDateTime dataNascimento;
                                String endereço;
                                String telefone;
                                int livrosLidos;
                                int paginasLidas;

                                public void ler(Livro livro) {
                                    this.livrosLidos += 1;
                                    this.paginasLidas += livro.numPaginas;
                                }

                                public void ler(Revista revista) {
                                    this.paginasLidas += revista.numPaginas;
                                }
                            }
                        
                    

Isso que acabamos de fazer chama-se sobrecarga de método (method overloading).


É um recurso importante do ponto de vista semântico, pois quem for utilizar a classe pessoa, vai precisar aprender apenas um método, que pode ser aplicado a vários tipos.


A única restrição quanto à sobrecarga, é que os métodos devem ter assinaturas diferentes, ou seja, não podemos ter dois métodos com o mesmo tipo, quantidade, e posição dos argumentos.
Não podemos, por exemplo, ter dois métodos ler(Livro livro) na classe Pessoa.

Agora sabemos como criar variantes de um mesmo método que operam em tipos diferentes e de formas diferentes, mas mantém uma mesma ideia.


Que tal expandir o mundo da biblioteca, para que as pessoas possam pegar livros ou revistas emprestados?

Perguntas:

  1. Quantas sobrecargas tem o método getBytes da classe String?
  2. Posso sobrecarregar atributos (tipos diferentes, mesmo nome)?

Exercício:

  1. Crie uma classe PiParaTodos que pode emitir o valor de Pi (π) com a precisão numérica desejada (em casas decimais) e em quatro tipos diferentes: double, float, int (truncado) e String.

Até a próxima aula!