2 questões de metodos sobrepostos

Sem compilar, oq acontece e pq:
1

class A {void m(A a) {System.out.print("A");}}
class B extends A {void m(B b) {System.out.print("B");}}
class C extends B {void m(C c) {System.out.print("C");}}
class D extends C {
  void m(D d) {System.out.print("D");}
  public static void main(String[] args) {
    A a = new A(); B b = new B(); C c = new C(); D d = new D();
    d.m(a); d.m(b); d.m(c);
}}

2

class A {void m(A a) {System.out.print("A");}}
class B extends A {void m(B b) {System.out.print("B");}}
class C extends B {void m(C c) {System.out.print("C");}}
class D extends C {
  void m(D d) {System.out.print("D");}
  public static void main(String[] args) {
    A a = new A(); B b = new B(); C c = new C(); D d = new D();
    a.m(c); a.m(c); a.m(c);
}}

:?:

Hum… gostei desta questão… não é complicada, mas é inteligente… :slight_smile:

No código 1 ele vai imprimir ABC, isso porque vc está acessando o método M da classe D que sobreu uma sobrecarga em todas as classes…

Ele vai decidir o que imprime em tempo de execução, vai procurar o método que se encaixa com o parametro passado…

Olhe o código abaixo:


public void Testa( int i ) { System.out.println( "Versão Int" ); }
public void Testa( String s ) { System.out.println( "Versão String" ); }

O que acontece se eu tiver este dois metodos em uma classe e executar a linha abaixo?

char c = 'd';
Testa(c);

Qual Método ele vai chamar? o Int ou o String?!

É a mesma lógica para o seu código… o primeiro…


O Segundo código, não é taum simples de enxergar, mas só pensar um pouco…

a Classe A é mãe de todas as outras, nela tem o metodo M que recebe como parametro um objeto do tipo A ou que se encaixem em A… todas as classes que herdam direta ou indiretamente a classe A podem entrar no metodo M…

Este segundo código vai imprimir AAA…


Se falei besteira postem ai em que parte falei fezes…

Atn.
Dennys Fredericci :lol:

Na primeira questao eu concordo com o nosso amigo que responseu…
a primeira eh realmente pelas minha conclusões ABC
mas a segunda o nosso amigo responseu errado…
veja porque…

class A {void m(A a) {System.out.print(“A”);}}
class B extends A {void m(B b) {System.out.print(“B”);}}
class C extends B {void m(C c) {System.out.print(“C”);}}
class D extends C {
void m(D d) {System.out.print(“D”);}
public static void main(String[] args) {
A a = new A(); B b = new B(); C c = new C(); D d = new D();
a.m©; a.m©; a.m©;
}}

a Classe A n tem nenhum metodo que receba como argumentos a classe C, assim ocorrerá erro de compilaçao!!!
entendeu??? eu acho q eh isso :razz:

Então…

eu imagino que noss amigo shadow esteja equivocado…

pois quando é chamado o metodo:


 a.m(c)

a referência c é promovida…

Não tenho como compilar, mas testa ai!

Atn.
Dennys Fredericci

ou testar sim, mas estou quase certo que a minha resposta eh a correta, vou testar isso hoje!!!quando chegar em casa!!! :coffee:

o Dennys esta correto, na verdade o A eh a superclasse, então neste caso você poderá atribuir uma subclasse de “A” em um parametro que recebe “A”.

Estranhu…
vcs tem razão…
a resposta eh realmente AAA, so n entendi direito pq q q isso acontece…

shadow fazendo analogias fica mais facil entender, vou fazer um exemplo

A = Carro
B = Renault
C = Clio

se um parametro recebe “Carro”, você poderá mandar o “Clio” nesse parametro. Pois você garante que “Clio” (por ser uma subclasse de “Renault” e “Carro”) é um “Carro”.

Já o oposto não da pra fazer. Por que se você recebe “Clio”, e manda um “Carro”, não tem como garantir que este “Carro” seja um “Clio”. E é por isso que no primeiro exemplo ele procura nas classes superiores se este método esta implementado. se nao tivesse daria erro.

Isso não explica tecnicamente como funciona. Mas ajuda a visualizar e a compreender. espero que tenha ajudado.

[]'s Victor

Gostei da analogia, fazendo desse modo fica muito mais facil de entender.
:okok:

Aproveitando o assunto, vejam uma variação. O que vocês acham que será impresso ao executar o código? Por que?

package teste; 

class A {
  public void metodo(A a) {
    System.out.print("A ");
  }
}

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

public class Main { 
  public static void main(String[] args) { 
    A aa = new A();
    A ab = new B();
    B bb = new B();
    
    ab.metodo(aa); 
    ab.metodo(ab); 
    ab.metodo(bb);    
  } 
}

Robson acho que vai imprimir “AAA”, melos mesmos motivos das questoes acima…

Sim, “AAA”.

Você tá chamando três vezes o método da primeira classe (A).

na verdade imprime "A A A "
:cool:

gente, num entendi pq em

ab.metodo(bb);

ele Ñ chama o método da classe B, visto que bb e ab são referência de B. Método sempre ñ começam a buscar de baixo pra cima! entaum?

deu pra sacar a pergunta?!

Fábio,

Acho que é assim:

O objeto que chama o método é determinado em tempo de compilação pelo tipo de sua referência, que neste caso é do tipo A.

Como a classe A não tem um método que receba um objeto do tipo B como argumento, mas B é subclasse de A, então bb é convertido, também em tempo de compilação, para um tipo A.

Em tempo de execução, devido ao polimorfismo, o objeto ab que na verdade é do tipo B invoca o método que recebe um objeto do tipo A como arqumento. Como a classe B não substitui este método, então o método da superclasse é executado e imprime A.

:oops: