Polymorphisme, redéfinition, surcharge

Type déclaré et type réel, liaison dynamique, redéfinition d'une méthode héritée, surcharge par la signature, appel de super.méthode(), transtypage et test de type en Java.

  • 26 cartes
  • 4 thèmes
  • Gratuit

Le programme, thème par thème

Le poids de chaque thème suit celui que lui donne l'examen.

  1. Notions
  2. Questions
  3. Ranger et relier
  4. Mises en situation

Quelques cartes du deck

  • Polymorphisme : de quoi s'agit-il ?

    Voir la réponse

    Capacité d'un même appel de méthode à produire des comportements différents selon la classe réelle de l'objet qui le reçoit.

    Une boucle qui appelle crier() sur un tableau d'animaux n'a pas à savoir lesquels sont des chiens ou des chats : chaque objet répond à sa manière.

  • Qu'affiche cette boucle ?

    ```java
    class Animal {
    void crier() { System.out.println("..."); }
    }
    class Chien extends Animal {
    void crier() { System.out.println("Ouaf"); }
    }
    class Chat extends Animal {
    void crier() { System.out.println("Miaou"); }
    }

    Animal[] t = { new Chien(), new Chat(), new Animal() };
    for (Animal x : t) {
    x.crier();
    }
    `

    • Ouaf, Miaou, ...
    • ..., ..., ...
    • Ouaf, Ouaf, ...
    • Miaou, Ouaf, ...
    Voir la réponse

    Ouaf, Miaou, ...

    La variable x est toujours de type Animal, mais l'appel est résolu à l'exécution selon l'objet réel : Chien, puis Chat, puis Animal.

  • Une méthode redéfinie garde la même … que la méthode héritée ; l'annotation … fait vérifier cette règle par le compilateur.

    Voir la réponse

    Une méthode redéfinie garde la même signature que la méthode héritée ; l'annotation @Override fait vérifier cette règle par le compilateur.

    Sans l'annotation, une faute de frappe dans un type de paramètre crée en silence une nouvelle méthode. Avec elle, l'erreur est signalée : method does not override or implement a method from a supertype.

  • Redéfinition : de quoi s'agit-il ?

    Voir la réponse

    Réécriture, dans une sous-classe, d'une méthode héritée avec la même signature, pour en changer le comportement.

    Les paramètres doivent être identiques, sinon on écrit une autre méthode. L'annotation @Override fait vérifier ce point par le compilateur.

  • Ce programme compile, mais l.contains(new Point(1)) affiche false alors que la liste contient un point d'abscisse 1. Pourquoi ?

    ```java
    class Point {
    int x;
    Point(int x) { this.x = x; }
    public boolean equals(Point p) { return p.x == x; }
    }

    List<Point> l = new ArrayList<>();
    l.add(new Point(1));
    System.out.println(l.contains(new Point(1)));
    `

    • contains compare les références avec == et n'appelle jamais equals
    • equals(Point) surcharge equals(Object) sans la redéfinir
    • Il manque hashCode, que contains consulte avant equals
    • Il faudrait déclarer l'attribut x en private
    Voir la réponse

    equals(Point) surcharge equals(Object) sans la redéfinir

    contains appelle equals(Object). Ici la méthode écrite prend un Point : c'est une autre signature, donc une surcharge ignorée. Avec @Override, le compilateur l'aurait refusée ; la bonne écriture prend un Object. Une ArrayList ne consulte pas hashCode, seules les tables de hachage le font.