Monday, February 16, 2009

SCJP - 02 - Métodos sobrecarregados (Overloading)

É, eu também confundia as duas coisas. Overriding é, de forma simplificada, quando você altera o comportamento de um método herdado. Você redefine o método, com o mesmo nome identificador e lista de parâmetros, com base nas regras do post anterior.



Overloading, no entanto, é quando você usa o mesmo nome identificador, mas diferentes tipos de retorno, lista de parâmetros e modificadores de acesso.





class Base {
public String metodo() {
return "apenas um teste na classe base";
}

protected String metodo(Integer numero) {
return numero.toString() + " integer";
}

String metodo(String string) {
return string;
}
}

class Derivada extends Base {

public String metodo() {
return "apenas um teste na classe derivada";
}

public String metodo(boolean teste) {
if (teste) {
return "verdadeiro";
}

return "falso";
}

protected String metodo(Short numero) {
return numero.toString() + " short";
}
}

public class Principal {
public static void main(String[] args) {
Derivada derivada = new Derivada();
Base base = derivada;

System.out.println(
base .getClass().getName() +
": " + base .metodo());

System.out.println(
derivada.getClass().getName() +
": " + derivada.metodo(1));

System.out.println(
derivada.getClass().getName() +
": " + derivada.metodo(true));

}
}


No exemplo acima, o método método é tanto sobrecarregado quanto sobrescrito na classe derivada. E seguindo as regras discutidas nos posts anteriores, não sentimos dificuldades ao concluir que a primeira saída é dada pela versão sem parâmetros do método método, sobrescrita na classe derivada.



Mas as coisas já complicam quando tentamos analisar a segunda saída. O literal 1 é um Integer ou Short? Copie e compile. Pra mim, bateu Integer. Daí eu fui pesquisar, e achei:



int is the default data type of an integer literal. [www.javaying.com]


E daí, concluímos que o literal 1 foi automaticamente convertido para um Integer, e então, a versão do método na classe base foi chamada.



class Base {}

class Derivada extends Base {}

public class Principal {

public void analizaObjeto(Base base) {
System.out.println("objeto da classe base");
}

public void analizaObjeto(Derivada derivada) {
System.out.println("objeto da classe derivada");
}

public void analizaObjeto(Object objeto) {
System.out.println("é um objeto");
}

public static void main(String[] args) {
Principal principal = new Principal();

Derivada derivada = new Derivada();
Base base = derivada;

principal.analizaObjeto(base);

}
}


Você gafanhoto se perguntaria qual das saídas o programa exibiria. É relativamente fácil (eu sempre quis dizer isso :P). Quando se fala de sobrecarga, o que interessa é o tipo definido pela referência, e não o tipo da instância. Até agora, nos meus nossos estudos, a única coisa que leva em consideração o tipo da instância é a chamada de métodos sobrescritos. A resposta da pergunta seria:



objeto da classe base


A versão do método sobrecarregado a ser chamado é decidida em tempo de compilação, com base no tipo declarado pela referência passada por parâmetro.



No comments:

Post a Comment

Regras são chatas, mas...
Todos os comentários são lidos e moderados previamente.
São publicados aqueles que respeitam as regras abaixo:

- Seu comentário precisa ter relação com o assunto do post;
- Em hipótese alguma faça propaganda de outros blogs ou sites;
- Não inclua links desnecessários no conteúdo do seu comentário;
- Se quiser deixar sua URL, comente usando a opção OpenID;
- CAIXA ALTA, miguxês ou erros de ortografia não serão tolerados;
- Ofensas pessoais, ameaças e xingamentos não são permitidos;