Ciao ragazzi,
ho appena iniziato a studiare il java. A tal proposito, mi sto cimentando con il polimorfismo. Per prova ho scritto queste classi:

codice:
public class Animale {
  
   public void interroga(){
	   	   System.out.println("Ciao");
   }
}


public class Cane extends Animale{
	 
	 public void interroga(){
		   
		   System.out.println("Bau");
	   }

}

public class Gatto extends Animale{
	
	 public void interroga(){
		   
		   System.out.println("Miao");
	   }

}



public class Chiama {
	
	 public static void chiama(Animale a){
		   a.interroga();
	   }
  public static void main(String[] args){
	  Animale a= new Cane();
	  Cane b = new Cane();
	  Gatto c = new Gatto();
	  chiama(a);
	  
  }
}
Allora, la cosa che non capisco è questa. con l'istruzione Animale a= new Cane() io creo un oggetto di tipo Cane e lo memorizzo in un oggetto di tipo animale. Quindi dovrei fare il cosiddetto upcasting. Quindi, siccome a è di tipo Animale, dovrebbe richiamare il metodo interroga della classe Animale. Ma in realtà a chiama interroga della classe Cane, stampando a video "Bau",ma perchè?

Allora che differenza c'è con lo scrivere Cane a = new Cane()? Questa cosa davvero non riesco a capirla. Io pensavo che facendo l'upcasting, si perdesse tutte le implementazioni fatte nella classe figlia. Ma in realtà non si perdono.

Altra cosa che non ho capito è l'incapsulamento. Cioè, cosa cambia se alle variabili di una classe non ci accedo direttamente ma mediante dei metodi getters e setters? Mi fareste un breve esempio in cui è pericoloso non usare l'incapsulamento? Grazie