Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

2. Desenvolva código que mostra o uso de polimorfismo Exercício 7

Pelo que entendi do exercício o "x" não leva o valor 32 consigo e E extends D que extends C que extends B onde x por padrão deve valer zero, e é decrescido um certo? não tenho certeza, aí executa o if e deveria encerrar imprimindo uma vez o "c".

Foi o que entendi, onde eu deixei escapar?

4 respostas
solução!

Fala aí Adauto tudo bem?

Então vamos entender o que acontece nesse código,

No método main instanciamos a classe E e chama-mos o método X passando o valor 32.

Ao executar esse código o compilador vai verificar se na classe E existe um método X como na classe E não existe esse método ele irá procurar super classe de E. Que nesse caso é a classe D. (Então na classe E não faz absolutamente nada.)

A classe D sobre escreve o método X mas na sua implementação ele somente chama o método X da sua super classe (super.x(i)). Que nesse caso é a classe C. ( Ou seja a classe D também não faz nada só repassa a responsabilidade.)

A classe C por sua vez também sobre escreve o método X e a sua implementação ela imprime no console a string b, e delega para a sua super classe a chamada do método X ( super.x(i)). Nesse caso a super classe da classe C é a classe B. ( A classe C imprime no console a letra 'b' e repassa sua responsabilidade para sua super classe.)

A classe B tem o método X e na implementação ele faz o seguinte:

    if( ++i < 0 ) return;
    x(-1);
    System.out.println("c");

quando chega nesse momento o que ocorre é o seguinte, no if ele incrementa a variavel i e verifica se o valor após o incremento é menor que zero.

Como passamos o valor 32 no momento do if será incrementado par 33 e verificado se esse resultado é menor que 0, como nesse caso não é ele passa para a próxima instrução. Que é x(-1) quando o compilador chega nesse ponto ele irá executar o método X da classe que instanciamos, que no caso é a classe E e aí vai repetir todo o processo passando por todas as super classes até chegar na classe B novamente.

Quando chegar na classe B pela segunda vez o valor de i vai estar valendo -1, ao passar pelo if novamente vai ser incrementado e o valor de i vai passar a ser 0 se verificado novamente se 0 é menor que 0 e como não é vai chamar novamente Xpassando o valor -1. E com isso entra em loop infinito e nunca imprime a string c .

Cada chamada ao método X (inclusive cada vez que é repassado a responsabilidade para classe superior) é adicionado à pilha de execução em algum momento ela ultrapassa o limite dessa pilha e gera o erro StackOverflowError.

Se útil marque como solucionado. ;)

Oi Fernando Furtado.

Sim, tive essa mesma percepção. A única coisa que não percebi é que o looping era feito desde a classe E até a B novamente, quando fiz o exercício pressupus que ele chamava o método x de B. Muito obrigado pela explicação. Só uma coisa que acho que não ficou muito claro foi as alternativas. Eu assinalei a "Compila e dá exception." que para mim é o que acontece, só que ele corrigiu dizendo que a correta é "Compila e entra em loop.". Bem, realmente entra em loop mas o resultado final é um StackOverflowError, que eu entendo ser uma Exceção. Eu olhei a alternativa que o exercício da como correta e achei que ele queria dizer que era um loop infinito mas sem erro. Só uma observação. Posso estar errado.

Ressalvas importantes: Primeiro: método/atributo acessado por referência é buscado pelo compilador por herança, enquanto houver herança ele irá buscar até encontrar Segundo: podemos chamar super/this em métodos e atributos a rodo! Em construtores o super/this devem ser a primeira instrução(somente) Terceiro: o loop acontece no if() pois ele verifica se um int é menor que 0, porém ele faz um pré-incremento de -1.

Quarto: a resposta correta não tem: antes de entrar em loop ele imprime b. Resposta correta: compila, imprime b e entra em loop gerando estouro de pilha!

Nesse exercício, eu jurava que iria dar erro de compilação, pois a classe D não tem pelo menos um método abstrato.