Passer au contenu principal
eLearner.app
Module 3 · Leçon 2 sur 26/14 dans le cours~15 min
Leçons du module (2/2)

Polymorphisme et Classes Abstraites

Le polymorphisme et les classes abstraites sont des concepts avancés de la programmation orientée objet qui permettent d'écrire du code flexible, extensible et indépendant des implémentations spécifiques.

Le Polymorphisme

Le terme polymorphisme (plusieurs formes) fait référence à la capacité de traiter des objets de différentes classes comme s'ils appartenaient à un type commun. En Java, une variable de type superclasse peut stocker une référence à un objet de n'importe quelle sous-classe.

Code
class Animal {
    public void makeSound() {
        System.out.println("Verso...");
    }
}

class Dog extends Animal {
    public void makeSound() {
        System.out.println("Woof");
    }
}

class Cat extends Animal {
    public void makeSound() {
        System.out.println("Miao");
    }
}

Grâce au polymorphisme, nous pouvons faire ceci :

Code
Animal myAnimal1 = new Dog(); // Polimorfismo
Animal myAnimal2 = new Cat(); // Polimorfismo

myAnimal1.makeSound(); // Esegue il metodo di Dog (Woof)
myAnimal2.makeSound(); // Esegue il metodo di Cat (Miao)

La décision de quelle méthode invoquer se fait au moment de l'exécution (Late Binding ou dynamic dispatch) en fonction de l'objet réel et non du type de la variable de référence.

Classes Abstraites (abstract)

Une classe abstraite est une classe marquée du mot-clé abstract qui ne peut pas être instanciée directement (vous ne pouvez pas faire new MyAbstractClass()). Elle sert de "modèle partiel" pour d'autres classes.

Méthodes Abstraites

Une classe abstraite peut contenir des méthodes abstraites : des méthodes déclarées sans corps (sans accolades et sans code), se terminant par un point-virgule. Les sous-classes non abstraites sont obligées d'implémenter toutes les méthodes abstraites héritées.

Code
abstract class Shape {
    String color;

    // Metodo astratto (senza corpo)
    public abstract double getArea();
}

class Circle extends Shape {
    double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    // Obbligatorio implementare getArea
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

Dynamic Binding / Late Binding

Comment Java sait-il quelle méthode exécuter au moment de l'exécution ? Ce processus est connu sous le nom de Late Binding (ou Dynamic Binding). Contrairement à la surcharge (résolue au moment de la compilation), le compilateur ne sait pas quelle méthode spécifique sera exécutée. À la place, il génère une instruction d'appel générique. Au moment de l'exécution, la Java Virtual Machine (JVM) examine l'objet réel en mémoire et invoque l'implémentation de la méthode définie dans la classe de cet objet.

Classes Abstraites et Absence d'Implémentation

Si une sous-classe hérite d'une classe abstraite, elle a deux options :

  1. Implémenter toutes les méthodes abstraites : dans ce cas, la classe peut être une classe normale (concrète) et être instanciée.
  2. Se déclarer abstraite : si la sous-classe ne fournit pas d'implémentation pour toutes les méthodes abstraites héritées, elle doit à son tour être déclarée avec le mot-clé abstract.
Code
abstract class Animal {
    public abstract void makeSound();
}

// Questa classe DEVE essere astratta perché non implementa makeSound()
abstract class Canine extends Animal {
    // Eredita makeSound() ma non lo implementa
}

À toi de jouer

Exercice#java.m3.l2.e1
Tentatives : 0Chargement…

Déclarez une variable s de type Shape et attribuez-lui un nouvel objet Circle en utilisant le polymorphisme.

Chargement de l'éditeur…
Afficher l'indice

Écrivez `Shape s = new Circle();` pour utiliser le type de base comme type de référence.

Solution disponible après 3 tentatives

Exercice#java.m3.l2.e2
Tentatives : 0Chargement…

Rendez la classe Shape abstraite et ajoutez la méthode abstraite double getArea(). Complétez ensuite Square pour qu'elle étende Shape et implémente getArea() en retournant side * side.

Chargement de l'éditeur…
Afficher l'indice

Déclarez `public abstract double getArea();` dans Shape. Dans Square, ajoutez `@Override public double getArea() { return side * side; }`.

Solution disponible après 3 tentatives

Exercice#java.m3.l2.e3
Tentatives : 0Chargement…

Déclarez dans le main un tableau de type Shape[] contenant un objet Circle avec un rayon de 2.0 et un objet Square avec un côté de 3.0. Ensuite, utilisez une boucle (for ou for-each) pour afficher dans la console l'aire de chaque forme en appelant la méthode getArea().

Chargement de l'éditeur…
Afficher l'indice

Déclarez le tableau avec `Shape[] shapes = { new Circle(2.0), new Square(3.0) };` et parcourez-le avec une boucle `for (Shape s : shapes)` en affichant `s.getArea()`.

Solution disponible après 3 tentatives