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…
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…
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…
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.
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);
}
}
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.