Mostrando postagens com marcador Overloading. Mostrar todas as postagens
Mostrando postagens com marcador Overloading. Mostrar todas as postagens

sexta-feira, 2 de novembro de 2012

[Java] Overloading ou Overriding? (Parte 2/2)

Uns chamam de sobrescrita outros de subscrita, eu acho subscrita feio, mas sobrescrita está errado, já que overriding não quer dizer isto. Bem vou adotar subscrita e os que tiverem outras idéias podem postar como resposta a este post. Ficarei muito grato!

Overriding (Subscrita).

Subscrita é dar outra implementação a um método que já existe na classe herdada, exceto, é claro, se o método em questão for declarado, na classe mãe, como final ou static.

É o que ocorre com os métodos abstratos herdados de uma superclasse abstrata. Neste caso, a menos que a subclasse também seja abstrata, é obrigatório prover a implementação do método.

Então podemos dizer sem medo de errar, que a subclasse concreta subscreve os métodos abstratos herdados de uma superclasse abstrata.

Nestes casos, você concorda que poderemos ter várias implementações para cada subclasse que subscrever um método abstrato herdado de uma mesma subclasse?

Então podemos dizer que teremos, neste caso, várias formas (implementações) do mesmo método?

É claro que sim, concordo com você, então estamos diante de um polimorfismo, correto?

Correto, você acertou novamente.

Veja um exemplo para prosseguirmos em nosso raciocínio:

public class Animal{
  public void moveSe(){
    System.out.println("Sai de um lugar para outro.");
  }
}

public class Cobra extends Animal{
  public void moveSe(){
    System.out.println("Sai de um lugar para outro, rastejando.");
  }
}

public class Canguru extends Animal{
  public void moveSe(){
    System.out.println("Sai de um lugar para outro, saltando.");
  }
}

public class TesteAnimal(){
  public static void main(String[] args){
    Animal cobra = new Cobra();
    Animal canguru = new Canguru();
    cobra.moveSe();
    canguru.moveSe();
  }
}

O exemplo anterior, compilando sem problemas, produzirá que saída ao executarmos a classe TestAnimal?

Exatamente, a saída será:

Sai de um lugar para o outro, rastejando.
Sai de um lugar para o outro, saltando.

Isto porque, apesar de cobra e canguru serem do tipo Animal, cada uma destas referências, aponta para uma instância de Cobra e Canguru, respectivamente. Portanto, o método subscrito será invocado na execução.

Lembre-se que isto só é possível porque Animal também tem um método moveSe(). Caso contrário, o método moveSe() não teria visibilidade para uma referência do tipo Animal. E mesmo porque, se Animal não tivesse moveSe(), não estaríamos falando de subscrita (e o animal não estaria no código).

Veja outras restrições para um método subscrito:
  • Não pode ter um modificador de acesso mais restritivo.
  • Não pode ter uma assinatura diferente.
  • Não pode ter um tipo de retorno diferente.
  • Não pode ter nível de acesso mais restritivo.
  • Apenas métodos herdados podem ser subscritos. Lembrando, se o método original for final ou static, não poderá ser subscrito, e se for private, só poderá ser subscrito por subclasses no mesmo pacote da superclasse.
  • Não pode lançar exceções verificadas novas ou mais abrangentes que as declaradas pelo método original da superclasse.


É isso! Espero ter-lhe ajudado de alguma forma com estas informações. Qualquer dúvida ou contribuição, fique a vontade para postar. Terei imenso prazer em responder todas.

Mauricio da Silva Marinho.


[Java] Overloading ou Overriding? (Parte 1/2)

Qual a diferença entre estas duas técnicas de programação OO? O que significam?

Overloading (Sobrecarga).

Um método sobrecarregado é aquele que aparece mais de uma vez em uma classe (ou subclasse) com assinatura (lista de argumentos) distinta.

O tipo de retorno e a implementação, podem ser, opcionalmente diferentes. Então podemos dizer que métodos sobrecarregados:

  • devem possuir assinaturas distintas.
  • podem possuir tipos de retorno distintos.
  • podem possuir modificadores de acesso distintos.
  • podem declarar exceções verificadas novas ou mais abrangentes.

Veja o seguinte exemplo de método sobrecarregado:

class Aritmetica{
  public int soma(int a, int b){
    return a + b;
  }
  public double soma(double a, double b){
    return a + b;
  }
}

//Chamando o metodo soma sobrecarregado.
public class TestaAritmetica{
  public static void main(String[] args){
    Aritmetica calculadora = new Aritmetica();
    int a = 10;
    int b = 20;
    int somaDosInts = calculadora.soma(a, b);
    int somaDosDoubles = calculadora.soma(10.5 + 20.5);
  }
}

No exemplo anterior, na classe TestaAritmetica, somaDosInts recebe o retorno da chamada a primeira forma do método sobrecarregado Aritmetica.soma que é soma(int, int). E somaDosDoubles recebe o retorno da chamada a segunda forma do método sobrecarregado Aritmetica.soma, que é soma(double, double). É um método polimórfico, pois tem mais de uma forma.

É o tipo de argumento que irá acionar a forma chamada de um método sobrecarregado, pois a identidade do método é dada pela sua assinatura. Veja este outro exemplo:

class Pet{}

class Cao extends Pet{}

class Lar{
  public void maisUmNaFamilia(Pet pet){
    System.out.println("Chegou um pet na casa!");
  }
  public void maisUmNaFamilia(Cao cao){
    System.out.println("Chegou um cão na casa!");
  }
  public static void main(String[] args){
    Lar lar = new Lar();
    Pet pet = new pet();
    Cao cao = new Cao();
    Pet refParaCao = new Cao();
    lar.maisUmNaFamilia(pet);
    lar.maisUmNaFamilia(cao);
    lar.maisUmNaFamilia(refParaCao);
  }
}

E no caso do exemplo anterior, qual seria a saída?

Lembre-se: a forma do método sobrecarregado será identificada pelos tipos da lista de parâmetros, pela assinatura do método. Logo, independente de refParaCao guardar uma referência de Cao, seu tipo é Pet e por isso o método forma do método sobregarregado Lar.maisUmNaFamilia que será invocada é: Lar.maisUmNaFamilia(Pet). Potanto a saída será:

Chegou um pet na casa!
Chegou um cao na casa!
Chegou um pet na casa!

É isso aí! Estes conhecimentos são cobrados na prova SCJP/OCJP e espero que lhe ajudem a esclarecer algumas questões importantes. No próximo post discutiremos Overriding, as confusões entre os dois conceitos e como o examinador pode se aproveitar disso para lhe confundir no exame.

Forte abraço,

Mauricio da Silva Marinho