Bonjour,

J'ai un petit soucis pour me représenter ce qu'il se passe réellement en mémoire, et je commence sérieusement à m’emmêler les pinceaux malgré les lectures de ci de là sur le net. Aussi, je me tourne vers vous afin d’éclairer ma lanterne.

Mettons que j'ai les classes suivantes :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Mere
{
   public void doSmth(){ 
      System.out.println("Mere: doSmth");  
   }
}
 
public class Enfant extends Mere
{
   public void doSmth() { 
      System.out.println("Enfant: doSmth"); 
   }
   public void onlyDefinedInChild() { 
      System.out.println("Enfant: onlyDefinedInChild"); 
   }
}
Nous sommes d'accord sur les implications suivantes :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
Mere m = new Mere(); m.doSmth(); // print: Mere: doSmth 
Enfant e = new Enfant(); e.doSmth(); // print: Enfant: doSmth (si doSmth() pas defini dans Enfant alors on aurait eu Mere: doSmth )
Maintenant, le cast:
1) je reprends ce post :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
Mere derivedInstance = new Enfant();
Mere baseInstance  = new Mere();
   
Enfant good = (Enfant) derivedInstance; // OK
Enfant fail = (Enfant) baseInstance;    // Throws InvalidCastException

derivedInstance.doSmth(); // print: Enfant: doSmth
Je ne comprends pas ce qu'il se passe en mémoire : pourquoi derivedInstance.doSmth(); appelle correctement une méthode de Enfant par overriding (mécanisme qui me semble somme logique du fait du new Child() ), alors que je ne peux pas appeler une méthode uniquement définie dans Enfant (derivedInstance.onlyDefinedInChild() me renvoie une erreur) ?
Pourtant, si j'imprime la taille de mes objets, derivedInstance semble avoir l'espace mémoire d'un Enfant (plus grand que son parent baseInstance).
Pourquoi pouvoir appeler certaines méthodes de l'Enfant et pas d'autres ?

2) Deuxième constat que je ne m'explique pas, je pense que j'ai loupé un principe pourtant crucial pour bloquer là dessus :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
Enfant c = new Enfant();
Mere p = (Mere) c;
p.doSmth(); // print:  Enfant: doSmth
Je m'attends après un cast à avoir comme print: Mere: doSmth. Pourquoi diantre est-ce le doSmth() de l'enfant qui est appelé ?
Que se passe-t-il en mémoire ?


Merci par avance de m’éclairer sur ces points.