classVeiculo{intx=10;publicvoidmetodo(){System.out.println("Valor de x em Veiculo: "+x);//Imprime 10 - OK}}classCarroextendsVeiculo{publicvoidmetodo(){x=11;// variável herdada, não altera a variável de instância de VeiculoSystem.out.println("Valor de x em Carro: "+x);// Imprime 11 - OKsuper.metodo();//Estranhamente imprime 11 ao invés de 10, pq??newVeiculo().metodo();//Aqui imprime 10 corretamente}}
A dúvida é com relação a variável de instância x herdada.
Qual o motivo de a chamada super.metodo() imprimir 11, já que ela chama o método da super classe?
Quando vc fez x=10 na classe pai vc criou um atributo de visibilidade ‘padrão’.
A classe filha alterou o valor do atributo herdado da classe pai. Quando vc executou super.metodo vc invocou o codigo original. O que o codigo original faz? acessa this.x que, nesse objeto, vale 11.
Quer ver prevalecer o valor da classe pai? Faça x= 10 ser private.
Acho que vc esta confundindo com o contexto estatico também. Vc não esta acessando um estado na classe pai pois este estado não existe mais
T
TiagoTC
Quando vc fez a atribuição x = 11 na classe Carro, a variável alterada foi na verdade a da classe Veículo (pois a classe carro não possui uma variável x). Logo após, quando vc faz super.metodo() vc está chamando o método da classe veículo que usa a mesma variável x que vc acabou de alterar.
Na linha de baixo ( new Veiculo().metodo(); ) vc está criando um novo objeto. E esse novo objeto possui o valor de x = 10 normal (vc não alterou ele). Por isso que ao chamar o método “metodo()” dele ele imprime 10.
O fato de uma classe A herdar uma variável de instância da classe B não implica que a classe A irá ter uma cópia da variável. Ela ira usar a mesma variável da classe B.
peczenyj
O termo correto seriam atributos. Gosto de pensar em variaveis como algo que eu crio no escopo de um método (ou bloco de codigo) que ira desaparecer com o termino do mesmo. Pensar em variaveis nesse caso é pensar que podem existir contextos globais como em outras linguagens.
T
TiagoTC
Mas variáveis de instância não é a mesma coisa que atributos?
rmala_ti
peczenyj:
Quando vc fez x=10 na classe pai vc criou um atributo de visibilidade ‘padrão’.
A classe filha alterou o valor do atributo herdado da classe pai. Quando vc executou super.metodo vc invocou o codigo original. O que o codigo original faz? acessa this.x que, nesse objeto, vale 11.
Quer ver prevalecer o valor da classe pai? Faça x= 10 ser private.
Acho que vc esta confundindo com o contexto estatico também. Vc não esta acessando um estado na classe pai pois este estado não existe mais ;-)
Então o fato de imprimir 11 é simplesmente devido a chamada this.x no método padrão, e this neste contexto se refere ao objeto da classe Carro, é isso?
rmala_ti
Tiago, eu discordo.
A variável x é defaul então ela é herdada sim pela subclasse e a variável alterada em Carro é a que essa classe herdou.
TiagoTC:
Na linha de baixo ( new Veiculo().metodo(); ) vc está criando um novo objeto. E esse novo objeto possui o valor de x = 10 normal (vc não alterou ele). Por isso que ao chamar o método “metodo()” dele ele imprime 10.
Concordo, eu vacilei aqui… rsrsrrs
TiagoTC:
O fato de uma classe A herdar uma variável de instância da classe B não implica que a classe A irá ter uma cópia da variável. Ela ira usar a mesma variável da classe B.
Discordo também, se ela foi herdada, é como se ela tivesse sido declarada como atributo da classe Carro.
evertonsilvagomesjav
cara vc esta alterando valor de uma variavel herdada ou seja no objeto que vc esta usando pra chamar o método vc esta realmente alterando o valor dela em Veiculo sim faça o teste com this.x que fica mais facil de enchergar:
publicvoidmetodo(){this.x=11;//aqui seria o equivalente a: c.x = 11; ok? System.out.println("Valor de x em Carro: "+x);super.metodo();newVeiculo().metodo();}publicstaticvoidmain(String[]args){Carc=newCar();c.metodo();}
para resolver o problema vc pode simplesmente declarar um "int x" na classe Car:
publicvoidmetodo(){intx=100;// ou qualquer outro numero que vc quiserSystem.out.println("Valor de x em Carro: "+x);super.metodo();newVeiculo().metodo();}publicstaticvoidmain(String[]args){Carc=newCar();c.metodo();}
T
TiagoTC
TiagoTC:
O fato de uma classe A herdar uma variável de instância da classe B não implica que a classe A irá ter uma cópia da variável. Ela ira usar a mesma variável da classe B.
Discordo também, se ela foi herdada, é como se ela tivesse sido declarada como atributo da classe Carro.[/quote]
Como assim rmalati? Não existe isso de “redeclaração implícita”. A única forma de a classe Carro ter um atributo próprio é declarando ela explicitamente com int x (colocando o tipo antes, conforme o everton explicou). O que acontece é o seguinte: o método “metodo()” da classe Carro possui a atribuição x = 11. Primeiro ele vai procurar no escopo daquele método a variável x. Como não tem nenhuma declaração, ele vai para o escopo da classe Carro. Como também não tem nenhum atributo x declarado na classe Carro, ele então vai procurar nos atributos da classe que Carro herdou (no caso Veículo). Como Veículo possui x declarado, ele vai usar esse. Mas ele não copia o valor de x ou algo parecido. Ele vai usar exatamente esse x da classe Veículo.
rmala_ti
Pouts... num acredito...
agora finalmente eu entendi isso....
Estava enganado mesmo, mas agora clareou.
Eu tinha entendido que se uma classe um membro é como se esta classe tivesse declarado ela mesma.
Herda mesmo, mas existe somente uma variável, a que foi declarada na super classe.
publicclassSobrescricaoteste3{publicstaticvoidmain(String[]args){newSub().teste();}}classSuper{intx=222;publicvoidteste(){System.out.println("Valor de x em Super = "+this.x);}}classSubextendsSuper{intx=22;publicvoidteste(){this.x=444;System.out.println("Valor de x em Sub = "+this.x);// 444super.teste();//222 considerando que Sub declara x, se não declarar imprimirá 444 mesmo.}}
Obrigado pessoal, isso ajuda a explicar algumas questões perdidas nos mocks.
rmala_ti
É Tiago eu achava que era uma redeclaração implícita mesmo, valeu pela ajuda ai.