Menu
Coddy logo textTech

Relazione Has-A

Fa parte della sezione Programmazione orientata agli oggetti del percorso Lua di Coddy. Lezione 49 di 70.

Durante tutto il corso, hai usato l’ereditarietà per condividere il comportamento tra classi: un Dog “è un” Animal. Ma l’ereditarietà non è sempre lo strumento giusto.

A volte, gli oggetti non condividono un albero genealogico; invece, un oggetto semplicemente contiene un altro. Questo si chiama composizione e modella una relazione «ha-un».

Considera un'auto. Un'auto non è un tipo di motore. Ha un motore. Il motore è un oggetto separato che si trova all'interno dell'auto:

local Engine = {}
Engine.__index = Engine

function Engine:new(horsepower)
    local obj = {horsepower = horsepower}
    setmetatable(obj, Engine)
    return obj
end

local Car = {}
Car.__index = Car

function Car:new(model, engine)
    local obj = {
        model = model,
        engine = engine  -- Memorizza l'oggetto Engine all'interno di Car
    }
    setmetatable(obj, Car)
    return obj
end

Quando crei un'auto, passi un oggetto motore esistente al suo costruttore:

local myEngine = Engine:new(200)
local myCar = Car:new("Sedan", myEngine)

print(myCar.engine.horsepower)  -- 200

L’auto non eredita dal motore. Ne mantiene semplicemente un riferimento. Questo mantiene indipendenti entrambe le classi. Potresti sostituirlo con un motore diverso o usare la stessa classe Motore in una motocicletta.

La composizione ti dà una flessibilità che l’ereditarietà non può offrire: assembli oggetti a partire da componenti invece di vincolarli a una rigida gerarchia di famiglie.

challenge icon

Sfida

Facile

Costruiamo un sistema informatico usando la composizione! Invece dell'ereditarietà, creerai un Computer che ha una CPU al suo interno: dimostrando la relazione "has-a".

Organizzerai il codice in tre file:

  • CPU.lua: Crea una classe CPU con un costruttore :new(brand, speed) che memorizza il nome del produttore e la velocità in GHz. Includi un metodo :getInfo() che restituisce una stringa nel formato: {brand} @ {speed}GHz
  • Computer.lua: Crea una classe Computer il cui costruttore :new(model, cpu) accetta il nome di un modello e un oggetto CPU. Computer memorizza al suo interno l'oggetto CPU (composizione!). Includi un metodo :describe() che stampa il modello del computer e le informazioni della sua CPU.
  • main.lua: Mettiamo tutto insieme! Leggi gli input per il produttore della CPU, la velocità della CPU e il modello del computer. Crea prima un oggetto CPU, poi passalo al costruttore di Computer. Infine, chiama il metodo :describe() del computer.

Riceverai tre input:

  1. Il produttore della CPU (una stringa)
  2. La velocità della CPU in GHz (un numero)
  3. Il nome del modello del computer (una stringa)

L'output dovrebbe mostrare la descrizione del computer, che include le informazioni della CPU contenuta al suo interno:

Model: {model}
CPU: {brand} @ {speed}GHz

Per esempio, se gli input sono Intel, 3.5 e WorkStation, l'output dovrebbe essere:

Model: WorkStation
CPU: Intel @ 3.5GHz

Nota che Computer non eredita da CPU. Semplicemente conserva un riferimento a una CPU. Il metodo :describe() di Computer accede ai dati della CPU tramite l'oggetto memorizzato, mostrando come la composizione consenta di costruire oggetti complessi a partire da parti più semplici!

Provalo tu

-- main.lua
-- Metti insieme tutti gli elementi usando la composizione

local CPU = require('CPU')
local Computer = require('Computer')

-- Leggi gli input
local cpuBrand = io.read()
local cpuSpeed = tonumber(io.read())
local computerModel = io.read()

-- TODO: Crea un oggetto CPU con la marca e la velocità

-- TODO: Crea un oggetto Computer con il modello e l'oggetto CPU

-- TODO: Chiama il metodo describe() del computer per stampare l'output
quiz iconMettiti alla prova

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

Esercitati da solo: Compilatore Lua online