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”.
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”
Essa é minha duvida pq no primeiro exemplo ele nao chamou o método de “C”, achava que deveria ser igual ao segundo exemplo…
thiago.correa
Mude, na tua classe A, o tipo do parâmetro para Object
T
TiagoTC
thiago.correa:
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"
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
A c1 = new C();
por
B c1 = new C();
O código passa a imprimir "B". Ou seja, não tem nada haver com sobreescrita...
evertonsilvagomesjav
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?
T
TiagoTC
evertonsilvagomesjava:
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 igual o parametro do método de "A" e passando pra Object 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:
classAnimal{}classDogextendsAnimal{}publicstaticvoidmetodo(Animala){//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.}publicstaticvoidmain(Stringargs[]){Dogdog=newDog();//Aqui a variável é do tipo Dog, correto?metodo(dog);}
Não é isso?
evertonsilvagomesjav
Pois então se vc fizer: Animal animal = new Dog() “animal” continua sendo um Animal.
V
vmsb11
é exatamente isso, tanto que no exemplo se vc trocar:
Aa=newC();porBb=newC();asaídaseriaB
essa questão mostra algumas sutilezas que dificilmente a gente encontra num livro normal de Java
evertonsilvagomesjav
vmsb e pq aqui ele nao faz o mesmo?
publicclassBextendsA{voidgo(Stringa){System.out.println("jow");}}publicclassBextendsA{voidgo(Stringa){System.out.println("jow");}}publicclassC{publicstaticvoidmain(String[]args){Ateste=newB();b.go("teste");// isso imprimi jow, mesmo a variavel teste sendo do tipo "A", devido ao polimorfismo }}
V
vmsb11
só lembrando que este código do exercicio é um exemplo de sobrecarga, não de sobreescrita por mudamos o argumento do método…
V
vmsb11
evertonsilvagomesjava:
vmsb e pq aqui ele nao faz o mesmo?
publicclassBextendsA{voidgo(Stringa){System.out.println("jow");}}publicclassBextendsA{voidgo(Stringa){System.out.println("jow");}}publicclassC{publicstaticvoidmain(String[]args){Ateste=newB();b.go("teste");// isso imprimi jow, mesmo a variavel teste sendo do tipo "A", devido ao polimorfismo }}
isso aí é um sobreposição de método e aí o polimorfismo entra na hora de ele escolher o método a ser chamado
el_loko
É 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”.
evertonsilvagomesjav
sopreposiçao seria o mesmo que sobreescrita? Porque pra mim aquilo era sobreescrita rsrs
V
vmsb11
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
fique atento tb na prova para não confundir isso com retornos covariantes…falo isso porq no inicio eu confundia
evertonsilvagomesjav
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:
publicclassA{voidgo(Stringa){System.out.println("everton");}}publicclassBextendsA{voidgo(Integernome){System.out.println("jow");}publicstaticvoidmain(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?}
V
vmsb11
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
T
TiagoTC
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?
V
vmsb11
isso msm…
el_loko
TiagoTC:
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?
Exactamente. Caso contrário seria sobrecarga.
evertonsilvagomesjav
Métodos com sobrecarga ele procura no Supertipo hehe, e retornos covariantes sao possiveis pq sao com objetos quando se trata de “E-UM”, agora ta entendido, questaozinha bacana essa rs, vlw a todos!!!