16 fevereiro 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.


Creative Commons License
Esta obra está licenciada sob uma Licença Creative Commons.
Comentários
0 Comentários

0 comments:

Postar um comentário

Regras são chatas, mas...

- 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;