Sabe-se que, dentro de uma anonymous class podemos chamar métodos, atributos e variáveis da classe principal, porém não é possível fazer o mesmo para chamar métodos de super (método original que foi sobrescrito pela classe principal). Para tanto, encapsulei a chamada em um outro método.
public void superMetodo() {
super.metodo();
}
Porém, me surgiu uma dúvida, o que aconteceria se houvesse uma nova classe na hierarquia de classes que chamasse o método superMetodo()? O super representaria a classe-pai da mesma ou representaria a classe-pai do "ponto" onde foi implementado?
/**
* Representação da dúvida.
*/
class Parent {
public void method() {
//do something
}
}
class Child extends Parent {
public void method() {
//do other thing
}
/**
* Encapsulando chamada a super.method()
*/
public void superMethod() {
//Aqui chama parent.method()
super.method();
}
}
class GrandChild extends Child {
public void test() {
//Aqui chama parent.method() ou child.method()?
superMethod();
}
}
Para solucionar a dúvida, fiz o teste abaixo, como desafio, digam-me o que ocorre. :)
package br.com.teste.oo;
/**
* Testando chamada a super.metodo() dentro de uma classe anônima.
*
* @author wellington.nogueira
*/
public class Main {
/**
* Método inicializador da aplicação
*/
public static void main(String[] args) {
/* **** TESTE 01 **** */
//De acordo com a implementação de run, será chamado
// - o método whoami da classe Pai (super.whoami())
// - o método whoami sobrescrito pela classe Filho
Pai who1 = new Filho();
who1.run();
System.out.println();
/* **** TESTE 02 **** */
//Baseando-se na mesma idéia do teste anterior (TESTE 01),
//o que ocorre aqui?
Pai who2 = new Neto();
who2.run();
}
}
/**
* Classe Pai.
*
* @author wellington.nogueira
*/
abstract class Pai {
/**
* Quem sou eu? :)
*/
public void whoami() {
System.out.println("sou o pai");
}
/**
* Executor
*/
public abstract void run();
}
/**
* Classe que implementa o método run() e sobreescreve whoami() da classe Pai
*
* @author wellington.nogueira
*/
class Filho extends Pai {
@Override
public void whoami() {
System.out.println("sou o filho");
}
/**
* Invocação ao método whoami da classe-pai (herdada por esta classe).
* Esse método foi criado para ser utilizado dentro de uma classe anônima.
*
* @see Pai#whoami()
*/
void superWhoami() {
super.whoami();
}
@Override
public void run() {
//Classe anônima que necessita fazer uma chamada ao método da classe-pai.
Runnable r = new Runnable() {
@Override
public void run() {
// Chamada ao método que substitui chamada de
// super.whoami() que não é possível ser feita aqui.
superWhoami();
whoami();
}
};
r.run();
}
}
/**
* Classe que sobreescreve whoami() da classe Filho.
*
* @author wellington.nogueira
*/
class Neto extends Filho {
@Override
public void whoami() {
System.out.println("sou o neto");
}
}