Construtor da SuperClasse chamando método sobreescrito da Subclasse?

Boa Tarde, pessoaLL.

O seguinte codigo imprime 40 para tal eu cheguei a conclusão que o construtor da superclasse está chamando um metodo sobrecarregando na subclasse.

public class Base {
	int value = 0; 
              Base(){ 
                addValue(); 
                  } 
    public	void addValue(){
   System.out.println("To sendo chamado na classe base");
   value += 10; } 
     int getValue(){ 
   return value;
	} 
	} 

class Derived extends Base{ 
	Derived(){addValue();}

	public void addValue() {
		System.out.println("To sendo chamado na classe Derived");
		value+=20;
	}
 

	
} 
public class Teste {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Base b = new Derived(); 
		System.out.println(b.getValue()); 
	
	}

}

Agradeço qualquer explicação.

Ao instanciar objeto “d” (Derived) seu construtor chama primeiro o construtor da superclasse Base, implicitamente (super()), que vai invocar o método “addValue()” que foi sobrescrito na subclasse, fazendo “value” valer 20, após isso é executado o construtor da subclasse Derived, q adiciona mais 20 ao “value”, resultando em 40.

Portanto, o método “addValue()” foi sobrescrito e não sobrecarregado, pois se fosse sobrecarregado, como a referência de “b” foi feita para a superclasse Base, o método “addValue” da subclasse não seria exergado qd fosse invocado.

Eu entendi que se trata sobreescrição.
O que eu não entendi é por que quando o construtor da superclasse e executado e chamado a versão sobeescrita do metodo??
Obrigado.

Essa é a grande vantagem da sobrescrita. Você poder redefinir o método. Imagina que o método na superclasse fosse abstrato, o que aconteceria se ele fosse invocado e a superclasse não pudesse ver o método sobrescrito?

Sobrescrever significa “esqueça a implementação da superclasse e use isto no lugar”.

Cara, isso é muito fácil de confundir! Muito bom exemplo!

Na primeira vez q eu vi parecia-me que vc estava chamando b.addValue() e não b.getValue(). Mesmo acessando o contrutos da superclasse ele ainda usa o método sobreescrito. Então instanciando uma variável da subclasse o método da superclasse não será útil mais. Mesmo qd foi chamado dentro do construtor da superclasse.

Mas… olha só o que eu fiz tentando estudar um pouco mais o código

class Base {
	int value = 0;
	Base(){
		addValue();
	}
	private void addValue(){
		System.out.println("To sendo chamado na classe base");
		value += 10;
	}
	int getValue(){
		return value;
	}
}   

class Derived extends Base{
	Derived(){
		addValue();
	}

	public void addValue() {
		System.out.println("To sendo chamado na classe Derived");
		value+=20;
	}
}

public class DerivedTest00 {
	public static void main(String[] args) {
		Base b = new Derived();
		System.out.println(b.getValue());
	}
}

Coloquei o método da superClasse como private. Resultado… o código compila, porém o método addValue não é sobreescrito, então o primeiro contrutor que roda, o da classe Base é obrigado a chamar o método addValue da classe Base e depois o segundo contrutor que roda, da classe Derived chama o método addValue() da classe Derived.

Resultado:
To sendo chamado na classe base
To sendo chamado na classe Derived
30

É nóis estudando pra certificação… :lol:

Apesar que isso possa ser fácil de confundir, ele pode ser um grande aliado no dia a dia. Dê uma pesquisada sobre Template methods pattern e você vai entender melhor essa parte de sobreescrita e como ela pode te ajudar no dia a dia.

Ficou legal tópico bastante esclarecedor.
Valeu pessoal.

Muito legal eu ter topado isso aqui, eu vou prestar a OCJP e se caisse esse tipo de coisa nem sei o que eu responderia.
Vlw galera.

Jamais chame métodos sobrescritos no construtor da classe.
Lembrem-se que a construção ocorre de cima para baixo, portanto, você estará chamando um método de um trecho da classe que sequer foi construído ainda.

O comportamento disso é completamenteindefinido. E, mesmo onde não der erro, será inconsistente também.