Redéfinition de méthode (@Override)
Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy — leçon 22 sur 87.
La redéfinition de méthode permet à une sous-classe de fournir sa propre implémentation d'une méthode qui est déjà définie dans sa classe parente. C'est ainsi que les classes enfants personnalisent le comportement hérité pour répondre à leurs besoins spécifiques.
Lorsque vous redéfinissez une méthode, la version de la sous-classe remplace complètement la version du parent pour les objets de cette sous-classe. La méthode doit avoir le même nom, le même type de retour et les mêmes paramètres que la méthode parente :
public class Animal {
public void makeSound() {
System.out.println("Some generic sound");
}
}
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Woof!");
}
}
public class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Meow!");
}
}L'annotation @Override indique au compilateur que vous avez l'intention de redéfinir une méthode parente. Bien qu'elle soit facultative, elle est fortement recommandée car le compilateur détectera les erreurs si vous orthographiez mal le nom de la méthode par accident ou si vous utilisez les mauvais paramètres :
@Override
public void makeSound() { } // Correct - le compilateur vérifie ceci
public void makesound() { } // Faute de frappe ! Crée une nouvelle méthode au lieu de la redéfinirLorsque vous appelez une méthode redéfinie, Java exécute la version qui appartient au type d'objet réel :
Dog dog = new Dog();
dog.makeSound(); // Résultat : Woof!
Cat cat = new Cat();
cat.makeSound(); // Résultat : Meow!Rappelez-vous de la leçon précédente que vous pouvez utiliser super.methodName() à l'intérieur d'une méthode redéfinie si vous souhaitez toujours inclure le comportement du parent en plus de votre nouveau code.
Défi
FacileConstruisons un système de notification qui démontre comment les sous-classes peuvent surcharger les méthodes parentes pour fournir leur propre comportement spécialisé. Vous verrez comment l'annotation @Override aide à détecter les erreurs et comment chaque sous-classe peut personnaliser les méthodes héritées.
Vous allez créer trois fichiers pour organiser votre code :
Notification.java: Créez la classe parente qui représente une notification générique. Elle doit avoir :- Un champ privé pour le
message(String) - Un constructeur qui accepte le message
- Une méthode
getMessage()qui retourne le message - Une méthode
send()qui affiche :Sending notification: [message]
- Un champ privé pour le
EmailNotification.java: Créez une sous-classe qui étend Notification et personnalise la manière dont les notifications sont envoyées par e-mail :- Un champ privé pour l'adresse e-mail du
recipient(String) - Un constructeur qui prend à la fois le message et le destinataire, en utilisant
super(message)pour la partie parente - Surchargez la méthode
send()en utilisant l'annotation@Overridepour afficher :Emailing [recipient]: [message]
- Un champ privé pour l'adresse e-mail du
Main.java: Démontrez comment le même nom de méthode produit un comportement différent selon le type d'objet. Vous recevrez deux entrées : un message et une adresse e-mail. Créez à la fois une Notification régulière et une EmailNotification avec le même message, puis appelezsend()sur chacune pour voir les différentes sorties.
Vous recevrez deux entrées : le message (String) et l'adresse e-mail du destinataire (String).
Votre sortie doit afficher deux lignes - la première provenant de la méthode send() du parent, puis de la version surchargée dans EmailNotification. Cela démontre comment la surcharge de méthode permet aux sous-classes de remplacer le comportement hérité par leur propre implémentation.
Aide-mémoire
La redéfinition de méthode (method overriding) permet à une sous-classe de fournir sa propre implémentation d'une méthode déjà définie dans sa classe parente. La méthode redéfinie doit avoir le même nom, le même type de retour et les mêmes paramètres que la méthode parente.
public class Animal {
public void makeSound() {
System.out.println("Some generic sound");
}
}
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Woof!");
}
}L'annotation @Override est facultative mais fortement recommandée. Elle indique au compilateur que vous avez l'intention de redéfinir une méthode parente, ce qui aide à détecter des erreurs telles que des noms de méthodes mal orthographiés ou des paramètres incorrects :
@Override
public void makeSound() { } // Correct - le compilateur vérifie ceci
public void makesound() { } // Faute de frappe ! Crée une nouvelle méthode au lieu de la redéfinirLors de l'appel d'une méthode redéfinie, Java exécute la version qui appartient au type d'objet réel :
Dog dog = new Dog();
dog.makeSound(); // Output: Woof!
Cat cat = new Cat();
cat.makeSound(); // Output: Meow!Vous pouvez utiliser super.methodName() à l'intérieur d'une méthode redéfinie pour inclure le comportement du parent en plus de votre nouveau code.
Essayez vous-même
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Lire les entrées
String message = scanner.nextLine();
String recipient = scanner.nextLine();
// TODO: Créer un objet Notification avec le message
// TODO: Créer un objet EmailNotification avec le message et le destinataire
// TODO: Appeler send() sur l'objet Notification
// TODO: Appeler send() sur l'objet EmailNotification
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses vs ObjetsLe mot-clé thisMéthodesChamps (Attributs)Méthode constructeurSurcharge de constructeurRécapitulatif - Calculatrice simple4Héritage
Héritage de base (extends)Le mot-clé superRedéfinition de méthode (@Override)Chaînage de constructeursLa classe ObjectHéritage simple et multiniveauPourquoi pas d'héritage multiple de classesRécapitulatif - Hiérarchie des employés7Méthodes spéciales et classe Object
Méthode toString()equals() et hashCode()Méthode clone()compareTo() et ComparableInterface ComparatorRécapitulatif - Tri personnalisé2Modificateurs d'accès et Encapsulation
Aperçu des niveaux d'accèsMéthodes Getter et SetterMasquage d'informationsLe mot-clé finalRécapitulatif - Gestionnaire de compte bancaire5Polymorphisme
Bases de la surcharge de méthodesRedéfinition de méthodes (Run-Time)Upcasting et DowncastingL'opérateur instanceofClasses et méthodes abstraitesRécapitulatif - Calculateur de formes8Concepts avancés de la POO
Composition vs HéritageAgrégation vs CompositionClasses internes, imbriquées et anonymesEnums et méthodes d'EnumRecords (Java 16+)Classes scellées (Java 17+)11Patrons de conception, partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FabriquePatron MonteurPatron ObservateurPatron Stratégie3Propriétés de classe et membres statiques
Variables d'instance vs variables statiquesMéthodes statiquesBlocs statiquesConstantes (static final)Récapitulatif - Compteur et utilitaire6Interfaces et Classes Abstraites
Introduction aux InterfacesImplémentation d'InterfacesImplémentation d'Interfaces MultiplesDefault et Static dans les InterfacesClasses Abstraites vs InterfacesInterfaces FonctionnellesRécapitulatif - Système de Paiement9La généricité
Introduction à la généricitéClasses génériquesMéthodes génériquesParamètres de type bornésWildcards (?, extends, super)Récapitulatif - Conteneur générique12Patrons de conception, partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositePatron Itérateur