Sovrascrivere i metodi
Fa parte della sezione Programmazione orientata agli oggetti del percorso Lua di Coddy. Lezione 37 di 70.
Finora, le classi figlie hanno ereditato i metodi delle classi genitore e ne hanno aggiunti di nuovi. Ma cosa succede se una classe figlia ha bisogno dello stesso nome di metodo con un comportamento diverso? Questo si chiama override del metodo.
Quando definisci un metodo in una classe figlia con lo stesso nome di uno nella classe genitore, la versione della classe figlia ha la precedenza. La catena di ricerca di Lua controlla prima la classe figlia e, se trova il metodo lì, smette di cercare.
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 ridefinisce 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!")
endOra ogni classe risponde in modo diverso alla stessa chiamata di metodo:
local generic = Animal:new("Creature")
local buddy = Dog:new("Buddy")
generic:speak() -- Output: Creature emette un suono
buddy:speak() -- Output: Buddy abbaia: Woof!:speak() del cane sostituisce completamente la versione della classe genitore per le istanze di Dog. Questo ti permette di creare comportamenti specializzati mantenendo un’interfaccia coerente: ogni animale può :speak(), ma ogni specie lo fa in modo diverso.
Sfida
FacileCreiamo un piccolo regno animale in cui creature diverse parlano a modo loro! Creerai una classe genitore Animal e due classi figlie, Cat e Cow, che sovrascrivono ciascuna il metodo :speak() della classe genitore con un comportamento specifico.
Organizzerai il codice in quattro file:
Animal.lua: la classe base con un costruttore:new(name)che memorizza il nome dell'animale. Includi un metodo:speak()che stampa il nome dell'animale seguito damakes a sound. Questo è il comportamento predefinito che le classi figlie sovrascriveranno.Cat.lua: una classe figlia che eredita da Animal. Il suo costruttore:new(name)deve chiamare il costruttore genitore e poi ricollegare la metatabella a Cat. Sovrascrivi il metodo:speak()in modo che i gatti dicano qualcosa di diverso: stampa il nome del gatto seguito dameows: Meow!Cow.lua: un'altra classe figlia che eredita da Animal. Configura il costruttore come per Cat. Sovrascrivi:speak()in modo che le mucche stampino il loro nome seguito damoos: Moo!main.lua: metti tutto insieme! Leggi due nomi dall'input, crea un Cat con il primo nome e una Cow con il secondo, poi chiama:speak()su ciascuno per dimostrare che lo stesso nome di metodo produce un output diverso a seconda della classe.
Riceverai due input:
- Il nome del gatto
- Il nome della mucca
Nel file principale, crea entrambi gli animali e chiama :speak() prima sul gatto, poi sulla mucca.
Per esempio, se gli input sono Whiskers e Bessie, l'output dovrebbe essere:
Whiskers meows: Meow!
Bessie moos: Moo!Nota come entrambi gli animali rispondano alla stessa chiamata del metodo :speak(), ma ciascuno produca un output specifico per il proprio tipo. La versione di Cat sostituisce completamente il comportamento generico del genitore "makes a sound", e lo stesso fa quella di Cow. Questo è il funzionamento dell'override dei metodi: stessa interfaccia, implementazioni diverse!
Provalo tu
-- main.lua: Metti tutto insieme
local Cat = require('Cat')
local Cow = require('Cow')
-- Leggi l'input
local catName = io.read()
local cowName = io.read()
-- TODO: Crea un Cat con il primo nome
-- TODO: Crea un Cow con il secondo nome
-- TODO: Chiama :speak() prima sul gatto, poi sulla mucca
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Il concetto di «self»
Tabelle con funzioni«self» esplicitoLa sintassi dei due puntiPunto o due puntiRiepilogo - Spostare il punto4Progetto: Banca digitale
Configurazione del progettoMetodo di deposito7Polimorfismo e sovrascrittura
Sovrascrivere i metodiChiamare i metodi della classe genitoreDuck TypingInterfaccia comuneVerificare il tipoRiepilogo - Ruoli dei dipendenti2Schema del prototipo di classe
Il concetto di prototipoCollegare con __indexIl costruttore :new()Inizializzare gli attributiIstanze indipendentiRiepilogo - Fabbrica di auto5Sovraccarico degli operatori nella OOP
Sommare oggettiSottrarre oggettiConcatenare oggettiConfrontare oggetti (<, >)Ripasso - Calcoli con il portafoglio8Incapsulamento
Convenzioni di denominazioneClosure per la privacyAccesso tramite closureTabelle di sola letturaLogica di convalidaRiepilogo - Cassaforte sicura11Modelli di progettazione (base)
Funzioni factoryTabella singletonPattern IteratorObserver (listener)Riepilogo - Factory per logger3Stato e comportamento degli oggetti
Variabili di istanzaMetodi getterMetodi setterProprietà calcolateFormattazione delle stringheControlli di uguaglianzaRiepilogo - Voto dello studente6Fondamenti dell'ereditarietà
Configurare l'ereditarietàEreditare i metodiEstendere il costruttoreAggiungere metodi alla classe figliaCondiviso vs specificoRiepilogo - Gerarchia delle formeEsercitati da solo: Compilatore Lua online