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.