Tem como chamar um método de uma superclasse indireta?

10 respostas
S

Por exemplo:

class A {
    public void metodo() { /*faz algo*/ }
}

class B extends A {
    public void metodo() { /*faz algo*/ } //sobrescrito
}

class C extends B {
    public void metodo() {  //sobrescrito
         //chamar metodo() da classe A
    }
}

Tem como em metodo() da classe C chamar metodo() da classe A?

Tentei algo do tipo: ((A) this).metodo() mas parece que ele chama o próprio método e entra numa recursão infinita.

10 Respostas

P

se A, B e C são Classes, isso aih q vc esta tentando fazer não funciona, pois os 3 métodos tem a mesma assinatura…

os argumentos dos métodos de mesmo nome nas Classes filhas, tem q ser diferentes, aih funciona…simplesmnete passando os argumentos corretos para cada implementação do metodo…

na real precisariamos entender o seu design para saber o q vc esta tentando fazer…

espero ter ajudado…flw

BrunoBastosPJ

Você vai ter que criar uma instância da classe A, não tem como chamar super.super

S
"pedrobusko":
se A, B e C são Classes, isso aih q vc esta tentando fazer não funciona, pois os 3 métodos tem a mesma assinatura....

os argumentos dos métodos de mesmo nome nas Classes filhas, tem q ser diferentes, aih funciona....simplesmnete passando os argumentos corretos para cada implementação do metodo....

na real precisariamos entender o seu design para saber o q vc esta tentando fazer....

espero ter ajudado....flw

O que tenho aqui na verdade é uma classe A com funcionalidades básica, uma classe B que estende A e várias classes que estendem B. Os métodos dessas classes que estendem B serão chamados "polimorficamente" através de objetos da classe B. Ilustrando:

ArrayList<B> objetos = new ArrayList<B>();
objetos.add(new C()); //C estende B
objetos.add(new D()); //D estende B
objetos.add(new E()); //E estende B
//...

for(B i : objetos)
    i.metodo();

/* acredito que mesmo metodo() não sendo abstact em B, será chamado metodo() de C, certo? */

Em uma dessas classes que estende B, achei que apenas um método não precisaria ser reescrito pois o que estava na classe A era suficiente. Mas como o metodo() dessa classe vai ser chamado, pensei em simplesmente encaminhar para a classe A (super.super).

Em C++ acho que daria para usar o operador de resolução de escopo (::), agora em java não sei...

Valeu a atenção cara.

P

bom…consegui entender um pouco melhor…

super.super nao eh possivel…mas como um extende ao outro, em C vc tem acesso aos metodos de A e de B…

a forma mais facil de vc exergar isso, e como se a sua instancia de C, fosse uma grande classe C+B+A…

a nao ser q tenha classes e metodos abstratos nesse meio…aih pode mudar um pouco…

bom, pode ser q a gente nao esteja se entendendo tb, hehehehehe

S

“pedrobusko”:
bom…consegui entender um pouco melhor…
super.super nao eh possivel…mas como um extende ao outro, em C vc tem acesso aos metodos de A e de B…
a forma mais facil de vc exergar isso, e como se a sua instancia de C, fosse uma grande classe C+B+A…
a nao ser q tenha classes e metodos abstratos nesse meio…aih pode mudar um pouco…
bom, pode ser q a gente nao esteja se entendendo tb, hehehehehe

Bom, acho que entendi o que você quis dizer, mas no meu caso eu estaria sobrescrevendo metodo() na subclasses, assim não posso chamar diretamente metodo() das superclasses.

Fiz um pequeno teste aqui, e em C++ isso é possível. Acredito que em Java também deva ser.

Na próxima mensagem postarei dois programas iguais que ilustram o que eu quero fazer, o primeiro escrito em Java e o outro em C++ (já com a solução do problema).

S

Observe metodo() na classe C em ambos os programas:

import java.util.ArrayList;

class A {
    public void metodo() {
		System.out.println("metodo() em A");
	}
}

class B extends A {
    public void metodo() {
		System.out.println("metodo() em B");
	}
}

class C extends B {
    public void metodo() {
		 //gostaria de chamar metodo() de A aqui
         System.out.println("metodo() em C");
    }
}

class D extends B {
    public void metodo() {
        System.out.println("metodo() em D");
    }
}

public class Main {
	public static void main(String args[]) {
		ArrayList<B> objetos = new ArrayList<B>();
		objetos.add(new C());
		objetos.add(new D());

		for(B i : objetos)
			i.metodo();
	}
}

