Metode Instans dan self
Definisikan metode menggunakan sintaks titik dua dan parameter implisit self.
Metode Instans dan self adalah pelajaran Lua Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Lua Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Lua Academy mencakup 4 pelajaran total.
self adalah Instans
Saat Anda memanggil obj:method(), Lua secara otomatis meneruskan obj sebagai argumen pertama. Berdasarkan konvensi, parameter ini diberi nama self. Melalui self, metode dapat mengakses data instans dan memanggil metode lain.
local Counter = {}
Counter.__index = Counter
function Counter.new(start)
return setmetatable({value=start or 0, step=1}, Counter)
end
function Counter:increment()
self.value = self.value + self.step
end
function Counter:getValue() return self.value end
local c = Counter.new(10)
c:increment(); c:increment()
print(c:getValue()) -- 12Perangkaian Metode
Kembalikan self dari metode agar pemanggilan dapat dirangkai: obj:method1():method2():method3(). Setiap pemanggilan mengembalikan objek yang sama sehingga memungkinkan gaya berantai. Cara ini paling cocok untuk metode yang mengubah keadaan.
local Builder = {}
Builder.__index = Builder
function Builder.new()
return setmetatable({parts={}},Builder)
end
function Builder:add(s) self.parts[#self.parts+1]=s; return self end
function Builder:addAll(t)
for _,v in ipairs(t) do self.parts[#self.parts+1]=v end
return self
end
function Builder:build() return table.concat(self.parts," ") end
local result = Builder.new()
:add("Hello")
:add("from")
:addAll({"Lua","OOP"})
:build()
print(result) -- Hello from Lua OOPMemanggil Metode Lain
Metode dapat memanggil metode lain pada instans yang sama melalui self:otherMethod(). Ini mendorong penggunaan ulang kode di dalam kelas. Pembantu privat dapat berupa fungsi lokal biasa yang menerima self secara eksplisit.
local Stack = {}
Stack.__index = Stack
function Stack.new() return setmetatable({_data={},_size=0},Stack) end
function Stack:push(v) self._size=self._size+1; self._data[self._size]=v end
function Stack:pop()
if self:isEmpty() then return nil end
local v=self._data[self._size]; self._data[self._size]=nil
self._size=self._size-1; return v
end
function Stack:peek()
return not self:isEmpty() and self._data[self._size] or nil
end
function Stack:isEmpty() return self._size==0 end
function Stack:size() return self._size end
local s=Stack.new(); s:push(1);s:push(2);s:push(3)
print(s:pop(),s:peek(),s:size()) -- 3 2 2Peringatan Penimpaan Metode
Menetapkan bidang instans dengan nama yang sama seperti metode kelas akan menyembunyikan metode tersebut untuk instans itu. Ini biasanya merupakan bug — berhati-hatilah ketika nama bidang instans dapat bertabrakan dengan nama metode.
local Dog = {}
Dog.__index = Dog
function Dog.new(n) return setmetatable({name=n},Dog) end
function Dog:speak() print(self.name..": Woof!") end
local d = Dog.new("Rex")
d:speak() -- Rex: Woof!
-- Accidental shadow:
d.speak = "loud" -- now d.speak is a string, not a function
local ok,err = pcall(function() d:speak() end)
print(ok, err) -- false attempt to call a string valueself dalam Panggilan Balik
Meneruskan metode sebagai panggilan balik akan menghilangkan self implisit. Bungkus metode tersebut dalam closure untuk menangkap self.
local Timer = {}
Timer.__index = Timer
function Timer.new(n) return setmetatable({count=n},Timer) end
function Timer:tick()
self.count=self.count-1
print("Ticking, count:", self.count)
end
local t = Timer.new(3)
-- Wrong: loses self
-- local cb = t.tick -- cb(t) works but cb() doesn't
-- Correct: closure captures self
local cb = function() t:tick() end
cb(); cb(); cb() -- Ticking 3 timesMetode Statis vs Metode Instans
Metode statis dipanggil pada kelas, bukan pada instans. Metode ini tidak memiliki self (atau menerima kelas sebagai self). Dalam Lua, tidak ada pembedaan formal — berdasarkan konvensi, gunakan . (bukan :) untuk metode statis.
local MathUtils = {}
MathUtils.__index = MathUtils
-- Static method (no instance needed)
function MathUtils.clamp(v, lo, hi)
return math.max(lo, math.min(hi, v))
end
-- Instance method (needs self)
function MathUtils:scale(factor)
self.value = self.value * factor
end
print(MathUtils.clamp(15, 0, 10)) -- 10
local m = setmetatable({value=5},MathUtils)
m:scale(3)
print(m.value) -- 15Metode Mixin
Tambahkan metode dari tabel mixin ke sebuah kelas tanpa pewarisan formal. Ini adalah komposisi datar: salin atau referensikan fungsi milik mixin ke dalam tabel kelas.
local Serializable = {}
function Serializable:serialize()
local parts={}
for k,v in pairs(self) do
if type(v)~="function" then
parts[#parts+1]=k.."="..tostring(v)
end
end
return "{"..table.concat(parts,",").."}"
end
local User = {}
User.__index = User
User.serialize = Serializable.serialize -- mixin!
function User.new(n,a) return setmetatable({name=n,age=a},User) end
local u = User.new("Alice",30)
print(u:serialize())Metode Abstrak
Lua tidak memaksakan metode abstrak, tetapi Anda dapat mendefinisikan metode kelas dasar yang menimbulkan galat sehingga subkelas harus menimpanya. Ini adalah konvensi untuk menandai metode yang "wajib ditimpa".
local Shape = {}
Shape.__index = Shape
function Shape.new() return setmetatable({},Shape) end
function Shape:area()
error(type(self).." must implement area()",2)
end
function Shape:describe()
print("Shape area:", self:area())
end
local sq={}
setmetatable(sq,{__index=Shape})
function sq:area() return 4*4 end
sq:describe() -- Shape area: 16Tabel Metode
Untuk kelas dengan banyak metode, kelompokkan metode berdasarkan fungsinya. Semua metode dalam tabel yang sama menggunakan pencarian metatabel yang sama, tetapi Anda dapat membaginya berdasarkan tanggung jawab menggunakan ruang nama turunan.
local Entity = {}
Entity.__index = Entity
Entity.Physics = {}
function Entity.Physics:applyForce(fx,fy)
self.vx=(self.vx or 0)+fx
self.vy=(self.vy or 0)+fy
end
Entity.Render = {}
function Entity.Render:draw()
print(string.format("Draw at (%g,%g)",self.x or 0,self.y or 0))
end
-- Mix into main class
for k,v in pairs(Entity.Physics) do Entity[k]=v end
for k,v in pairs(Entity.Render) do Entity[k]=v end
function Entity.new(x,y) return setmetatable({x=x,y=y},Entity) end
local e=Entity.new(10,20); e:draw(); e:applyForce(5,0); print(e.vx)Delegasi vs Pewarisan
Utamakan delegasi (menyimpan referensi) daripada rantai pewarisan yang dalam. Sebuah kelas dapat mendelegasikan tugas kepada objek lain alih-alih mewarisinya, sehingga keterikatan tetap rendah dan setiap kelas tetap berfokus.
local Logger = {}
Logger.__index = Logger
function Logger.new(name) return setmetatable({name=name},Logger) end
function Logger:log(msg) print("["..self.name.."] "..msg) end
local Service = {}
Service.__index = Service
function Service.new(name)
return setmetatable({
name=name,
logger=Logger.new(name) -- delegation
},Service)
end
function Service:start()
self.logger:log("starting...") -- delegate logging
print(self.name, "running")
end
Service.new("AuthService"):start()Pemeriksaan Cepat
Apa perbedaan antara obj:method() dan obj.method()?
Ringkasan: Metode Instans
Ringkasan:
- Sintaks pemanggilan dengan titik dua:
obj:method()==obj.method(obj) - Kembalikan self untuk perangkaian metode
- Panggil metode lain:
self:otherMethod() - Panggilan balik: bungkus dalam closure untuk mempertahankan self
- Metode statis: berdasarkan konvensi, gunakan notasi titik
- Gunakan delegasi daripada pewarisan mendalam untuk fleksibilitas
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Metode Instans dan self” gratis?
Ya — teks lengkap “Metode Instans dan self” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Lua Academy, upgrade ke CoddyKit PRO. Kursus Lua Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Metode Instans dan self”?
Definisikan metode menggunakan sintaks titik dua dan parameter implisit self. Kamu berlatih Lua Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Lua Academy?
Tidak diperlukan pengalaman sebelumnya. Lua Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “Metode Instans dan self” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Lua Academy ini?
Ya. Setiap pelajaran Lua Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Class melalui Metatabel
- Konstruktor dan new()
- Metode Instans dan self
- Enkapsulasi dengan Closure