Em Java, não é possível definir métodos com mesma assinatura na mesma classe. Porém, é possível definir métodos com mesma assinatura em classes derivadas. Isto é um caso de Polimorfismo, ou seja, métodos com a mesma assinatura executando ações diferentes.
Métodos de instância podem ser redefinidos (overridden) por uma subclasse; métodos de classe podem ser escondidos (hidden) por uma subclasse. A tabela abaixo serve de guia para entendermos melhor estes conceitos:
Método de instância na superclasse | Método de classe na superclasse | |
---|---|---|
Método de instância na subclasse | Redefinido | Erro de compilação |
Método estático na subclasse | Erro de compilação | Escondido |
Com relação ao tipo de retorno, uma subclasse pode restringir o tipo de retorno (ou seja, usar um subtipo dele), mas não pode usar um tipo mais geral ou de outra parte da hierarquia de tipos.
Por outro lado, com relação ao encapsulamento, uma subclasse pode ser menos restritiva na permissão de acesso, mas não mais restritiva.
Note que é um erro de compilação usar a mesma assinatura para métodos de classe na superclasse e métodos de instância na subclasse, ou vice-versa.
A diferença entre redefinir e esconder é a seguinte: o método redefinido, quando chamado, determina o tipo da variável na hora da execução para escolher qual código executar, se o da classe filha ou o da classe mãe. A isto se chama acoplamento dinâmico. Exemplo:
Arquivo: Animal.java
public class Animal {
public static void testClassMethod() {
System.out.println("The class method in Animal.");
}
public void testInstanceMethod() {
System.out.println("The instance method in Animal.");
}
}
Arquivo: Cat.java
public class Cat extends Animal {
public static void testClassMethod() {
System.out.println("The class method" + " in Cat.");
}
public void testInstanceMethod() {
System.out.println("The instance method" + " in Cat.");
}
public static void main(String[] args) {
// Método de classe chamado via classe
Animal.testClassMethod();
Cat.testClassMethod();
// Cada macaco no seu galho
Animal myAnimal = new Animal();
Cat myCat = new Cat();
// Método de classe chamado via instância (desencorajado)
myAnimal.testClassMethod();
myCat.testClassMethod();
// Método de instância: escolhe em tempo de execução
myAnimal.testInstanceMethod();
myCat.testInstanceMethod();
// Macaco no galho do outro
myAnimal = myCat;
// Método de classe chamado via instância (desencorajado)
myAnimal.testClassMethod();
myCat.testClassMethod();
// Método de instância: escolhe em tempo de execução
myAnimal.testInstanceMethod();
myCat.testInstanceMethod();
}
}
Saída:
The class method in Animal.
The class method in Cat.
The class method in Animal.
The class method in Cat.
The instance method in Animal.
The instance method in Cat.
The class method in Animal.
The class method in Cat.
The instance method in Cat.
The instance method in Cat.
Anotação @Override
Sobrecarga (overloading) é quando métodos de uma mesma classe têm nomes iguais, mas assinaturas diferentes.
Nenhum comentário:
Postar um comentário