1. Mais ce n'est pas tout.

Supposons que la Cowclasse ait une printAll()méthode qui appelle deux autres méthodes. Ensuite, le code fonctionnera comme ceci :

Code Description
class Cow
{
   public void printAll()
   {
      printColor();
      printName();
   }

   public void printColor ()
   {
      System.out.println("I'm a white whale");
   }

   public void printName()
   {
      System.out.println("I'm a cow");
   }
}

class Whale extends Cow
{
   public void printName()
   {
      System.out.println("I'm a whale");
   }
}
public static void main(String[] args)
{
   Whale whale = new Whale ();
   whale.printAll();
}
La sortie d'écran sera :
I'm a white whale
I'm a whale

Notez que lorsque la printAll()méthode de la Cowclasse est appelée sur un Whaleobjet, la printNameméthode de laWhale classe est utilisée, pas celle de la Cowméthode.

L'essentiel n'est pas la classe dans laquelle la méthode est écrite, mais plutôt le type (classe) de l'objet sur lequel la méthode est appelée.

Seules les méthodes non statiques peuvent être héritées et remplacées. Les méthodes statiques ne sont pas héritées et ne peuvent donc pas être remplacées.

Voici à quoi Whaleressemble la classe après l'application de l'héritage et du remplacement de méthode :

class Whale
{
   public void printAll()
   {
      printColor();
      printName();
   }

   public void printColor()
   {
      System.out.println("I'm a white whale");
   }

   public void printName()
   {
      System.out.println("I'm a whale");
   }
}
Voici à quoi Whaleressemble la classe après l'application de l'héritage et de la substitution de méthode : Nous ne connaissons aucune ancienne printNameméthode.

2. Transtypage

Il y a un point encore plus intéressant ici. Parce qu'une classe hérite de toutes les méthodes et données de sa classe parent, une référence à un objet de la classe enfant peut être stockée dans (assignée à) des variables dont le type est le même que la classe parent (et le parent du parent, etc. — jusqu'à la Objectclasse). Exemple:

Code Description
public static void main(String[] args)
{
   Whale whale = new Whale();
   whale.printColor();
}
La sortie d'écran sera :
I'm a white whale
public static void main(String[] args)
{
   Cow cow = new Whale();
   cow.printColor();
}
La sortie d'écran sera :
I'm a white whale
public static void main(String[] args)
{
   Object o = new Whale();
   System.out.println(o.toString());
}
La sortie d'écran sera :
Whale@da435a.

La toString()méthode est héritée de la Objectclasse

C'est une propriété très précieuse : un peu plus tard, vous comprendrez comment l'utiliser en pratique.


3. Appel d'une méthode sur un objet

Lorsqu'une méthode est appelée sur une variable, la méthode est en fait appelée sur un objet. Ce mécanisme est appelé répartition dynamique des méthodes.

Voici à quoi ça ressemble :

Code Description
public static void main(String[] args)
{
   Whale whale = new Whale();
   whale.printName();
}
La sortie d'écran sera :
I'm a whale
public static void main(String[] args)
{
   Cow cow = new Whale();
   cow.printName();
}
La sortie d'écran sera :
I'm a whale

Notez que l'implémentation spécifique de la printName()méthode qui est appelée — celle de Cowou celle de la Whaleclasse — n'est pas déterminée par le type de la variable, mais par le type de l'objet auquel la variable fait référence.

La Cowvariable stocke une référence à un Whaleobjet, et la printName()méthode définie dans la Whaleclasse est ce qui est appelé.

Ce n'est pas très évident. Rappelez-vous la règle principale :

L'ensemble des méthodes disponibles pour être appelées sur une variable est déterminé par le type de la variable. Et l'implémentation de méthode spécifique qui est appelée est déterminée par le type/classe de l'objet référencé par la variable.

Vous rencontrerez cela tout le temps, donc plus tôt vous vous en souviendrez, mieux ce sera.