Menu
Coddy logo textTech

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!")
end

Dé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.

challenge icon

Défi

Facile

Construisons 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 de makes 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 de meows: 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 de moos: 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 :

  1. Le nom du chat
  2. 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!")
end

Utilisation 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
quiz iconTestez-vous

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