Luokat metataulukoilla
Simuloikaa luokkia taulukoilla ja käyttäkää __index-kenttää metodien hakuun.
Luokat metataulukoilla on ilmainen Lua Academy-oppitunti CoddyKitissä. Tämä on oppitunti 1/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Lua Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Lua Academy-kurssilla on yhteensä 4 oppituntia.
Luokkataulumalli
Luokka on Luassa yksinkertaisesti taulukko, joka tallentaa metodit. Instanssit ovat taulukoita, joiden metataulun __index osoittaa luokkataulukkoon. Näin kaikki metodit ovat instanssien käytettävissä hakuketjun kautta.
local Animal = {}
Animal.__index = Animal
function Animal.new(name, sound)
return setmetatable({name=name, sound=sound}, Animal)
end
function Animal:speak()
print(self.name .. " says " .. self.sound)
end
local dog = Animal.new("Rex","Woof")
dog:speak() -- Rex says Woof__index osoittaa luokkaan
Asettamalla ClassName.__index = ClassName ilmoitetaan, että "puuttuvia avaimia haetaan luokkataulukosta". Kun instanssimetodia kutsutaan, Lua ei löydä sitä instanssista, tarkistaa metataulun (__index), löytää luokan ja hakee metodin sieltä.
local Point = {}
Point.__index = Point
Point.type = "2D Point"
function Point.new(x,y)
return setmetatable({x=x,y=y}, Point)
end
function Point:magnitude()
return math.sqrt(self.x^2 + self.y^2)
end
local p = Point.new(3,4)
print(p:magnitude()) -- 5.0
print(p.type) -- 2D Point (from class)Rakentajamalli
new()-funktio on rakentaja: se luo taulukon, jossa on instanssin tiedot, ja palauttaa sen metatauluun käärittynä niin, että metataulu osoittaa luokkaan. Tämä on Luan vakiotapa luoda olioita.
local Circle = {}
Circle.__index = Circle
function Circle.new(cx, cy, radius)
assert(radius > 0, "radius must be positive")
return setmetatable({cx=cx, cy=cy, r=radius}, Circle)
end
function Circle:area()
return math.pi * self.r^2
end
function Circle:perimeter()
return 2 * math.pi * self.r
end
local c = Circle.new(0, 0, 5)
print(string.format("Area: %.2f", c:area()))Metodin ja funktion syntaksi
obj:method() on syntaktinen lyhennys muodolle obj.method(obj). Määritelkää metodit kaksoispistesyntaksilla (function Cls:method()), jotta saatte implisiittisen self-parametrin. Kutsukaa metodia kaksoispisteellä, jotta instanssi välitetään sille. Pisteen ja kaksoispisteen sekoittaminen aiheuttaa vaikeasti havaittavia virheitä.
local Dog = {}
Dog.__index = Dog
-- Define with colon: self is implicit
function Dog:bark(times)
for i = 1, (times or 1) do
print(self.name .. ": Woof!")
end
end
function Dog.new(name)
return setmetatable({name=name}, Dog)
end
local d = Dog.new("Buddy")
d:bark(2) -- Buddy: Woof! (x2)
-- Dog.bark(d,1) -- same thing, explicit selfLuokkatasoiset ja instanssitasoiset kentät
Luokkataulukon kentät ovat kaikkien instanssien jakamia (luokkamuuttujia). Instanssitaulukon kentät ovat instanssikohtaisia. Instanssi voi peittää luokan kentän luomalla oman samannimisen kentän.
local Entity = {}
Entity.__index = Entity
Entity.count = 0 -- class-level counter
function Entity.new(name)
Entity.count = Entity.count + 1
return setmetatable({name=name, id=Entity.count}, Entity)
end
local a = Entity.new("alpha")
local b = Entity.new("beta")
local c = Entity.new("gamma")
print(Entity.count) -- 3
print(a.id, b.id, c.id) -- 1 2 3tostring luokille
Lisätkää luokkataulukkoon __tostring, jotta tulosteen esitysmuoto olisi luettava. Koska instanssin metataulu on luokka ja luokalla on __tostring, kaikki instanssit käyttävät sitä automaattisesti.
local Vec2 = {}
Vec2.__index = Vec2
Vec2.__tostring = function(v)
return string.format("Vec2(%g, %g)", v.x, v.y)
end
function Vec2.new(x,y)
return setmetatable({x=x,y=y}, Vec2)
end
function Vec2.__add(a, b)
return Vec2.new(a.x+b.x, a.y+b.y)
end
local v1 = Vec2.new(1,2)
local v2 = Vec2.new(3,4)
print(v1+v2) -- Vec2(4, 6)Instanssin tyypin tarkistaminen
Tarkistakaa, onko olio luokan instanssi, vertaamalla sen metataulua luokkataulukkoon. Tämä vastaa Luan instanceof-toimintoa.
local Dog = {}
Dog.__index = Dog
function Dog.new(name)
return setmetatable({name=name}, Dog)
end
local function isDog(obj)
return getmetatable(obj) == Dog
end
local d = Dog.new("Rex")
local t = {}
print(isDog(d)) -- true
print(isDog(t)) -- falseYksityiset metodit
Yksityiset metodit ovat moduulitiedoston paikallisia funktioita. Niitä ei voi kutsua moduulin ulkopuolelta, mutta moduulin julkiset metodit voivat käyttää niitä upvalue-arvoina.
local Account = {}
Account.__index = Account
-- Private helper
local function validate(amount)
return type(amount)=="number" and amount > 0
end
function Account.new(balance)
return setmetatable({balance=balance or 0}, Account)
end
function Account:deposit(amount)
assert(validate(amount), "invalid amount")
self.balance = self.balance + amount
end
function Account:getBalance() return self.balance endLuokkien vertailu
Ylikuormittakaa __eq ja __lt mukautettua yhtäsuuruus- ja järjestysvertailua varten. Lua kutsuu __eq-metamethodia taulukoille vain, kun molemmilla operandeilla on sama metataulu.
local Temp = {}
Temp.__index = Temp
Temp.__eq = function(a,b) return a.celsius == b.celsius end
Temp.__lt = function(a,b) return a.celsius < b.celsius end
Temp.__tostring = function(t)
return t.celsius.."°C"
end
function Temp.new(c)
return setmetatable({celsius=c}, Temp)
end
local t1 = Temp.new(100)
local t2 = Temp.new(0)
print(t1 == Temp.new(100)) -- true
print(t2 < t1) -- trueUseita luokkia
Kukin luokka on itsenäinen taulukko, jolla on oma metataulunsa. Eri luokkien oliolla on eri metataulut. Tämä muodostaa Lualla toteutetun moniluokkaisen olio-ohjelmointijärjestelmän perustan.
local Cat = {}
Cat.__index = Cat
function Cat.new(name) return setmetatable({name=name,lives=9},Cat) end
function Cat:loseLife() self.lives=self.lives-1; return self.lives end
local Dog2 = {}
Dog2.__index = Dog2
function Dog2.new(name) return setmetatable({name=name,tricks={}},Dog2) end
function Dog2:learn(t) self.tricks[#self.tricks+1]=t end
local c = Cat.new("Whiskers")
local d = Dog2.new("Buddy")
d:learn("sit"); d:learn("stay")
print(c:loseLife(), #d.tricks) -- 8 2Pikatarkistus
Miksi asetamme ClassName.__index = ClassName?
Kertaus: luokat metataulujen avulla
Yhteenveto:
- Luokka = taulukko +
__index = self - Rakentaja:
function Cls.new(...) return setmetatable({}, Cls) end - Metodit: määritellään luokkataulukossa ja kutsutaan kaksoispistesyntaksilla
- Luokan ja instanssin kentät: luokan kentät jaetaan, instanssin kentät ovat oliokohtaisia
- Tyypin tarkistus:
getmetatable(obj) == Cls
Opi Lua tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 40
- Oppitunnit
- 159
Usein kysytyt kysymykset
Onko oppitunti ”Luokat metataulukoilla” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Lua Academy-oppimispolun 3 oppituntia, myös oppitunnin “Luokat metataulukoilla”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Lua Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Luokat metataulukoilla”?
Simuloikaa luokkia taulukoilla ja käyttäkää __index-kenttää metodien hakuun. Harjoittelet Lua Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Lua Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Lua Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/4.
Kuinka kauan ”Luokat metataulukoilla”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Lua Academy-oppitunnilla?
Kyllä. Jokainen Lua Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Luokat metataulukoilla
- Rakentajat ja new()
- Instanssimetodit ja self
- Kapselointi sulkeumilla