인스턴스 메서드와 self
콜론 구문과 암시적 self 매개변수를 사용해 메서드를 정의합니다.
인스턴스 메서드와 self은(는) CoddyKit의 무료 Lua Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Lua Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Lua Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
self는 인스턴스입니다
obj:method()를 호출하면 Lua는 obj를 첫 번째 인수로 자동 전달합니다. 관례상 이 매개변수의 이름은 self입니다. 메서드는 self를 통해 인스턴스 데이터에 접근하고 다른 메서드를 호출합니다.
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메서드 연쇄 호출
연쇄 호출을 가능하게 하려면 메서드에서 self를 반환하세요: obj:method1():method2():method3(). 각 호출이 동일한 객체를 반환하므로 플루언트 방식으로 작성할 수 있습니다. 상태를 변경하는 메서드에 특히 잘 맞습니다.
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다른 메서드 호출하기
메서드는 self:otherMethod()를 통해 같은 인스턴스의 다른 메서드를 호출할 수 있습니다. 이는 클래스 내부에서 코드 재사용을 촉진합니다. 비공개 보조 함수는 self를 명시적으로 받는 일반 지역 함수로 작성할 수 있습니다.
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메서드 재정의 주의 사항
클래스 메서드와 같은 이름의 인스턴스 필드를 설정하면 해당 인스턴스에서 그 필드가 메서드를 가립니다. 이는 대개 버그이므로, 인스턴스 필드 이름이 메서드 이름과 충돌할 수 있을 때 주의해야 합니다.
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
메서드를 콜백으로 전달하면 암시적인 self가 사라집니다. 클로저로 메서드를 감싸 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정적 메서드와 인스턴스 메서드
정적 메서드는 인스턴스가 아니라 클래스에서 호출합니다. 정적 메서드에는 self가 없거나 클래스를 self로 받습니다. Lua에는 공식적인 구분이 없으므로, 관례상 정적 메서드에는 :가 아닌 .을 사용합니다.
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믹스인 메서드
공식적인 상속 없이 믹스인 테이블의 메서드를 클래스에 추가하세요. 이는 평면 조합으로, 믹스인의 함수를 클래스 테이블에 복사하거나 참조하는 방식입니다.
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())추상 메서드
Lua는 추상 메서드를 강제하지 않지만, 오류를 발생시키는 기반 클래스 메서드를 정의하여 하위 클래스가 이를 재정의하도록 만들 수 있습니다. 이는 "반드시 재정의해야 함"을 나타내는 관례입니다.
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메서드 테이블
메서드가 많은 클래스라면 기능별로 그룹을 나누어 정리하세요. 같은 테이블의 모든 메서드는 동일한 메타테이블 조회를 공유하지만, 하위 네임스페이스를 사용해 관심사별로 나눌 수 있습니다.
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)위임과 상속
깊은 상속 계층보다 참조를 보유하는 위임을 우선하세요. 클래스가 다른 클래스에서 상속받는 대신 다른 객체에 작업을 위임할 수 있으므로 결합도가 낮아지고 각 클래스의 역할이 명확해집니다.
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()빠른 확인
obj:method()와 obj.method()의 차이는 무엇인가요?
복습: 인스턴스 메서드
요약:
- 콜론 호출 구문:
obj:method()==obj.method(obj) - 메서드 연쇄 호출을 위해 self를 반환합니다
- 다른 메서드를 호출합니다:
self:otherMethod() - 콜백에서는 self를 보존하도록 클로저로 감쌉니다
- 정적 메서드에는 관례상 점 표기법을 사용합니다
- 유연성을 위해 깊은 상속보다 위임을 사용합니다
자주 묻는 질문
“인스턴스 메서드와 self” 강의는 무료인가요?
네 — “인스턴스 메서드와 self” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Lua Academy 강의 전체를 잠금 해제할 수 있습니다. Lua Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“인스턴스 메서드와 self”에서 뭘 배우나요?
콜론 구문과 암시적 self 매개변수를 사용해 메서드를 정의합니다. 브라우저에서 직접 실행하는 실습 코드로 Lua Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Lua Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Lua Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“인스턴스 메서드와 self” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Lua Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Lua Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 메타테이블을 이용한 클래스
- 생성자와 new()
- 인스턴스 메서드와 self
- 클로저를 이용한 캡슐화