[RESOLVIDO]Polimorfismo

Galera dado o codigo:

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

Eu olhando o codigo achei que ia imprimir “C”, mas imprime “A”…Porque eu estava pensando que com o polimorfismo ele iria procurar primeiro no filho “C” se nao achasse ou o argumento nao atendesse em “C” ele iria para “A”.

Tem como alguem me explicar por favor o pq?

Em tempo de execução ele procura saber qual é o tipo de objeto é o objeto c1, como é do tipo A, ele executa o método do mesmo! Agora se, a variável c1 fosse C, então ele imprimiria “C”

Ta mas veja só quero saber qual a diferença…

[code]public class A {

void go(String a){
	System.out.println("everton");

}

}[/code]

[code]public class B extends A {

void go(String a){
	System.out.println("jow");

}
}[/code]

[code]public class C {

public static void main(String[] args) {
A teste = new B();

b.go("teste"); // isso imprimi jow, mesmo a variavel teste sendo do tipo "A", devido ao polimorfismo

}
}[/code]

Essa é minha duvida pq no primeiro exemplo ele nao chamou o método de “C”, achava que deveria ser igual ao segundo exemplo…

Mude, na tua classe A, o tipo do parâmetro para Object :wink:

Alguém me corrija se eu estiver errado, mas, para mim, o tipo é referente à classe a qual vc deu o new (C neste caso). A é meramente como você vai referenciar o objeto, mas não o tipo dele.

Everton, com relação à sua dúvida, realmente não consigo entender porque está imprimindo A também… Vamos esperar…

Eu achei que era porque public void m1(C c) não estava sobrescrevendo public void m1(A a). Por[em, se substituirmos

		[code]A c1 = new C();[/code]

por

	[code]B c1 = new C();[/code]

O código passa a imprimir “B”. Ou seja, não tem nada haver com sobreescrita…

Pois é mas na verdade A a = new B(), á variavel “a” é do tipo “A” mesmo, porém nao entendi sobre a questão da chamada do método. Eu trocando o parametro do método de “A” e passando pra Object igual o thiag.correa falou realmente ele chamou o método de “A” porém nao sei pq tb. Agora se eu troco os dois para Object o polimorfismo age e ele chama o método de B. Alguem da uma luz?

Everton, veja este exemplo:

[code]
class Animal{}
class Dog extends Animal{}

public static void metodo(Animal a){
//Aqui, a variável NÃO é do tipo animal. Ela é referenciada por animal, mas o tipo dela continua sendo Dog. Uma variável sempre nasce e morre de um único tipo.
}

public static void main(String args[]){
Dog dog = new Dog(); //Aqui a variável é do tipo Dog, correto?
metodo(dog);
}[/code]

Não é isso?

Pois então se vc fizer: Animal animal = new Dog() “animal” continua sendo um Animal.

é exatamente isso, tanto que no exemplo se vc trocar:

 
A a = new C(); por B b = new C();

a saída seria B

essa questão mostra algumas sutilezas que dificilmente a gente encontra num livro normal de Java

vmsb e pq aqui ele nao faz o mesmo?

[code]public class B extends A {

void go(String a){   
    System.out.println("jow");   

}
}
public class B extends A {

void go(String a){
	System.out.println("jow");

}
}

public class C {

public static void main(String[] args) {
A teste = new B();

b.go("teste"); // isso imprimi jow, mesmo a variavel teste sendo do tipo "A", devido ao polimorfismo   

}
}
[/code]

só lembrando que este código do exercicio é um exemplo de sobrecarga, não de sobreescrita por mudamos o argumento do método…

[quote=evertonsilvagomesjava]vmsb e pq aqui ele nao faz o mesmo?

[code]public class B extends A {

void go(String a){   
    System.out.println("jow");   

}
}
public class B extends A {

void go(String a){
	System.out.println("jow");

}
}

public class C {

public static void main(String[] args) {
A teste = new B();

b.go("teste"); // isso imprimi jow, mesmo a variavel teste sendo do tipo "A", devido ao polimorfismo   

}
}
[/code][/quote]
isso aí é um sobreposição de método e aí o polimorfismo entra na hora de ele escolher o método a ser chamado

É exactamente isso! No primeiro exemplo postado pelo everton fica claro que os métodos das classes B e C não sobrescrevem o método “m1” da classe A,
apenas usam a sobrecarga. Acho que isso explica o pq imprime “A” e não “C”.

sopreposiçao seria o mesmo que sobreescrita? Porque pra mim aquilo era sobreescrita rsrs

sim…rsrsrsrs…vc ta certo…
acho que não vi direito o código…
o primeiro código que vc postou é um exemplo de sobrecarga de métodos, agora o segundo é sobreposição/sobrescrita de métodos :smiley:
fique atento tb na prova para não confundir isso com retornos covariantes…falo isso porq no inicio eu confundia

Hum acho que agora fixou na cachola, em casos com sobrecarga com polimorfismo ele em tempo de execução procura o tipo especifico da variavel.

no caso A a = new B() // por isso ele vai em a, né rs.

agora na passagem para o método exemplo:

[code]public class A {

void go(String a){
	System.out.println("everton");
}

}

public class B extends A {

 void go (Integer nome){
	System.out.println("jow");
}

public static void main(String[] args) {
	
	
	u.go(10); // isso nao compila pq os argumentos tem que serem compativeis, ou na passagem do método teria que ser uma string ok?

}[/code]

se vc fizer A u = new B();
não funciona msm, lembre quando vc faz:

SuperTipo s = new SubTipo

vc só terá acesso aos métodos definidos na classe SuperTipo e os métodos sobrescritos em SubTipo

Quer dizer então que quando se trata do retorno do método sobreescrito, este retorno pode ser de um tipo estendido do tipo da classe pai (retorno covariante) mas, com relação aos parâmetros, é necessário que os tipos sejam exatamente os da classe pai (não podem ser subtipos como no caso do retorno).

É isso?

isso msm…