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.
P
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?
R
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?
R
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.
E
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.
R
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.
R
rmala_ti
É Tiago eu achava que era uma redeclaração implícita mesmo, valeu pela ajuda ai.