Redéfinition de méthodes
Fait partie de la section Object Oriented Programming du Journey Lua de Coddy — leçon 37 sur 70.
Jusqu'à présent, les classes enfants ont hérité des méthodes parentes et en ont ajouté de nouvelles. Mais que se passe-t-il si un enfant a besoin du même nom de méthode avec un comportement différent ? C'est ce qu'on appelle la redéfinition de méthode (ou method overriding).
Lorsque vous définissez une méthode dans une classe enfant avec le même nom qu'une méthode de la classe parente, la version de l'enfant est prioritaire. La chaîne de recherche de Lua vérifie d'abord la classe enfant — si elle y trouve la méthode, elle arrête de chercher.
local Animal = {}
Animal.__index = Animal
function Animal:new(name)
local obj = {name = name}
setmetatable(obj, Animal)
return obj
end
function Animal:speak()
print(self.name .. " makes a sound")
end
-- Dog redéfinit speak()
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new(name)
local obj = Animal.new(Animal, name)
setmetatable(obj, Dog)
return obj
end
function Dog:speak()
print(self.name .. " barks: Woof!")
endDésormais, chaque classe répond différemment au même appel de méthode :
local generic = Animal:new("Creature")
local buddy = Dog:new("Buddy")
generic:speak() -- Résultat : Creature makes a sound
buddy:speak() -- Résultat : Buddy barks: Woof!Le :speak() de Dog remplace complètement la version du parent pour les instances de Dog. Cela vous permet de créer un comportement spécialisé tout en conservant une interface cohérente — chaque animal peut :speak(), mais chaque espèce le fait différemment.
Défi
FacileConstruisons un petit royaume animal où différentes créatures s'expriment de manière unique ! Vous allez créer une classe parente Animal et deux classes enfants — Cat et Cow — qui surchargent chacune la méthode :speak() du parent avec leur propre comportement spécialisé.
Vous organiserez votre code sur quatre fichiers :
Animal.lua: Votre classe de base avec un constructeur:new(name)qui stocke le nom de l'animal. Incluez une méthode:speak()qui affiche le nom de l'animal suivi demakes a sound. C'est le comportement par défaut que les classes enfants surchargeront.Cat.lua: Une classe enfant qui hérite d'Animal. Son constructeur:new(name)doit appeler le constructeur parent, puis lier à nouveau la métatable à Cat. Surchargez la méthode:speak()pour que les chats disent quelque chose de différent — affichez le nom du chat suivi demeows: Meow!Cow.lua: Une autre classe enfant héritant d'Animal. Configurez le constructeur de la même manière que pour Cat. Surchargez:speak()pour que les vaches affichent leur nom suivi demoos: Moo!main.lua: Rassemblez le tout ! Lisez deux noms à partir de l'entrée, créez un Cat avec le premier nom et une Cow avec le second nom, puis appelez:speak()sur chacun pour démontrer que le même nom de méthode produit un résultat différent selon la classe.
Vous recevrez deux entrées :
- Le nom du chat
- Le nom de la vache
Dans votre fichier principal, créez les deux animaux et appelez :speak() sur le chat en premier, puis sur la vache.
Par exemple, si les entrées sont Whiskers et Bessie, la sortie devrait être :
Whiskers meows: Meow!
Bessie moos: Moo!Remarquez comment les deux animaux répondent au même appel de méthode :speak(), mais chacun produit une sortie spécifique à son type. La version du Cat remplace complètement le comportement générique "makes a sound" du parent, tout comme celle de la Cow. C'est la surcharge de méthode en action — même interface, différentes implémentations !
Aide-mémoire
La redéfinition de méthode (method overriding) permet à une classe enfant de définir une méthode avec le même nom qu'une méthode parente, remplaçant ainsi le comportement du parent par une fonctionnalité spécialisée.
Lorsque Lua recherche une méthode, il vérifie d'abord la classe enfant. S'il y trouve la méthode, il utilise cette version et arrête de chercher dans la classe parente.
Exemple de base de redéfinition de méthode :
local Animal = {}
Animal.__index = Animal
function Animal:new(name)
local obj = {name = name}
setmetatable(obj, Animal)
return obj
end
function Animal:speak()
print(self.name .. " makes a sound")
end
-- Dog redéfinit speak()
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new(name)
local obj = Animal.new(Animal, name)
setmetatable(obj, Dog)
return obj
end
function Dog:speak()
print(self.name .. " barks: Woof!")
endUtilisation de la méthode redéfinie :
local generic = Animal:new("Creature")
local buddy = Dog:new("Buddy")
generic:speak() -- Sortie : Creature makes a sound
buddy:speak() -- Sortie : Buddy barks: Woof!La méthode de la classe enfant remplace complètement la version du parent pour les instances de cette classe enfant, permettant un comportement spécialisé tout en maintenant une interface cohérente à travers toutes les classes.
Essayez vous-même
-- main.lua : Rassembler tous les éléments
local Cat = require('Cat')
local Cow = require('Cow')
-- Lire l'entrée
local catName = io.read()
local cowName = io.read()
-- TODO: Créer un Cat avec le premier nom
-- TODO: Créer une Cow avec le second nom
-- TODO: Appeler :speak() sur le cat d'abord, puis sur la cow
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Object Oriented Programming
1Le concept de « self »
Tables avec fonctions« self » expliciteLa syntaxe avec deux-pointsPoint vs deux-pointsRécapitulatif - Point mobile4Projet : Banque numérique
Configuration du projetMéthode de dépôt7Polymorphisme et Redéfinition
Redéfinition de méthodesAppeler des méthodes parentesDuck TypingInterface communeVérification du typeRécapitulatif - Rôles des employés10Projet : Gestionnaire de formes
Configuration du projetClasse Rectangle2Modèle de prototype de classe
Le concept de prototypeLiaison avec __indexLe constructeur :new()Initialisation des attributsInstances indépendantesRécapitulatif - Usine de voitures5Surcharge d'opérateurs en POO
Additionner des objetsSoustraire des objetsConcaténer des objetsComparer des objets (<, >)Récapitulatif - Calculs de portefeuille8Encapsulation
Conventions de nommageClosures pour la confidentialitéAccès via les ClosuresTables en lecture seuleLogique de validationRécapitulatif - Coffre-fort sécurisé11Patrons de conception (Lite)
Fonctions FactoryTable SingletonPatron IteratorObserver (Écouteur)Récapitulatif - Logger Factory3État et comportement des objets
Variables d'instanceMéthodes GetterMéthodes SetterPropriétés calculéesFormatage de chaînesVérifications d'égalitéRécapitulatif - Note de l'étudiant6Bases de l'héritage
Mise en place de l'héritageHériter des méthodesÉtendre le constructeurAjouter des méthodes enfantsPartagé vs UniqueRécapitulatif - Hiérarchie des formes