Certificacao - interessante

12 respostas
maxguzenski

achei essa questao bastante interessante, o q acham?

class G {
	String s1 = "G.s1";
	
	void printS1(){
		System.out.print("G.printS1," + s1);
	}
	
	G() { 
		printS1();
	}
}

class H extends G {
	String s1 = "H.s1";
	
	void printS1() {
		System.out.print("H.printS1," + s1);
	}

	public static void main(String[] args) {
		H h = new H();
	}
}

12 Respostas

marciolx

essa é uma “pegadinha” clássica (e infame como todas as outras, na minha opinião), o método chamado é o do objeto em runtime.

marciolx

fora isso eu não entendí o valor impresso do s1, o que ocorreu?

ricardolecheta

porque s1 fica com o valor null? :?:

cancao

Acho que acontece o seguinte:

G() {
      printS1();
      // aqui.
   }

No “aqui”, o construtor da super classe é que está sendo (implicitamente) executado e por isso a variavel s1 ainda não foi iniciada. Apenas quando o construtor da classe H executar é que a variavel será inciada. Acho que é isso. No mais a questão é bastante interessante. Eu errei nesse esquema de imprimir null. :oops:

Até mais.

L

Tudo bem, ele chama o construtor da classe pai e a variavel ainda nao foi inicializada, por isso imprimi null, agora eu a inicializei a variavel dentro do construtor pai e ela continuou nula… pq???

T

Pelo que eu entedi , a ordem das coisas eh a seguinte, quando voce cria um objeto java:

  1. chamada do construtor do pai ( o default ou o especificado pelo super(), caso essa chamada exista )

  2. inicializacao das variaves do objeto ( variaveis nao staticas)

  3. execucao do construtor da classe

Como o construtor da classe pai chama um metodo que eh definida na classe filha, esse metodo printS1 eh executado. Note que a variavel s1 da classe pai possui valor, mas a inicializacao da variavel s1 da classe filha ainda nao voi executada. Ao executar a o printS1 da filha, a referencia da s1 eh da classe filha, nao classe pai. por isso o null aparece.

Se fosse realizada a referencia para super.s1, apareceria o conteudo da s1 da parent, eh claro.

TaQ

Experimentem criar um construtor para H.
Ele não passa lá antes da printS1() da H, então o construtor da H só é rodado após G ter terminado de fazer suas coisas … na minha saída aqui tive:

  • construtor de G
  • chamada de G para printS1() de H
  • construtor de H
TaQ

Outra:
Se as duas printS1() forem declaradas private, o output será:
G.printS1,G.s1

L

Pergunto:
se no construtor pai eu tenho :

G () { 
setString();
printS1()
}

ele nao deveria executar os dois metodos, e na classe filha imprimir o valor da variavel do pai???

TaQ

Nesse caso funciona legal (se você definir o setString() em ambas as classes), pois ele vai inicializar e imprimir a s1 de H através das duas funções chamadas, que são da classe filha (H) e não da classe pai (G). Então:

1 - H é criada e chama o construtor de G
2 - G chama o método setString() de H (ele existe lá também! sobrepõe o definido em G … se vc não criar esse método em H, ele vai chamar o da G mas a s1 de H continuará nula)
3 - G chama o método printS1() de H (ele existe lá também! sobrepõe o definido em G … se vc não criar esse método em H, ele vai chamar o da G, e aí vc vai ver a s1 definida no item 2)
4 - Construtor de H é chamado

Ah, sem querer ser mala mas tá errado o comecinho da sua assinatura eheh
"Posso ter facrassado muitas vezes". :wink:

L


Ah, sem querer ser mala mas tá errado o comecinho da sua assinatura eheh
"Posso ter facrassado muitas vezes". ;-)

boa :smiley:
valeu

Alexandre

Notem que se declararmos as variaveis como:

static String s1 = "G.s1";  // na classe G
static String s1 = "H.s1";  // na classe H

as variaveis, sendo staticas, serao inicializadas antes dos construtores,
como a classe em execucao e “H”, entao sera inicializado, e impresso:

Criado 23 de julho de 2003
Ultima resposta 31 de jul. de 2003
Respostas 12
Participantes 8