em C++:

#include <list>
#include <iostream>

class A {
public:
	void virtual metodo() {
		std::cout << "metodo() em A" << std::endl;
	}
};

class B : public A {
public:
	void metodo() {
		std::cout << "metodo() em B" << std::endl;
	}
};

class C : public B {
public:
	void metodo() {
		A::metodo(); //assim funciona!
    }
};

class D : public B {
public:
	void metodo() {
       	std::cout << "metodo() em D" << std::endl;
    }
};

int main() {
	std::list<B*> objetos;
	objetos.push_back(new C());
	objetos.push_back(new D());

	for(std::_List_iterator<B*> i = objetos.begin(); i != objetos.end(); i++)
		(*i)->metodo();

	return 0;
}
"Saída em Java:":
metodo() em C metodo() em D
"Saída em C++:":
metodo() em A metodo() em D
P

cara...entendi seu problema....acho q a solução vai ser vc transformar esse método da classe A em estatico e la na classe C vc fazer A.metodo();

maaas, lembrando q vc nao pode efetuar uma chamada estatica de dentro de um metodo estatico, ou seja...o metodo() em C não podera ser estatico....eh isso q eu nao se se vai ser possivel.....se nao rolar, faz como um Bruno falou cria uma instancia de A em C e chama o metodo...nesse caso, a ligação entre A e C não vai te servir, por causa do nivel de acesso q eh limitado a classe pai....

agora se o contexto da sua aplicação for parecido com esse exemplo, a melhor solução na minha opinião seria:

import java.util.ArrayList;

class A {
    public static void metodo(String letra) {
      System.out.println("metodo() em "+letra);
   }
}

class B extends A {
    metodo("B");
}

class C extends B {
    metodo("C");
}

class D extends B {
    metodo("D");
}

public class Main {
   public static void main(String args[]) {
      ArrayList<B> objetos = new ArrayList<B>();
      objetos.add(new C());
      objetos.add(new D());

      for(B i : objetos)
         i.metodo();
   }
}
S
"pedrobusko":
cara...entendi seu problema....acho q a solução vai ser vc transformar esse método da classe A em estatico e la na classe C vc fazer A.metodo();

maaas, lembrando q vc nao pode efetuar uma chamada estatica de dentro de um metodo estatico, ou seja...o metodo() em C não podera ser estatico....eh isso q eu nao se se vai ser possivel.....se nao rolar, faz como um Bruno falou cria uma instancia de A em C e chama o metodo...nesse caso, a ligação entre A e C não vai te servir, por causa do nivel de acesso q eh limitado a classe pai....

agora se o contexto da sua aplicação for parecido com esse exemplo, a melhor solução na minha opinião seria:

import java.util.ArrayList;

class A {
    public static void metodo(String letra) {
      System.out.println("metodo() em "+letra);
   }
}

class B extends A {
    metodo("B");
}

class C extends B {
    metodo("C");
}

class D extends B {
    metodo("D");
}

public class Main {
   public static void main(String args[]) {
      ArrayList<B> objetos = new ArrayList<B>();
      objetos.add(new C());
      objetos.add(new D());

      for(B i : objetos)
         i.metodo();
   }
}

É, não testei, mas acho que é uma solução.
O problema é que foge um pouco do padrão que eu vinha seguindo para os outros métodos, mas talvez isso seja frescura minha.. hehe =P

Criar uma nova instância de A para chamar metodo() não serve de jeito nenhum para minha aplicação.

Valeu mesmo a ajuda cara. Abraço!

P

q bom q pude ajudar…

e lembre-se, padrões são bons enquanto funcionam…hehehehehe…

tem q saber julgar o q tem q funcionar e o q tem q ser feito “corretamente”…

S

“pedrobusko”:
q bom q pude ajudar…

e lembre-se, padrões são bons enquanto funcionam…hehehehehe…

tem q saber julgar o q tem q funcionar e o q tem q ser feito “corretamente”…

Poisé, acho que é bem isso mesmo, preciso “saber julgar” melhor as coisas.
As vezes me apego a detalhes que se parar pra pensar, realmente não vão fazer diferença mais a frente, e acabo perdendo tempo demais pensando em fazer algo para não perder tempo depois, hehe. =P
Não que seja interessante encher de gambiarras, mas é que as vezes não vale a pena mesmo…

Té!

Criado 5 de janeiro de 2007
Ultima resposta 5 de jan. de 2007
Respostas 10
Participantes 3