0Pricing
Lua Academy · Pelajaran

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())  -- 12

Perangkaian 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 OOP

Memanggil 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  2

Peringatan 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 value

self 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 times

Metode 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)  -- 15

Metode 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: 16

Tabel 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

  1. Class melalui Metatabel
  2. Konstruktor dan new()
  3. Metode Instans dan self
  4. Enkapsulasi dengan Closure
← Kembali ke Lua Academy