Configurare l'ereditarietà
Fa parte della sezione Programmazione orientata agli oggetti del percorso Lua di Coddy. Lezione 31 di 70.
Finora hai creato classi in cui ogni oggetto cerca i metodi in un'unica tabella prototipo. Ma cosa succede se vuoi che una classe si basi su un'altra? È qui che entra in gioco l'ereditarietà: una classe figlia può accedere a tutto ciò che proviene da una classe genitore, aggiungendo al contempo le proprie funzionalità.
L'intuizione fondamentale è che una tabella di classe può avere a sua volta un metatable. Quando Lua non riesce a trovare qualcosa nella classe figlia, lo cerca in __index del metatable della classe figlia, che punta alla classe genitore.
-- Classe genitore
local Animal = {}
Animal.__index = Animal
function Animal:new()
local obj = {}
setmetatable(obj, Animal)
return obj
end
function Animal:breathe()
print("Breathing...")
endOra ecco la configurazione dell’ereditarietà. Creiamo una classe figlia e impostiamo la sua metatable in modo che guardi alla classe genitore:
-- Classe figlia
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})Questa singola riga, setmetatable(Dog, {__index = Animal}), crea il collegamento di ereditarietà. Quando un'istanza di Dog chiama un metodo che non si trova in Dog, Lua controlla Animal.
La catena di ricerca funziona così: istanza → Dog → Animal. Ogni passaggio usa __index per trovare la tabella successiva in cui cercare. Questo permette alle classi figlie di ereditare automaticamente tutti i metodi della classe genitore senza copiarli.
Sfida
FacileCostruiamo la tua prima gerarchia di ereditarietà! Creerai una semplice relazione tra una classe genitore e una classe figlia, in cui una classe Machine funge da base e una classe Robot eredita da essa.
Organizzerai il codice in tre file:
Machine.lua: Definisci la classe genitore usando il modello standard per le classi. Includi un costruttore:new()e un metodo:status()che stampaMachine is operational. Non dimenticare di impostare__indexe di restituire la classe alla fine del file.Robot.lua: Definisci la classe figlia che eredita da Machine. Richiedi il modulo Machine, configura la tabella Robot con il proprio__indexe stabilisci il collegamento di ereditarietà usandosetmetatable(Robot, {__index = Machine}). Includi un costruttore:new()che crea un'istanza con Robot come metatabella.main.lua: Metti insieme tutto richiedendo il modulo Robot, creando un'istanza di Robot e chiamando il metodo ereditato:status().
Il concetto chiave è che la classe Robot non definisce autonomamente :status(). Eredita questo metodo da Machine attraverso la catena delle metatabelle. Quando chiami :status() su un'istanza di Robot, Lua cercherà prima in Robot; non trovandolo, seguirà il collegamento __index fino a Machine, dove troverà il metodo.
Il tuo output dovrebbe essere:
Machine is operationalQuesta singola riga dimostra che l'ereditarietà funziona. Robot è riuscito ad accedere a un metodo definito solo nella sua classe genitore!
Provalo tu
-- main.lua: Metti tutto insieme
-- TODO: Importa il modulo Robot
-- TODO: Crea un'istanza di Robot usando Robot:new()
-- TODO: Chiama il metodo ereditato :status() sulla tua istanza di robot
-- Questo dovrebbe stampare "Machine is operational"
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 deposito2Schema 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